UNPKG

@singleton-i18n/angular-client

Version:

Singleton client code for Angular 10.

213 lines 28 kB
/* * Copyright 2019-2021 VMware, Inc. * SPDX-License-Identifier: EPL-2.0 */ import { Injectable } from '@angular/core'; import { getNameSpace } from '../config'; import { LocaleService } from './locale.service'; import { isDefined } from '../util'; import { filterArgs } from '../extensions/stringable'; import { MessageFormat } from '../formatters/message.formatter'; import { BaseService } from './base.service'; import { VIPService } from './vip.service'; import { VIPServiceConstants } from '../constants'; import { I18nContext } from './i18n.context'; const pseudoTag = '@@'; export class L10nService extends BaseService { constructor(vipService, localeService, messageFormat, i18nContext) { super(vipService, localeService); this.vipService = vipService; this.localeService = localeService; this.messageFormat = messageFormat; this.i18nContext = i18nContext; } /** * Generate long key with namespace. * @param config * @param key raw key */ getLongKey(config, key) { const nameSpace = config ? getNameSpace(config) : undefined; return nameSpace ? nameSpace .concat(VIPServiceConstants.NAME_SPACE_SEPARATOR) .concat(key) : key; } /** * In the mutiple component situation, the namespace is necessary. * Default workspace the main component in root scope and each lazy scope. * @param key raw key with namespace */ parseKey(key) { let nameSpace; let rawKey = key; if (key && key.indexOf(VIPServiceConstants.NAME_SPACE_SEPARATOR) > -1) { const parts = key.split(VIPServiceConstants.NAME_SPACE_SEPARATOR); nameSpace = parts[0]; rawKey = parts[1]; } nameSpace = nameSpace ? nameSpace : getNameSpace(this.vipService.mainConfig); return { rawKey: rawKey, nameSpace: nameSpace }; } /** * If translation is certainly be loaded before application bootstrap, the locale can be * skipped, otherwise make sure getting available locale from the return of stream API. * @param nameSpace * @param locale */ resolveLocaleData(nameSpace, locale) { let localeData; let translations; const currentLocale = locale ? locale : this.currentLocale; localeData = this.vipService.localeData[currentLocale]; translations = localeData && localeData.messages && localeData.messages[nameSpace] ? localeData.messages[nameSpace] : undefined; return translations; } /** * Register source bundles to the main configuration on demand. * For the isolated module (separated lib), the namespace is required. * Considering using the last item of the array for the configuration or new API instead. * @param args Source bundle objects from Angular component. */ registerSourceBundles(...args) { if (args) { this.vipService.registerSourceBundles(args, this.vipService.mainConfig); } } /** * Get source string via key with namespace * @param key raw key with namespace */ getSourceString(key) { if (typeof key !== 'string') { return undefined; } const l10nKey = this.parseKey(key); const sourceBundle = this.resolveLocaleData(l10nKey.nameSpace, this.localeService.defaultLocale.languageCode); if (sourceBundle && sourceBundle[l10nKey.rawKey]) { // If the corresponding value of key is an array containing source and comment if (Array.isArray(sourceBundle[l10nKey.rawKey])) { // prevent empty array if (sourceBundle[l10nKey.rawKey][0]) { return sourceBundle[l10nKey.rawKey][0]; } } else { return sourceBundle[l10nKey.rawKey]; } console.error('No English found for key: %s in sourceBundle', key); } return key; } /** * Determine whether the key already exists in the sourceBundles or translation. * if the locale is source locale, check whether the key exists in sourceBundles. * if the locale is not source locale, check whether the key exists in translation. * @param key raw key with namespace * @param locale */ isExistKey(key, locale) { const l10nKey = this.parseKey(key); if (this.localeService.isSourceLanguage) { locale = this.localeService.defaultLocale.languageCode; } else { locale = locale ? locale : this.currentLocale; } // sourceBundle or translations const resourceBundle = this.resolveLocaleData(l10nKey.nameSpace, locale); const isExist = resourceBundle && resourceBundle[l10nKey.rawKey] ? true : false; return isExist; } formatMessage(isFallback, locale, message, args) { if (isFallback) { locale = this.localeService.defaultLocale.languageCode; } return this.messageFormat.format(locale, message, args); } /** * @param key raw key with namespace * @param source source string for translation * @param args variables for placeholders * @param locale work with steam API */ translate(key, source, args, locale) { let translation; let isFallback; const l10nKey = this.parseKey(key); if (this.localeService.isSourceLanguage) { translation = source; } else { locale = locale ? locale : this.currentLocale; const translations = this.resolveLocaleData(l10nKey.nameSpace, locale); translation = translations ? translations[l10nKey.rawKey] : undefined; if (!translation || translation === '') { translation = source; const pseudoInConfig = this.vipService.mainConfig && this.vipService.mainConfig.isPseudo; const i18nEnabled = this.i18nContext.i18nEnabled !== false; if (pseudoInConfig && i18nEnabled) { translation = `${pseudoTag}${source}${pseudoTag}`; } isFallback = true; } } if (translation && translation.trim() !== '') { translation = this.formatMessage(isFallback, locale, translation, args); } return translation; } /** * @param key raw key with namespace * @param args variables and comment * @param locale optinal parameter for live update through 'stream' API */ getMessage(key, args, locale) { if (typeof key !== 'string') { return undefined; } if (!isDefined(key)) { return null; } // Detect whether existing Object in args Array, if exist, convert them into strings args = filterArgs(args); const source = this.getSourceString(key); const translation = this.translate(key, source, args, locale); return translation; } /** * This API is designed to generate scoped translate method for the isolated module. * The key with namespace which is generated by the configuration. * @param config The VIP configuration with product name, component name and version. */ getScopedTranslate(config) { return (key, args, locale) => { const longKey = this.getLongKey(config, key); return this.getMessage(longKey, args, locale); }; } /** * getSplitedMessage * get message array splited by the seperator * @param key raw key with namespace * @param args variables * @param locale optinal parameter for live update through 'stream' API * @param seperator is a regular expressions, default value is /##\d+/ */ getSplitedMessage(key, args, locale, seperator) { const message = this.getMessage(key, args, locale); const defaultSeperator = /##\d+/; seperator = isDefined(seperator) ? seperator : defaultSeperator; return message.split(seperator); } } L10nService.decorators = [ { type: Injectable } ]; L10nService.ctorParameters = () => [ { type: VIPService }, { type: LocaleService }, { type: MessageFormat }, { type: I18nContext } ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibDEwbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9ob21lL3JsaWdlbmcvUHJvamVjdHMvRGV2b3BzL0NsaWVudF9Bbmd1bGFyX0dpdEh1Yl9OcG1qcy92aXAvY2kvcHViMm9yZy9DbGllbnRfQW5ndWxhcl9HaXRIdWJfTnBtanMvc2luZ2xldG9uL3Byb2plY3RzL2FuZ3VsYXItY2xpZW50LyIsInNvdXJjZXMiOlsic3JjL3NlcnZpY2VzL2wxMG4uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQWEsTUFBTSxXQUFXLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDcEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFVBQVUsRUFBYyxNQUFNLGVBQWUsQ0FBQztBQUN2RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTdDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQztBQVV2QixNQUFNLE9BQU8sV0FBWSxTQUFRLFdBQVc7SUFDeEMsWUFDYyxVQUFzQixFQUN0QixhQUE0QixFQUM5QixhQUE0QixFQUM1QixXQUF3QjtRQUVoQyxLQUFLLENBQUMsVUFBVSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBTHZCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFD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Q0FBQztJQUNOLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ksaUJBQWlCLENBQUMsR0FBVyxFQUFFLElBQVksRUFBRSxNQUFlLEVBQUUsU0FBa0I7UUFDbkYsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ25ELE1BQU0sZ0JBQWdCLEdBQUcsT0FBTyxDQUFDO1FBQ2pDLFNBQVMsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUM7UUFDaEUsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7OztZQWpNSixVQUFVOzs7WUFiRixVQUFVO1lBTFYsYUFBYTtZQUdiLGFBQWE7WUFJYixXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDE5LTIwMjEgVk13YXJlLCBJbmMuXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMFxuICovXG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBnZXROYW1lU3BhY2UsIFZJUENvbmZpZyB9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQgeyBMb2NhbGVTZXJ2aWNlIH0gZnJvbSAnLi9sb2NhbGUuc2VydmljZSc7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tICcuLi91dGlsJztcbmltcG9ydCB7IGZpbHRlckFyZ3MgfSBmcm9tICcuLi9leHRlbnNpb25zL3N0cmluZ2FibGUnO1xuaW1wb3J0IHsgTWVzc2FnZUZvcm1hdCB9IGZyb20gJy4uL2Zvcm1hdHRlcnMvbWVzc2FnZS5mb3JtYXR0ZXInO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UgfSBmcm9tICcuL2Jhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBWSVBTZXJ2aWNlLCBMb2NhbGVEYXRhIH0gZnJvbSAnLi92aXAuc2VydmljZSc7XG5pbXBvcnQgeyBWSVBTZXJ2aWNlQ29uc3RhbnRzIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IEkxOG5Db250ZXh0IH0gZnJvbSAnLi9pMThuLmNvbnRleHQnO1xuXG5jb25zdCBwc2V1ZG9UYWcgPSAnQEAnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEwxME5LZXkge1xuICAgIHJhd0tleTogc3RyaW5nO1xuICAgIG5hbWVTcGFjZTogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBzb3VyY2VCdW5kbGVPYmplY3QgPSB7IFtrZXk6IHN0cmluZ106IGFueSB9O1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTDEwblNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByb3RlY3RlZCB2aXBTZXJ2aWNlOiBWSVBTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgbG9jYWxlU2VydmljZTogTG9jYWxlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBtZXNzYWdlRm9ybWF0OiBNZXNzYWdlRm9ybWF0LFxuICAgICAgICBwcml2YXRlIGkxOG5Db250ZXh0OiBJMThuQ29udGV4dFxuICAgICkge1xuICAgICAgICBzdXBlcih2aXBTZXJ2aWNlLCBsb2NhbGVTZXJ2aWNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBsb25nIGtleSB3aXRoIG5hbWVzcGFjZS5cbiAgICAgKiBAcGFyYW0gY29uZmlnXG4gICAgICogQHBhcmFtIGtleSByYXcga2V5XG4gICAgICovXG4gICAgcHVibGljIGdldExvbmdLZXkoY29uZmlnOiBWSVBDb25maWcsIGtleTogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IG5hbWVTcGFjZSA9IGNvbmZpZyA/IGdldE5hbWVTcGFjZShjb25maWcpIDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gbmFtZVNwYWNlID8gbmFtZVNwYWNlXG4gICAgICAgICAgICAuY29uY2F0KFZJUFNlcnZpY2VDb25zdGFudHMuTkFNRV9TUEFDRV9TRVBBUkFUT1IpXG4gICAgICAgICAgICAuY29uY2F0KGtleSkgOiBrZXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW4gdGhlIG11dGlwbGUgY29tcG9uZW50IHNpdHVhdGlvbiwgdGhlIG5hbWVzcGFjZSBpcyBuZWNlc3NhcnkuXG4gICAgICogRGVmYXVsdCB3b3Jrc3BhY2UgdGhlIG1haW4gY29tcG9uZW50IGluIHJvb3Qgc2NvcGUgYW5kIGVhY2ggbGF6eSBzY29wZS5cbiAgICAgKiBAcGFyYW0ga2V5IHJhdyBrZXkgd2l0aCBuYW1lc3BhY2VcbiAgICAgKi9cbiAgICBwcml2YXRlIHBhcnNlS2V5KGtleTogc3RyaW5nKTogTDEwTktleSB7XG4gICAgICAgIGxldCBuYW1lU3BhY2U6IHN0cmluZztcbiAgICAgICAgbGV0IHJhd0tleSA9IGtleTtcbiAgICAgICAgaWYgKGtleSAmJiBrZXkuaW5kZXhPZihWSVBTZXJ2aWNlQ29uc3RhbnRzLk5BTUVfU1BBQ0VfU0VQQVJBVE9SKSA+IC0xKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0cyA9IGtleS5zcGxpdChWSVBTZXJ2aWNlQ29uc3RhbnRzLk5BTUVfU1BBQ0VfU0VQQVJBVE9SKTtcbiAgICAgICAgICAgIG5hbWVTcGFjZSA9IHBhcnRzWzBdO1xuICAgICAgICAgICAgcmF3S2V5ID0gcGFydHNbMV07XG4gICAgICAgIH1cbiAgICAgICAgbmFtZVNwYWNlID0gbmFtZVNwYWNlID8gbmFtZVNwYWNlIDogZ2V0TmFtZVNwYWNlKHRoaXMudmlwU2VydmljZS5tYWluQ29uZmlnKTtcbiAgICAgICAgcmV0dXJuIHsgcmF3S2V5OiByYXdLZXksIG5hbWVTcGFjZTogbmFtZVNwYWNlIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSWYgdHJhbnNsYXRpb24gaXMgY2VydGFpbmx5IGJlIGxvYWRlZCBiZWZvcmUgYXBwbGljYXRpb24gYm9vdHN0cmFwLCB0aGUgbG9jYWxlIGNhbiBiZVxuICAgICAqIHNraXBwZWQsIG90aGVyd2lzZSBtYWtlIHN1cmUgZ2V0dGluZyBhdmFpbGFibGUgbG9jYWxlIGZyb20gdGhlIHJldHVybiBvZiBzdHJlYW0gQVBJLlxuICAgICAqIEBwYXJhbSBuYW1lU3BhY2VcbiAgICAgKiBAcGFyYW0gbG9jYWxlXG4gICAgICovXG4gICAgcHVibGljIHJlc29sdmVMb2NhbGVEYXRhKG5hbWVTcGFjZTogc3RyaW5nLCBsb2NhbGU/OiBzdHJpbmcpIHtcbiAgICAgICAgbGV0IGxvY2FsZURhdGE6IExvY2FsZURhdGE7XG4gICAgICAgIGxldCB0cmFuc2xhdGlvbnM6IGFueTtcbiAgICAgICAgY29uc3QgY3VycmVudExvY2FsZSA9IGxvY2FsZSA/IGxvY2FsZSA6IHRoaXMuY3VycmVudExvY2FsZTtcbiAgICAgICAgbG9jYWxlRGF0YSA9IHRoaXMudmlwU2VydmljZS5sb2NhbGVEYXRhW2N1cnJlbnRMb2NhbGVdO1xuICAgICAgICB0cmFuc2xhdGlvbnMgPSBsb2NhbGVEYXRhICYmIGxvY2FsZURhdGEubWVzc2FnZXMgJiZcbiAgICAgICAgICAgIGxvY2FsZURhdGEubWVzc2FnZXNbbmFtZVNwYWNlXSA/IGxvY2FsZURhdGEubWVzc2FnZXNbbmFtZVNwYWNlXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRyYW5zbGF0aW9ucztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBzb3VyY2UgYnVuZGxlcyB0byB0aGUgbWFpbiBjb25maWd1cmF0aW9uIG9uIGRlbWFuZC5cbiAgICAgKiBGb3IgdGhlIGlzb2xhdGVkIG1vZHVsZSAoc2VwYXJhdGVkIGxpYiksIHRoZSBuYW1lc3BhY2UgaXMgcmVxdWlyZWQuXG4gICAgICogQ29uc2lkZXJpbmcgdXNpbmcgdGhlIGxhc3QgaXRlbSBvZiB0aGUgYXJyYXkgZm9yIHRoZSBjb25maWd1cmF0aW9uIG9yIG5ldyBBUEkgaW5zdGVhZC5cbiAgICAgKiBAcGFyYW0gYXJncyBTb3VyY2UgYnVuZGxlIG9iamVjdHMgZnJvbSBBbmd1bGFyIGNvbXBvbmVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVnaXN0ZXJTb3VyY2VCdW5kbGVzKC4uLmFyZ3M6IHNvdXJjZUJ1bmRsZU9iamVjdFtdKSB7XG4gICAgICAgIGlmIChhcmdzKSB7XG4gICAgICAgICAgICB0aGlzLnZpcFNlcnZpY2UucmVnaXN0ZXJTb3VyY2VCdW5kbGVzKGFyZ3MsIHRoaXMudmlwU2VydmljZS5tYWluQ29uZmlnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBzb3VyY2Ugc3RyaW5nIHZpYSBrZXkgd2l0aCBuYW1lc3BhY2VcbiAgICAgKiBAcGFyYW0ga2V5IHJhdyBrZXkgd2l0aCBuYW1lc3BhY2VcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0U291cmNlU3RyaW5nKGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7IHJldHVybiB1bmRlZmluZWQ7IH1cbiAgICAgICAgY29uc3QgbDEwbktleSA9IHRoaXMucGFyc2VLZXkoa2V5KTtcbiAgICAgICAgY29uc3Qgc291cmNlQnVuZGxlID0gdGhpcy5yZXNvbHZlTG9jYWxlRGF0YShsMTBuS2V5Lm5hbWVTcGFjZSxcbiAgICAgICAgICAgIHRoaXMubG9jYWxlU2VydmljZS5kZWZhdWx0TG9jYWxlLmxhbmd1YWdlQ29kZSk7XG4gICAgICAgIGlmIChzb3VyY2VCdW5kbGUgJiYgc291cmNlQnVuZGxlW2wxMG5LZXkucmF3S2V5XSkge1xuICAgICAgICAgICAgLy8gSWYgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUgb2Yga2V5IGlzIGFuIGFycmF5IGNvbnRhaW5pbmcgc291cmNlIGFuZCBjb21tZW50XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShzb3VyY2VCdW5kbGVbbDEwbktleS5yYXdLZXldKSkge1xuICAgICAgICAgICAgICAgIC8vIHByZXZlbnQgZW1wdHkgYXJyYXlcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlQnVuZGxlW2wxMG5LZXkucmF3S2V5XVswXSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlQnVuZGxlW2wxMG5LZXkucmF3S2V5XVswXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBzb3VyY2VCdW5kbGVbbDEwbktleS5yYXdLZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignTm8gRW5nbGlzaCBmb3VuZCBmb3Iga2V5OiAlcyBpbiBzb3VyY2VCdW5kbGUnLCBrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGtleSBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgc291cmNlQnVuZGxlcyBvciB0cmFuc2xhdGlvbi5cbiAgICAgKiBpZiB0aGUgbG9jYWxlIGlzIHNvdXJjZSBsb2NhbGUsIGNoZWNrIHdoZXRoZXIgdGhlIGtleSBleGlzdHMgaW4gc291cmNlQnVuZGxlcy5cbiAgICAgKiBpZiB0aGUgbG9jYWxlIGlzIG5vdCBzb3VyY2UgbG9jYWxlLCBjaGVjayB3aGV0aGVyIHRoZSBrZXkgZXhpc3RzIGluIHRyYW5zbGF0aW9uLlxuICAgICAqIEBwYXJhbSBrZXkgcmF3IGtleSB3aXRoIG5hbWVzcGFjZVxuICAgICAqIEBwYXJhbSBsb2NhbGVcbiAgICAgKi9cbiAgICBwdWJsaWMgaXNFeGlzdEtleShrZXk6IHN0cmluZywgbG9jYWxlPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGwxMG5LZXkgPSB0aGlzLnBhcnNlS2V5KGtleSk7XG4gICAgICAgIGlmICh0aGlzLmxvY2FsZVNlcnZpY2UuaXNTb3VyY2VMYW5ndWFnZSkge1xuICAgICAgICAgICAgbG9jYWxlID0gdGhpcy5sb2NhbGVTZXJ2aWNlLmRlZmF1bHRMb2NhbGUubGFuZ3VhZ2VDb2RlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9jYWxlID0gbG9jYWxlID8gbG9jYWxlIDogdGhpcy5jdXJyZW50TG9jYWxlO1xuICAgICAgICB9XG4gICAgICAgIC8vIHNvdXJjZUJ1bmRsZSBvciB0cmFuc2xhdGlvbnNcbiAgICAgICAgY29uc3QgcmVzb3VyY2VCdW5kbGUgPSB0aGlzLnJlc29sdmVMb2NhbGVEYXRhKGwxMG5LZXkubmFtZVNwYWNlLCBsb2NhbGUpO1xuICAgICAgICBjb25zdCBpc0V4aXN0ID0gcmVzb3VyY2VCdW5kbGUgJiYgcmVzb3VyY2VCdW5kbGVbbDEwbktleS5yYXdLZXldID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICByZXR1cm4gaXNFeGlzdDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGZvcm1hdE1lc3NhZ2UoaXNGYWxsYmFjazogYm9vbGVhbiwgbG9jYWxlOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZywgYXJncz86IHN0cmluZ1tdIHwge30pIHtcbiAgICAgICAgaWYgKGlzRmFsbGJhY2spIHsgbG9jYWxlID0gdGhpcy5sb2NhbGVTZXJ2aWNlLmRlZmF1bHRMb2NhbGUubGFuZ3VhZ2VDb2RlOyB9XG4gICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2VGb3JtYXQuZm9ybWF0KGxvY2FsZSwgbWVzc2FnZSwgYXJncyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGtleSByYXcga2V5IHdpdGggbmFtZXNwYWNlXG4gICAgICogQHBhcmFtIHNvdXJjZSBzb3VyY2Ugc3RyaW5nIGZvciB0cmFuc2xhdGlvblxuICAgICAqIEBwYXJhbSBhcmdzIHZhcmlhYmxlcyBmb3IgcGxhY2Vob2xkZXJzXG4gICAgICogQHBhcmFtIGxvY2FsZSB3b3JrIHdpdGggc3RlYW0gQVBJXG4gICAgICovXG4gICAgcHVibGljIHRyYW5zbGF0ZShrZXk6IHN0cmluZywgc291cmNlOiBzdHJpbmcsIGFyZ3M/OiBhbnlbXSB8IHt9LCBsb2NhbGU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBsZXQgdHJhbnNsYXRpb246IHN0cmluZztcbiAgICAgICAgbGV0IGlzRmFsbGJhY2s6IGJvb2xlYW47XG4gICAgICAgIGNvbnN0IGwxMG5LZXkgPSB0aGlzLnBhcnNlS2V5KGtleSk7XG4gICAgICAgIGlmICh0aGlzLmxvY2FsZVNlcnZpY2UuaXNTb3VyY2VMYW5ndWFnZSkge1xuICAgICAgICAgICAgdHJhbnNsYXRpb24gPSBzb3VyY2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2NhbGUgPSBsb2NhbGUgPyBsb2NhbGUgOiB0aGlzLmN1cnJlbnRMb2NhbGU7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2xhdGlvbnMgPSB0aGlzLnJlc29sdmVMb2NhbGVEYXRhKGwxMG5LZXkubmFtZVNwYWNlLCBsb2NhbGUpO1xuICAgICAgICAgICAgdHJhbnNsYXRpb24gPSB0cmFuc2xhdGlvbnMgPyB0cmFuc2xhdGlvbnNbbDEwbktleS5yYXdLZXldIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKCF0cmFuc2xhdGlvbiB8fCB0cmFuc2xhdGlvbiA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbiA9IHNvdXJjZTtcbiAgICAgICAgICAgICAgICBjb25zdCBwc2V1ZG9JbkNvbmZpZyA9IHRoaXMudmlwU2VydmljZS5tYWluQ29uZmlnICYmIHRoaXMudmlwU2VydmljZS5tYWluQ29uZmlnLmlzUHNldWRvO1xuICAgICAgICAgICAgICAgIGNvbnN0IGkxOG5FbmFibGVkID0gdGhpcy5pMThuQ29udGV4dC5pMThuRW5hYmxlZCAhPT0gZmFsc2U7XG4gICAgICAgICAgICAgICAgaWYgKHBzZXVkb0luQ29uZmlnICYmIGkxOG5FbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9uID0gYCR7cHNldWRvVGFnfSR7c291cmNlfSR7cHNldWRvVGFnfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlzRmFsbGJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0cmFuc2xhdGlvbiAmJiB0cmFuc2xhdGlvbi50cmltKCkgIT09ICcnKSB7XG4gICAgICAgICAgICB0cmFuc2xhdGlvbiA9IHRoaXMuZm9ybWF0TWVzc2FnZShpc0ZhbGxiYWNrLCBsb2NhbGUsIHRyYW5zbGF0aW9uLCBhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJhbnNsYXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGtleSByYXcga2V5IHdpdGggbmFtZXNwYWNlXG4gICAgICogQHBhcmFtIGFyZ3MgdmFyaWFibGVzIGFuZCBjb21tZW50XG4gICAgICogQHBhcmFtIGxvY2FsZSBvcHRpbmFsIHBhcmFtZXRlciBmb3IgbGl2ZSB1cGRhdGUgdGhyb3VnaCAnc3RyZWFtJyBBUElcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0TWVzc2FnZShrZXk6IHN0cmluZywgYXJncz86IGFueVtdIHwge30sIGxvY2FsZT86IHN0cmluZykge1xuICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICAgICAgICBpZiAoIWlzRGVmaW5lZChrZXkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERldGVjdCB3aGV0aGVyIGV4aXN0aW5nIE9iamVjdCBpbiBhcmdzIEFycmF5LCBpZiBleGlzdCwgY29udmVydCB0aGVtIGludG8gc3RyaW5nc1xuICAgICAgICBhcmdzID0gZmlsdGVyQXJncyhhcmdzKTtcblxuICAgICAgICBjb25zdCBzb3VyY2UgPSB0aGlzLmdldFNvdXJjZVN0cmluZyhrZXkpO1xuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbiA9IHRoaXMudHJhbnNsYXRlKGtleSwgc291cmNlLCBhcmdzLCBsb2NhbGUpO1xuICAgICAgICByZXR1cm4gdHJhbnNsYXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBBUEkgaXMgZGVzaWduZWQgdG8gZ2VuZXJhdGUgc2NvcGVkIHRyYW5zbGF0ZSBtZXRob2QgZm9yIHRoZSBpc29sYXRlZCBtb2R1bGUuXG4gICAgICogVGhlIGtleSB3aXRoIG5hbWVzcGFjZSB3aGljaCBpcyBnZW5lcmF0ZWQgYnkgdGhlIGNvbmZpZ3VyYXRpb24uXG4gICAgICogQHBhcmFtIGNvbmZpZyBUaGUgVklQIGNvbmZpZ3VyYXRpb24gd2l0aCBwcm9kdWN0IG5hbWUsIGNvbXBvbmVudCBuYW1lIGFuZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRTY29wZWRUcmFuc2xhdGUoY29uZmlnOiBWSVBDb25maWcpOiBGdW5jdGlvbiB7XG4gICAgICAgIHJldHVybiAoa2V5OiBzdHJpbmcsIGFyZ3M/OiBhbnlbXSB8IHt9LCBsb2NhbGU/OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxvbmdLZXkgPSB0aGlzLmdldExvbmdLZXkoY29uZmlnLCBrZXkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShsb25nS2V5LCBhcmdzLCBsb2NhbGUpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGdldFNwbGl0ZWRNZXNzYWdlXG4gICAgICogZ2V0IG1lc3NhZ2UgYXJyYXkgc3BsaXRlZCBieSB0aGUgc2VwZXJhdG9yXG4gICAgICogQHBhcmFtIGtleSByYXcga2V5IHdpdGggbmFtZXNwYWNlXG4gICAgICogQHBhcmFtIGFyZ3MgdmFyaWFibGVzXG4gICAgICogQHBhcmFtIGxvY2FsZSBvcHRpbmFsIHBhcmFtZXRlciBmb3IgbGl2ZSB1cGRhdGUgdGhyb3VnaCAnc3RyZWFtJyBBUElcbiAgICAgKiBAcGFyYW0gc2VwZXJhdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9ucywgZGVmYXVsdCB2YWx1ZSBpcyAvIyNcXGQrL1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXRTcGxpdGVkTWVzc2FnZShrZXk6IHN0cmluZywgYXJncz86IGFueVtdLCBsb2NhbGU/OiBzdHJpbmcsIHNlcGVyYXRvcj86IFJlZ0V4cCkge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gdGhpcy5nZXRNZXNzYWdlKGtleSwgYXJncywgbG9jYWxlKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdFNlcGVyYXRvciA9IC8jI1xcZCsvO1xuICAgICAgICBzZXBlcmF0b3IgPSBpc0RlZmluZWQoc2VwZXJhdG9yKSA/IHNlcGVyYXRvciA6IGRlZmF1bHRTZXBlcmF0b3I7XG4gICAgICAgIHJldHVybiBtZXNzYWdlLnNwbGl0KHNlcGVyYXRvcik7XG4gICAgfVxufVxuIl19