@singleton-i18n/angular-client
Version:
Singleton client code for Angular 10.
198 lines • 29.9 kB
JavaScript
/*
* Copyright 2019-2021 VMware, Inc.
* SPDX-License-Identifier: EPL-2.0
*/
import { timeoutWith, catchError, map } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { VIPTimeOutError, invalidParamater } from './exceptions';
import { defer, throwError } from 'rxjs';
import { VIPServiceConstants } from './constants';
import { ResponseParser } from './response.parser';
import { isDefined } from './util';
export class I18nLoader {
}
export class VIPLoader {
constructor(responseParser, http) {
this.responseParser = responseParser;
this.http = http;
}
/**
* Get the i18n resource through VIP service.
* i18nAssets will be removed in future release.
* And for i18nAsset only support loading translation
* from web server, can't support loading patterns.
* @param url
* @returns Promise<any>
* @memberof VIPRestLoader
*/
getLocaleData(config, language, region) {
this.validateConfig(config);
const scope = config.i18nScope ? config.i18nScope.join(',') : '';
// For now, just only support downloading translation to local assets folder
// but it is also supposed to support formatting pattern data.
// Firstly, identify which mode is using.
if (isDefined(config.i18nAssets)) {
return scope === ''
? this.getTranslationByComponent(language, config)
: this.getCombineDataFromAssets(language, config);
}
// Secondly, which API should be used to communicate with VIP service.
return scope === ''
? this.getTranslationByComponent(language, config)
: this.getCombineLocaleData(config, language, region);
}
/**
* Get the combine locale data(translations and pattern) through assets folder.
* @param language language code in use
* @param config
*/
getCombineDataFromAssets(language, config) {
const url = this.getI18nResourceUrl(config, language);
return this.getRequest(url, config.timeout, (res) => {
return this.responseParser.ParseLocaleData(res, config);
});
}
/**
* Only get translations through VIP service.
* @param language language tag for translation.
* @param config without i18nScope
*/
getTranslationByComponent(language, config) {
const url = this.getComponentTranslationUrl(language, config);
return this.getRequest(url, config.timeout, (res) => {
return this.responseParser.ParseLocaleData(res, config);
});
}
/**
* Get combine locale data(translations and pattern) through VIP service.
* @param conf with i18nScope
* @param language language tag for translation.
* @param region region code for formatting pattern.
*/
getCombineLocaleData(conf, language, region) {
const scope = conf.i18nScope.join(',');
const url = this.getI18nResourceUrl(conf);
const combine = region ? 1 : 2;
return this.postRequest(url, {
language: language,
region: region,
productName: conf.productID,
version: conf.version,
components: [conf.component],
scope: scope,
pseudo: conf.isPseudo,
combine: combine,
machineTranslation: false
}, conf.timeout, (res) => {
return this.responseParser.ParseLocaleData(res, conf);
});
}
getSupportedLanguages(conf) {
const url = this.getSupportedLanguagesUrl(conf);
return this.getRequest(url, conf.timeout, (res) => this.responseParser.ParseSupportedLanguagesData(res));
}
getSupportedRegions(language, conf) {
const url = this.getSupportedRegionsUrl(language, conf.host);
return this.getRequest(url, conf.timeout, (res) => this.responseParser.ParseSupportedRegionsData(res));
}
getLocalizedCities(language, region, conf) {
const url = this.getLocalizedCitiesUrl(language, region, conf.host);
return this.getRequest(url, conf.timeout, (res) => this.responseParser.ParseSupportedRegionsData(res));
}
/**
* Fetch I18N resource from backend service through get request.
* @param url request url.
* @param timeout default value is 3000ms, timeoutWith default value is 0ms.
* @param fn a callback function that is executed after the request is completed.
*/
getRequest(url, timeout, fn) {
return this.http.get(url)
.pipe(timeoutWith(timeout, defer(() => {
return throwError(new VIPTimeOutError('Timeout error'));
})), map((res) => fn && typeof fn === 'function' ? fn(res) : res), catchError((err) => {
return throwError(err);
}));
}
/**
* Fetch I18N resource from backend service through post request.
* @param url request url.
* @param vipRequestBody parameters
* @param timeout default value is 3000ms, timeoutWith default value is 0ms.
* @param fn a callback function that is executed after the request is completed.
*/
postRequest(url, vipRequestBody, timeout, fn) {
return this.http.post(url, vipRequestBody)
.pipe(timeoutWith(timeout, defer(() => {
return throwError(new VIPTimeOutError('Timeout error'));
})), map((res) => fn && typeof fn === 'function' ? fn(res) : res), catchError((err) => {
return throwError(err);
}));
}
getI18nResourceUrl(conf, language) {
if (conf.i18nAssets) {
const path = `${conf.i18nAssets}${language}${VIPServiceConstants.ASSETS_SUFFIX}`;
return path;
}
return conf.host
.concat(VIPServiceConstants.TRANSLATION_PATTERN);
}
getComponentTranslationUrl(language, config) {
if (isDefined(config.i18nAssets)) {
const path = `${config.i18nAssets}${VIPServiceConstants.L10N_ASSETS_PREFIX}${language}${VIPServiceConstants.ASSETS_SUFFIX}`;
return path;
}
return config.host
.concat(VIPServiceConstants.L10N_COMPONENT_API_ENDPOINT)
.concat('/products/' + config.productID)
.concat('/versions/' + config.version)
.concat('/locales/' + language)
.concat('/components/' + config.component)
.concat('?pseudo=' + config.isPseudo);
}
getSupportedLanguagesUrl(config) {
return config.host
.concat(VIPServiceConstants.L10N_LOCAL_API_ENDPOINT)
.concat('/supportedLanguageList?')
.concat('productName=' + config.productID)
.concat('&version=' + config.version);
}
getSupportedRegionsUrl(language, host) {
return host
.concat(VIPServiceConstants.L10N_LOCAL_API_ENDPOINT)
.concat('/regionList?')
.concat('supportedLanguageList=' + language);
}
getLocalizedCitiesUrl(language, region, host) {
return host
.concat(VIPServiceConstants.L10N_LOCAL_API_ENDPOINT)
.concat('/regionList?')
.concat('supportedLanguageList=' + language)
.concat('&displayCity=true®ions=' + region);
}
validateConfig(initConfig) {
const message = ' in VIPLoader';
if (!isDefined(initConfig.productID) || !initConfig.productID.length) {
throw invalidParamater('productID' + message);
}
if (!isDefined(initConfig.version) || !initConfig.version.length) {
throw invalidParamater('version' + message);
}
// in i18nAssets mode, the host is not required
if (!isDefined(initConfig.host) && !isDefined(initConfig.i18nAssets)) {
throw invalidParamater('host' + message);
}
if (!isDefined(initConfig.language)) {
throw invalidParamater('language' + message);
}
return true;
}
}
VIPLoader.decorators = [
{ type: Injectable }
];
VIPLoader.ctorParameters = () => [
{ type: ResponseParser },
{ type: HttpClient }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZGVyLmpzIiwic291cmNlUm9vdCI6Ii9ob21lL3JsaWdlbmcvUHJvamVjdHMvRGV2b3BzL0NsaWVudF9Bbmd1bGFyX0dpdEh1Yl9OcG1qcy92aXAvY2kvcHViMm9yZy9DbGllbnRfQW5ndWxhcl9HaXRIdWJfTnBtanMvc2luZ2xldG9uL3Byb2plY3RzL2FuZ3VsYXItY2xpZW50LyIsInNvdXJjZXMiOlsic3JjL2xvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ2pFLE9BQU8sRUFBYyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFbkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQWNuQyxNQUFNLE9BQWdCLFVBQVU7Q0FLL0I7QUFHRCxNQUFNLE9BQU8sU0FBUztJQUNsQixZQUNXLGNBQThCLEVBQzdCLElBQWdCO1FBRGpCLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM3QixTQUFJLEdBQUosSUFBSSxDQUFZO0lBQUksQ0FBQztJQUVqQzs7Ozs7Ozs7T0FRRztJQUNJLGFBQWEsQ0FBQyxNQUFpQixFQUFFLFFBQWdCLEVBQUUsTUFBZTtRQUNyRSxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVCLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxTQUFT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Q0FBQyxRQUFRLENBQUMsRUFBRTtZQUNqQyxNQUFNLGdCQUFnQixDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsQ0FBQztTQUNoRDtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7OztZQW5NSixVQUFVOzs7WUF2QkYsY0FBYztZQUxkLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMTktMjAyMSBWTXdhcmUsIEluYy5cbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wXG4gKi9cbmltcG9ydCB7IHRpbWVvdXRXaXRoLCBjYXRjaEVycm9yLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgVklQVGltZU91dEVycm9yLCBpbnZhbGlkUGFyYW1hdGVyIH0gZnJvbSAnLi9leGNlcHRpb25zJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGRlZmVyLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBWSVBDb25maWcgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyBWSVBTZXJ2aWNlQ29uc3RhbnRzIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgUmVzcG9uc2VQYXJzZXIgfSBmcm9tICcuL3Jlc3BvbnNlLnBhcnNlcic7XG5pbXBvcnQgeyBMb2NhbGVEYXRhIH0gZnJvbSAnLi9zZXJ2aWNlcy92aXAuc2VydmljZSc7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZJUFJlcXVlc3RCb2R5IHtcbiAgICBsYW5ndWFnZTogc3RyaW5nO1xuICAgIHJlZ2lvbjogc3RyaW5nO1xuICAgIHByb2R1Y3ROYW1lOiBzdHJpbmc7XG4gICAgdmVyc2lvbjogc3RyaW5nO1xuICAgIGNvbXBvbmVudHM6IEFycmF5PHN0cmluZz47XG4gICAgc2NvcGU6IHN0cmluZztcbiAgICBwc2V1ZG8/OiBib29sZWFuO1xuICAgIG1hY2hpbmVUcmFuc2xhdGlvbj86IGJvb2xlYW47XG4gICAgY2hlY2tUcmFuc2xhdGlvblN0YXR1cz86IHN0cmluZztcbiAgICBjb21iaW5lOiBudW1iZXI7XG59XG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgSTE4bkxvYWRlciB7XG4gICAgYWJzdHJhY3QgZ2V0TG9jYWxlRGF0YShjb25maWc6IFZJUENvbmZpZywgbGFuZ3VhZ2U6IHN0cmluZywgcmVnaW9uPzogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+O1xuICAgIGFic3RyYWN0IGdldFN1cHBvcnRlZExhbmd1YWdlcyhjb25mOiBWSVBDb25maWcpOiBPYnNlcnZhYmxlPGFueT47XG4gICAgYWJzdHJhY3QgZ2V0U3VwcG9ydGVkUmVnaW9ucyhsYW5ndWFnZTogc3RyaW5nLCBjb25mOiBWSVBDb25maWcpOiBPYnNlcnZhYmxlPGFueT47XG4gICAgYWJzdHJhY3QgZ2V0TG9jYWxpemVkQ2l0aWVzKGxhbmd1YWdlOiBzdHJpbmcsIHJlZ2lvbjogc3RyaW5nLCBjb25mOiBWSVBDb25maWcpOiBPYnNlcnZhYmxlPGFueT47XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBWSVBMb2FkZXIgaW1wbGVtZW50cyBJMThuTG9hZGVyIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHVibGljIHJlc3BvbnNlUGFyc2VyOiBSZXNwb25zZVBhcnNlcixcbiAgICAgICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50KSB7IH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgaTE4biByZXNvdXJjZSB0aHJvdWdoIFZJUCBzZXJ2aWNlLlxuICAgICAqIGkxOG5Bc3NldHMgd2lsbCBiZSByZW1vdmVkIGluIGZ1dHVyZSByZWxlYXNlLlxuICAgICAqIEFuZCBmb3IgaTE4bkFzc2V0IG9ubHkgc3VwcG9ydCBsb2FkaW5nIHRyYW5zbGF0aW9uXG4gICAgICogZnJvbSB3ZWIgc2VydmVyLCBjYW4ndCBzdXBwb3J0IGxvYWRpbmcgcGF0dGVybnMuXG4gICAgICogQHBhcmFtIHVybFxuICAgICAqIEByZXR1cm5zIFByb21pc2U8YW55PlxuICAgICAqIEBtZW1iZXJvZiBWSVBSZXN0TG9hZGVyXG4gICAgICovXG4gICAgcHVibGljIGdldExvY2FsZURhdGEoY29uZmlnOiBWSVBDb25maWcsIGxhbmd1YWdlOiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZyk6IE9ic2VydmFibGU8TG9jYWxlRGF0YT4ge1xuICAgICAgICB0aGlzLnZhbGlkYXRlQ29uZmlnKGNvbmZpZyk7XG4gICAgICAgIGNvbnN0IHNjb3BlID0gY29uZmlnLmkxOG5TY29wZSA/IGNvbmZpZy5pMThuU2NvcGUuam9pbignLCcpIDogJyc7XG4gICAgICAgIC8vIEZvciBub3csIGp1c3Qgb25seSBzdXBwb3J0IGRvd25sb2FkaW5nIHRyYW5zbGF0aW9uIHRvIGxvY2FsIGFzc2V0cyBmb2xkZXJcbiAgICAgICAgLy8gYnV0IGl0IGlzIGFsc28gc3VwcG9zZWQgdG8gc3VwcG9ydCBmb3JtYXR0aW5nIHBhdHRlcm4gZGF0YS5cbiAgICAgICAgLy8gRmlyc3RseSwgaWRlbnRpZnkgd2hpY2ggbW9kZSBpcyB1c2luZy5cbiAgICAgICAgaWYgKGlzRGVmaW5lZChjb25maWcuaTE4bkFzc2V0cykpIHtcbiAgICAgICAgICAgIHJldHVybiBzY29wZSA9PT0gJydcbiAgICAgICAgICAgICAgICA/IHRoaXMuZ2V0VHJhbnNsYXRpb25CeUNvbXBvbmVudChsYW5ndWFnZSwgY29uZmlnKVxuICAgICAgICAgICAgICAgIDogdGhpcy5nZXRDb21iaW5lRGF0YUZyb21Bc3NldHMobGFuZ3VhZ2UsIGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2Vjb25kbHksIHdoaWNoIEFQSSBzaG91bGQgYmUgdXNlZCB0byBjb21tdW5pY2F0ZSB3aXRoIFZJUCBzZXJ2aWNlLlxuICAgICAgICByZXR1cm4gc2NvcGUgPT09ICcnXG4gICAgICAgICAgICA/IHRoaXMuZ2V0VHJhbnNsYXRpb25CeUNvbXBvbmVudChsYW5ndWFnZSwgY29uZmlnKVxuICAgICAgICAgICAgOiB0aGlzLmdldENvbWJpbmVMb2NhbGVEYXRhKGNvbmZpZywgbGFuZ3VhZ2UsIHJlZ2lvbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjb21iaW5lIGxvY2FsZSBkYXRhKHRyYW5zbGF0aW9ucyBhbmQgcGF0dGVybikgdGhyb3VnaCBhc3NldHMgZm9sZGVyLlxuICAgICAqIEBwYXJhbSBsYW5ndWFnZSBsYW5ndWFnZSBjb2RlIGluIHVzZVxuICAgICAqIEBwYXJhbSBjb25maWdcbiAgICAgKi9cbiAgICBwcml2YXRlIGdldENvbWJpbmVEYXRhRnJvbUFzc2V0cyhsYW5ndWFnZTogc3RyaW5nLCBjb25maWc6IFZJUENvbmZpZykge1xuICAgICAgICBjb25zdCB1cmwgPSB0aGlzLmdldEkxOG5SZXNvdXJjZVVybChjb25maWcsIGxhbmd1YWdlKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UmVxdWVzdCh1cmwsIGNvbmZpZy50aW1lb3V0LCAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlc3BvbnNlUGFyc2VyLlBhcnNlTG9jYWxlRGF0YShyZXMsIGNvbmZpZyk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPbmx5IGdldCB0cmFuc2xhdGlvbnMgdGhyb3VnaCBWSVAgc2VydmljZS5cbiAgICAgKiBAcGFyYW0gbGFuZ3VhZ2UgbGFuZ3VhZ2UgdGFnIGZvciB0cmFuc2xhdGlvbi5cbiAgICAgKiBAcGFyYW0gY29uZmlnIHdpdGhvdXQgaTE4blNjb3BlXG4gICAgICovXG4gICAgcHJpdmF0ZSBnZXRUcmFuc2xhdGlvbkJ5Q29tcG9uZW50KGxhbmd1YWdlOiBzdHJpbmcsIGNvbmZpZzogVklQQ29uZmlnKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IHRoaXMuZ2V0Q29tcG9uZW50VHJhbnNsYXRpb25VcmwobGFuZ3VhZ2UsIGNvbmZpZyk7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFJlcXVlc3QodXJsLCBjb25maWcudGltZW91dCwgKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZXNwb25zZVBhcnNlci5QYXJzZUxvY2FsZURhdGEocmVzLCBjb25maWcpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgY29tYmluZSBsb2NhbGUgZGF0YSh0cmFuc2xhdGlvbnMgYW5kIHBhdHRlcm4pIHRocm91Z2ggVklQIHNlcnZpY2UuXG4gICAgICogQHBhcmFtIGNvbmYgd2l0aCBpMThuU2NvcGVcbiAgICAgKiBAcGFyYW0gbGFuZ3VhZ2UgbGFuZ3VhZ2UgdGFnIGZvciB0cmFuc2xhdGlvbi5cbiAgICAgKiBAcGFyYW0gcmVnaW9uIHJlZ2lvbiBjb2RlIGZvciBmb3JtYXR0aW5nIHBhdHRlcm4uXG4gICAgICovXG4gICAgcHJpdmF0ZSBnZXRDb21iaW5lTG9jYWxlRGF0YShjb25mOiBWSVBDb25maWcsIGxhbmd1YWdlOiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZykge1xuICAgICAgICBjb25zdCBzY29wZSA9IGNvbmYuaTE4blNjb3BlLmpvaW4oJywnKTtcbiAgICAgICAgY29uc3QgdXJsID0gdGhpcy5nZXRJMThuUmVzb3VyY2VVcmwoY29uZik7XG4gICAgICAgIGNvbnN0IGNvbWJpbmUgPSByZWdpb24gPyAxIDogMjtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zdFJlcXVlc3QodXJsLCB7XG4gICAgICAgICAgICBsYW5ndWFnZTogbGFuZ3VhZ2UsXG4gICAgICAgICAgICByZWdpb246IHJlZ2lvbixcbiAgICAgICAgICAgIHByb2R1Y3ROYW1lOiBjb25mLnByb2R1Y3RJRCxcbiAgICAgICAgICAgIHZlcnNpb246IGNvbmYudmVyc2lvbixcbiAgICAgICAgICAgIGNvbXBvbmVudHM6IFtjb25mLmNvbXBvbmVudF0sXG4gICAgICAgICAgICBzY29wZTogc2NvcGUsXG4gICAgICAgICAgICBwc2V1ZG86IGNvbmYuaXNQc2V1ZG8sXG4gICAgICAgICAgICBjb21iaW5lOiBjb21iaW5lLFxuICAgICAgICAgICAgbWFjaGluZVRyYW5zbGF0aW9uOiBmYWxzZVxuICAgICAgICB9LCBjb25mLnRpbWVvdXQsIChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVzcG9uc2VQYXJzZXIuUGFyc2VMb2NhbGVEYXRhKHJlcywgY29uZik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRTdXBwb3J0ZWRMYW5ndWFnZXMoY29uZjogVklQQ29uZmlnKTogT2JzZXJ2YWJsZTxPYmplY3Q+IHtcbiAgICAgICAgY29uc3QgdXJsID0gdGhpcy5nZXRTdXBwb3J0ZWRMYW5ndWFnZXNVcmwoY29uZik7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFJlcXVlc3QodXJsLCBjb25mLnRpbWVvdXQsIChyZXM6IE9iamVjdCkgPT4gdGhpcy5yZXNwb25zZVBhcnNlci5QYXJzZVN1cHBvcnRlZExhbmd1YWdlc0RhdGEocmVzKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFN1cHBvcnRlZFJlZ2lvbnMobGFuZ3VhZ2U6IHN0cmluZywgY29uZjogVklQQ29uZmlnKTogT2JzZXJ2YWJsZTxPYmplY3Q+IHtcbiAgICAgICAgY29uc3QgdXJsID0gdGhpcy5nZXRTdXBwb3J0ZWRSZWdpb25zVXJsKGxhbmd1YWdlLCBjb25mLmhvc3QpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRSZXF1ZXN0KHVybCwgY29uZi50aW1lb3V0LCAocmVzOiBPYmplY3QpID0+IHRoaXMucmVzcG9uc2VQYXJzZXIuUGFyc2VTdXBwb3J0ZWRSZWdpb25zRGF0YShyZXMpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0TG9jYWxpemVkQ2l0aWVzKGxhbmd1YWdlOiBzdHJpbmcsIHJlZ2lvbjogc3RyaW5nLCBjb25mOiBWSVBDb25maWcpIHtcbiAgICAgICAgY29uc3QgdXJsID0gdGhpcy5nZXRMb2NhbGl6ZWRDaXRpZXNVcmwobGFuZ3VhZ2UsIHJlZ2lvbiwgY29uZi5ob3N0KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UmVxdWVzdCh1cmwsIGNvbmYudGltZW91dCwgKHJlczogT2JqZWN0KSA9PiB0aGlzLnJlc3BvbnNlUGFyc2VyLlBhcnNlU3VwcG9ydGVkUmVnaW9uc0RhdGEocmVzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZldGNoIEkxOE4gcmVzb3VyY2UgZnJvbSBiYWNrZW5kIHNlcnZpY2UgdGhyb3VnaCBnZXQgcmVxdWVzdC5cbiAgICAgKiBAcGFyYW0gdXJsIHJlcXVlc3QgdXJsLlxuICAgICAqIEBwYXJhbSB0aW1lb3V0IGRlZmF1bHQgdmFsdWUgaXMgMzAwMG1zLCB0aW1lb3V0V2l0aCBkZWZhdWx0IHZhbHVlIGlzIDBtcy5cbiAgICAgKiBAcGFyYW0gZm4gYSBjYWxsYmFjayBmdW5jdGlvbiB0aGF0IGlzIGV4ZWN1dGVkIGFmdGVyIHRoZSByZXF1ZXN0IGlzIGNvbXBsZXRlZC5cbiAgICAgKi9cbiAgICBwcml2YXRlIGdldFJlcXVlc3QodXJsOiBzdHJpbmcsIHRpbWVvdXQ6IG51bWJlciwgZm4/OiBGdW5jdGlvbik6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0KHVybClcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIHRpbWVvdXRXaXRoKHRpbWVvdXQsIGRlZmVyKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IobmV3IFZJUFRpbWVPdXRFcnJvcignVGltZW91dCBlcnJvcicpKTtcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICAgICAgbWFwKChyZXM6IE9iamVjdCkgPT4gZm4gJiYgdHlwZW9mIGZuID09PSAnZnVuY3Rpb24nID8gZm4ocmVzKSA6IHJlcyksXG4gICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCBJMThOIHJlc291cmNlIGZyb20gYmFja2VuZCBzZXJ2aWNlIHRocm91Z2ggcG9zdCByZXF1ZXN0LlxuICAgICAqIEBwYXJhbSB1cmwgcmVxdWVzdCB1cmwuXG4gICAgICogQHBhcmFtIHZpcFJlcXVlc3RCb2R5IHBhcmFtZXRlcnNcbiAgICAgKiBAcGFyYW0gdGltZW91dCBkZWZhdWx0IHZhbHVlIGlzIDMwMDBtcywgdGltZW91dFdpdGggZGVmYXVsdCB2YWx1ZSBpcyAwbXMuXG4gICAgICogQHBhcmFtIGZuIGEgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCBpcyBleGVjdXRlZCBhZnRlciB0aGUgcmVxdWVzdCBpcyBjb21wbGV0ZWQuXG4gICAgICovXG4gICAgcHJpdmF0ZSBwb3N0UmVxdWVzdCh1cmw6IHN0cmluZywgdmlwUmVxdWVzdEJvZHk6IFZJUFJlcXVlc3RCb2R5LCB0aW1lb3V0OiBudW1iZXIsIGZuPzogRnVuY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHVybCwgdmlwUmVxdWVzdEJvZHkpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICB0aW1lb3V0V2l0aCh0aW1lb3V0LCBkZWZlcigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKG5ldyBWSVBUaW1lT3V0RXJyb3IoJ1RpbWVvdXQgZXJyb3InKSk7XG4gICAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgICAgIG1hcCgocmVzOiBPYmplY3QpID0+IGZuICYmIHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJyA/IGZuKHJlcykgOiByZXMpLFxuICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKGVycik7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRJMThuUmVzb3VyY2VVcmwoY29uZjogVklQQ29uZmlnLCBsYW5ndWFnZT86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGlmIChjb25mLmkxOG5Bc3NldHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhdGggPSBgJHtjb25mLmkxOG5Bc3NldHN9JHtsYW5ndWFnZX0ke1ZJUFNlcnZpY2VDb25zdGFudHMuQVNTRVRTX1NVRkZJWH1gO1xuICAgICAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbmYuaG9zdFxuICAgICAgICAgICAgLmNvbmNhdChWSVBTZXJ2aWNlQ29uc3RhbnRzLlRSQU5TTEFUSU9OX1BBVFRFUk4pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q29tcG9uZW50VHJhbnNsYXRpb25VcmwobGFuZ3VhZ2U6IHN0cmluZywgY29uZmlnOiBWSVBDb25maWcpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZChjb25maWcuaTE4bkFzc2V0cykpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhdGggPSBgJHtjb25maWcuaTE4bkFzc2V0c30ke1ZJUFNlcnZpY2VDb25zdGFudHMuTDEwTl9BU1NFVFNfUFJFRklYfSR7bGFuZ3VhZ2V9JHtWSVBTZXJ2aWNlQ29uc3RhbnRzLkFTU0VUU19TVUZGSVh9YDtcbiAgICAgICAgICAgIHJldHVybiBwYXRoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb25maWcuaG9zdFxuICAgICAgICAgICAgLmNvbmNhdChWSVBTZXJ2aWNlQ29uc3RhbnRzLkwxME5fQ09NUE9ORU5UX0FQSV9FTkRQT0lOVClcbiAgICAgICAgICAgIC5jb25jYXQoJy9wcm9kdWN0cy8nICsgY29uZmlnLnByb2R1Y3RJRClcbiAgICAgICAgICAgIC5jb25jYXQoJy92ZXJzaW9ucy8nICsgY29uZmlnLnZlcnNpb24pXG4gICAgICAgICAgICAuY29uY2F0KCcvbG9jYWxlcy8nICsgbGFuZ3VhZ2UpXG4gICAgICAgICAgICAuY29uY2F0KCcvY29tcG9uZW50cy8nICsgY29uZmlnLmNvbXBvbmVudClcbiAgICAgICAgICAgIC5jb25jYXQoJz9wc2V1ZG89JyArIGNvbmZpZy5pc1BzZXVkbyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTdXBwb3J0ZWRMYW5ndWFnZXNVcmwoY29uZmlnOiBWSVBDb25maWcpIHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZy5ob3N0XG4gICAgICAgICAgICAuY29uY2F0KFZJUFNlcnZpY2VDb25zdGFudHMuTDEwTl9MT0NBTF9BUElfRU5EUE9JTlQpXG4gICAgICAgICAgICAuY29uY2F0KCcvc3VwcG9ydGVkTGFuZ3VhZ2VMaXN0PycpXG4gICAgICAgICAgICAuY29uY2F0KCdwcm9kdWN0TmFtZT0nICsgY29uZmlnLnByb2R1Y3RJRClcbiAgICAgICAgICAgIC5jb25jYXQoJyZ2ZXJzaW9uPScgKyBjb25maWcudmVyc2lvbik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTdXBwb3J0ZWRSZWdpb25zVXJsKGxhbmd1YWdlOiBzdHJpbmcsIGhvc3Q6IHN0cmluZykge1xuICAgICAgICByZXR1cm4gaG9zdFxuICAgICAgICAgICAgLmNvbmNhdChWSVBTZXJ2aWNlQ29uc3RhbnRzLkwxME5fTE9DQUxfQVBJX0VORFBPSU5UKVxuICAgICAgICAgICAgLmNvbmNhdCgnL3JlZ2lvbkxpc3Q/JylcbiAgICAgICAgICAgIC5jb25jYXQoJ3N1cHBvcnRlZExhbmd1YWdlTGlzdD0nICsgbGFuZ3VhZ2UpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0TG9jYWxpemVkQ2l0aWVzVXJsKGxhbmd1YWdlOiBzdHJpbmcsIHJlZ2lvbjogc3RyaW5nLCBob3N0OiBzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIGhvc3RcbiAgICAgICAgICAgIC5jb25jYXQoVklQU2VydmljZUNvbnN0YW50cy5MMTBOX0xPQ0FMX0FQSV9FTkRQT0lOVClcbiAgICAgICAgICAgIC5jb25jYXQoJy9yZWdpb25MaXN0PycpXG4gICAgICAgICAgICAuY29uY2F0KCdzdXBwb3J0ZWRMYW5ndWFnZUxpc3Q9JyArIGxhbmd1YWdlKVxuICAgICAgICAgICAgLmNvbmNhdCgnJmRpc3BsYXlDaXR5PXRydWUmcmVnaW9ucz0nICsgcmVnaW9uKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHZhbGlkYXRlQ29uZmlnKGluaXRDb25maWc6IFZJUENvbmZpZyk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gJyBpbiBWSVBMb2FkZXInO1xuICAgICAgICBpZiAoIWlzRGVmaW5lZChpbml0Q29uZmlnLnByb2R1Y3RJRCkgfHwgIWluaXRDb25maWcucHJvZHVjdElELmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgaW52YWxpZFBhcmFtYXRlcigncHJvZHVjdElEJyArIG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNEZWZpbmVkKGluaXRDb25maWcudmVyc2lvbikgfHwgIWluaXRDb25maWcudmVyc2lvbi5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IGludmFsaWRQYXJhbWF0ZXIoJ3ZlcnNpb24nICsgbWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW4gaTE4bkFzc2V0cyBtb2RlLCB0aGUgaG9zdCBpcyBub3QgcmVxdWlyZWRcbiAgICAgICAgaWYgKCFpc0RlZmluZWQoaW5pdENvbmZpZy5ob3N0KSAmJiAhaXNEZWZpbmVkKGluaXRDb25maWcuaTE4bkFzc2V0cykpIHtcbiAgICAgICAgICAgIHRocm93IGludmFsaWRQYXJhbWF0ZXIoJ2hvc3QnICsgbWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc0RlZmluZWQoaW5pdENvbmZpZy5sYW5ndWFnZSkpIHtcbiAgICAgICAgICAgIHRocm93IGludmFsaWRQYXJhbWF0ZXIoJ2xhbmd1YWdlJyArIG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbiJdfQ==