UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

179 lines 25.6 kB
import { Injectable } from '@angular/core'; import { ApplicationAvailability, ApplicationService, ApplicationType, FetchClient } from '@c8y/client'; import { AppStateService, ZipService } from '@c8y/ngx-components'; import { uniq } from 'lodash-es'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/client"; import * as i2 from "@c8y/ngx-components"; export class TranslationStoreService { constructor(appService, appState, zip, fetchClient) { this.appService = appService; this.appState = appState; this.zip = zip; this.fetchClient = fetchClient; this.translationAppName = 'User defined translations'; this.translationAppContextPath = 'user-defined-translations'; } /** * Retrieves a list of available translations for the given locales from all the hosted apps available on the tenant. */ async getAvailableTranslations(locales) { const { data: hostedApps } = await this.appService.list({ tenant: this.appState.currentTenant.value.name, type: 'HOSTED', pageSize: 2000 }); const uniqueContextPaths = uniq(hostedApps .filter(app => app.contextPath && app.manifest?.webSdkVersion) .map(app => app.contextPath)); const translations = {}; for (const contextPath of uniqueContextPaths) { for (const locale of locales) { try { const translationsForLanguageAndApp = await this.getFileFromPath(`/apps/${contextPath}/${locale}.json`); const translationsForLang = translationsForLanguageAndApp[locale]; for (const key of Object.keys(translationsForLang)) { if (!translations[key]) { translations[key] = {}; } translations[key][locale] = translationsForLang[key]; } } catch (e) { continue; } } } return translations; } /** * Retrieves the translations for the given locale from the translation app. */ async getTranslationsForLocale(locale) { try { const translations = await this.getFileFromTranslationApp(`${locale}.json`); if (translations[locale]) { return translations[locale]; } } catch (e) { // do nothing. } return {}; } /** * Retrieves the translations for the given locales from the translation app. */ async loadTranslationsForLocales(locales) { const translations = {}; const loadAndAddLocale = async (locale) => { translations[locale] = await this.getTranslationsForLocale(locale); }; await Promise.all(locales.map(loadAndAddLocale)); return translations; } /** * Retrieves a combined list of translations for all the provided locales. * The locales are combined into a single object per key and an array of these objects is returned. */ async getCombinedListOfTranslationsForPerKey(locales) { const translations = await this.loadTranslationsForLocales(locales); const translationMap = {}; for (const locale of Object.keys(translations)) { for (const key of Object.keys(translations[locale])) { let translationsForKey = translationMap[key]; if (!translationsForKey) { translationsForKey = {}; translationMap[key] = translationsForKey; } translationsForKey[locale] = translations[locale][key]; } } const keys = Object.keys(translationMap).sort((a, b) => a.localeCompare(b)); return keys.map(key => Object.assign({ key }, translationMap[key])); } /** * Updates the files of the translation application with the provided translations. */ async updateTranslations(translations) { const filesToUpload = new Array(); const translationsPerLocale = {}; for (const entry of translations) { const key = entry.key; for (const locale of Object.keys(entry)) { if (locale === 'key') { continue; } if (!translationsPerLocale[locale]) { translationsPerLocale[locale] = {}; } if (entry[locale]) { translationsPerLocale[locale][key] = entry[locale]; } } } const langs = this.appState.state.langs; for (const locale of langs) { const fileName = `${locale}.json`; filesToUpload.push({ path: fileName, contents: new File([JSON.stringify({ [locale]: translationsPerLocale[locale] || {} })], fileName) }); } const app = await this.getOrCreateTranslationApp(); await this.appService.binary(app).updateFiles(filesToUpload); } /** * @returns The translation app for the current tenant. If it does not exist, it will be created. */ async getOrCreateTranslationApp() { const { data: apps } = await this.appService.listByName(this.translationAppName); const ownApp = apps.find(app => app.contextPath === this.translationAppContextPath && app.owner.tenant.id === this.appState.currentTenant.value.name); if (ownApp) { return ownApp; } const { data: app } = await this.appService.create({ name: this.translationAppName, contextPath: this.translationAppContextPath, key: `${this.translationAppContextPath}-app-key`, type: ApplicationType.HOSTED, availability: ApplicationAvailability.MARKET, config: { icon: { class: 'language1' } }, noAppSwitcher: true, description: 'Providing user defined translations' }); const zip = await this.zip.createZip([]); const { data: binary } = await this.appService.binary(app).upload(zip, 'translations.zip'); const { data: updatedApp } = await this.appService.update({ id: app.id, activeVersionId: binary.id }); return updatedApp; } async getFileFromTranslationApp(file) { return this.getFileFromPath(`/apps/public/${this.translationAppContextPath}/${file}`); } async getFileFromPath(path) { const finalPath = `${path}?nocache=${Date.now()}`; // using fetch client instead of fetch directly here to ensure loading indicator is shown during these requests const response = await this.fetchClient.fetch(finalPath); if (response.status !== 200) { throw new Error(`Failed to fetch file from ${path}`); } return response.json(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationStoreService, deps: [{ token: i1.ApplicationService }, { token: i2.AppStateService }, { token: i2.ZipService }, { token: i1.FetchClient }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationStoreService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationStoreService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.ApplicationService }, { type: i2.AppStateService }, { type: i2.ZipService }, { type: i1.FetchClient }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRpb24tc3RvcmUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RyYW5zbGF0aW9uLWVkaXRvci9kYXRhL3RyYW5zbGF0aW9uLXN0b3JlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGtCQUFrQixFQUNsQixlQUFlLEVBQ2YsV0FBVyxFQUVaLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbEUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQzs7OztBQVVqQyxNQUFNLE9BQU8sdUJBQXVCO0lBSWxDLFlBQ1UsVUFBOEIsRUFDOUIsUUFBeUIsRUFDekIsR0FBZSxFQUNmLFdBQXdCO1FBSHhCLGVBQVUsR0FBVixVQUFVLENBQW9CO1FBQzlCLGFBQVEsR0FBUixRQUFRLENBQWlCO1FBQ3pCLFFBQUcsR0FBSCxHQUFHLENBQVk7UUFDZixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQVBmLHVCQUFrQixHQUFHLDJCQUEyQixDQUFDO1FBQ2pELDhCQUF5QixHQUFHLDJCQUEyQixDQUFDO0lBT3hFLENBQUM7SUFFSjs7T0FFRztJQUNILEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxPQUFpQjtRQUM5QyxNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7WUFDdEQsTUFBTSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJO1lBQzlDLElBQUksRUFBRSxRQUFRO1lBQ2QsUUFBUSxFQUFFLElBQUk7U0FDZixDQUFDLENBQUM7UUFFSCxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FD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SUFBWTtRQUNsRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLElBQUksQ0FBQyx5QkFBeUIsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFFTyxLQUFLLENBQUMsZUFBZSxDQUFDLElBQVk7UUFDeEMsTUFBTSxTQUFTLEdBQUcsR0FBRyxJQUFJLFlBQVksSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUM7UUFFbEQsK0dBQStHO1FBQy9HLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFekQsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELE9BQU8sUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3pCLENBQUM7K0dBOU1VLHVCQUF1QjttSEFBdkIsdUJBQXVCLGNBRnRCLE1BQU07OzRGQUVQLHVCQUF1QjtrQkFIbkMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvbkF2YWlsYWJpbGl0eSxcbiAgQXBwbGljYXRpb25TZXJ2aWNlLFxuICBBcHBsaWNhdGlvblR5cGUsXG4gIEZldGNoQ2xpZW50LFxuICBJQXBwbGljYXRpb25cbn0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQXBwU3RhdGVTZXJ2aWNlLCBaaXBTZXJ2aWNlIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyB1bmlxIH0gZnJvbSAnbG9kYXNoLWVzJztcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xhdGlvbkxvY2FsZSB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIGxvY2FsZTogc3RyaW5nO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBUcmFuc2xhdGlvblN0b3JlU2VydmljZSB7XG4gIHByb3RlY3RlZCByZWFkb25seSB0cmFuc2xhdGlvbkFwcE5hbWUgPSAnVXNlciBkZWZpbmVkIHRyYW5zbGF0aW9ucyc7XG4gIHByb3RlY3RlZCByZWFkb25seSB0cmFuc2xhdGlvbkFwcENvbnRleHRQYXRoID0gJ3VzZXItZGVmaW5lZC10cmFuc2xhdGlvbnMnO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYXBwU2VydmljZTogQXBwbGljYXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgYXBwU3RhdGU6IEFwcFN0YXRlU2VydmljZSxcbiAgICBwcml2YXRlIHppcDogWmlwU2VydmljZSxcbiAgICBwcml2YXRlIGZldGNoQ2xpZW50OiBGZXRjaENsaWVudFxuICApIHt9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBhIGxpc3Qgb2YgYXZhaWxhYmxlIHRyYW5zbGF0aW9ucyBmb3IgdGhlIGdpdmVuIGxvY2FsZXMgZnJvbSBhbGwgdGhlIGhvc3RlZCBhcHBzIGF2YWlsYWJsZSBvbiB0aGUgdGVuYW50LlxuICAgKi9cbiAgYXN5bmMgZ2V0QXZhaWxhYmxlVHJhbnNsYXRpb25zKGxvY2FsZXM6IHN0cmluZ1tdKSB7XG4gICAgY29uc3QgeyBkYXRhOiBob3N0ZWRBcHBzIH0gPSBhd2FpdCB0aGlzLmFwcFNlcnZpY2UubGlzdCh7XG4gICAgICB0ZW5hbnQ6IHRoaXMuYXBwU3RhdGUuY3VycmVudFRlbmFudC52YWx1ZS5uYW1lLFxuICAgICAgdHlwZTogJ0hPU1RFRCcsXG4gICAgICBwYWdlU2l6ZTogMjAwMFxuICAgIH0pO1xuXG4gICAgY29uc3QgdW5pcXVlQ29udGV4dFBhdGhzID0gdW5pcShcbiAgICAgIGhvc3RlZEFwcHNcbiAgICAgICAgLmZpbHRlcihhcHAgPT4gYXBwLmNvbnRleHRQYXRoICYmIGFwcC5tYW5pZmVzdD8ud2ViU2RrVmVyc2lvbilcbiAgICAgICAgLm1hcChhcHAgPT4gYXBwLmNvbnRleHRQYXRoKVxuICAgICk7XG5cbiAgICBjb25zdCB0cmFuc2xhdGlvbnM6IHsgW2tleTogc3RyaW5nXTogeyBbbG9jYWxlOiBzdHJpbmddOiBzdHJpbmcgfSB9ID0ge307XG4gICAgZm9yIChjb25zdCBjb250ZXh0UGF0aCBvZiB1bmlxdWVDb250ZXh0UGF0aHMpIHtcbiAgICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0cmFuc2xhdGlvbnNGb3JMYW5ndWFnZUFuZEFwcCA9IGF3YWl0IHRoaXMuZ2V0RmlsZUZyb21QYXRoKFxuICAgICAgICAgICAgYC9hcHBzLyR7Y29udGV4dFBhdGh9LyR7bG9jYWxlfS5qc29uYFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgdHJhbnNsYXRpb25zRm9yTGFuZyA9IHRyYW5zbGF0aW9uc0Zvckxhbmd1YWdlQW5kQXBwW2xvY2FsZV07XG4gICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModHJhbnNsYXRpb25zRm9yTGFuZykpIHtcbiAgICAgICAgICAgIGlmICghdHJhbnNsYXRpb25zW2tleV0pIHtcbiAgICAgICAgICAgICAgdHJhbnNsYXRpb25zW2tleV0gPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyYW5zbGF0aW9uc1trZXldW2xvY2FsZV0gPSB0cmFuc2xhdGlvbnNGb3JMYW5nW2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJhbnNsYXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgdHJhbnNsYXRpb25zIGZvciB0aGUgZ2l2ZW4gbG9jYWxlIGZyb20gdGhlIHRyYW5zbGF0aW9uIGFwcC5cbiAgICovXG4gIGFzeW5jIGdldFRyYW5zbGF0aW9uc0ZvckxvY2FsZTxUIGV4dGVuZHMgc3RyaW5nPihsb2NhbGU6IFQpOiBQcm9taXNlPHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNsYXRpb25zID0gYXdhaXQgdGhpcy5nZXRGaWxlRnJvbVRyYW5zbGF0aW9uQXBwKGAke2xvY2FsZX0uanNvbmApO1xuICAgICAgaWYgKHRyYW5zbGF0aW9uc1tsb2NhbGVdKSB7XG4gICAgICAgIHJldHVybiB0cmFuc2xhdGlvbnNbbG9jYWxlXTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBkbyBub3RoaW5nLlxuICAgIH1cbiAgICByZXR1cm4ge307XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSB0cmFuc2xhdGlvbnMgZm9yIHRoZSBnaXZlbiBsb2NhbGVzIGZyb20gdGhlIHRyYW5zbGF0aW9uIGFwcC5cbiAgICovXG4gIGFzeW5jIGxvYWRUcmFuc2xhdGlvbnNGb3JMb2NhbGVzKGxvY2FsZXM6IHN0cmluZ1tdKTogUHJvbWlzZTx7XG4gICAgW2tleTogc3RyaW5nXToge1xuICAgICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICAgIH07XG4gIH0+IHtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnM6IHtcbiAgICAgIFtrZXk6IHN0cmluZ106IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG4gICAgfSA9IHt9O1xuXG4gICAgY29uc3QgbG9hZEFuZEFkZExvY2FsZSA9IGFzeW5jIChsb2NhbGU6IHN0cmluZykgPT4ge1xuICAgICAgdHJhbnNsYXRpb25zW2xvY2FsZV0gPSBhd2FpdCB0aGlzLmdldFRyYW5zbGF0aW9uc0ZvckxvY2FsZShsb2NhbGUpO1xuICAgIH07XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbChsb2NhbGVzLm1hcChsb2FkQW5kQWRkTG9jYWxlKSk7XG5cbiAgICByZXR1cm4gdHJhbnNsYXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBhIGNvbWJpbmVkIGxpc3Qgb2YgdHJhbnNsYXRpb25zIGZvciBhbGwgdGhlIHByb3ZpZGVkIGxvY2FsZXMuXG4gICAqIFRoZSBsb2NhbGVzIGFyZSBjb21iaW5lZCBpbnRvIGEgc2luZ2xlIG9iamVjdCBwZXIga2V5IGFuZCBhbiBhcnJheSBvZiB0aGVzZSBvYmplY3RzIGlzIHJldHVybmVkLlxuICAgKi9cbiAgYXN5bmMgZ2V0Q29tYmluZWRMaXN0T2ZUcmFuc2xhdGlvbnNGb3JQZXJLZXkoXG4gICAgbG9jYWxlczogc3RyaW5nW11cbiAgKTogUHJvbWlzZTx7IGtleTogc3RyaW5nOyBbbG9jYWxlOiBzdHJpbmddOiBzdHJpbmcgfVtdPiB7XG4gICAgY29uc3QgdHJhbnNsYXRpb25zID0gYXdhaXQgdGhpcy5sb2FkVHJhbnNsYXRpb25zRm9yTG9jYWxlcyhsb2NhbGVzKTtcbiAgICBjb25zdCB0cmFuc2xhdGlvbk1hcDogeyBba2V5OiBzdHJpbmddOiB7IFtsb2NhbGU6IHN0cmluZ106IHN0cmluZyB9IH0gPSB7fTtcblxuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIE9iamVjdC5rZXlzKHRyYW5zbGF0aW9ucykpIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRyYW5zbGF0aW9uc1tsb2NhbGVdKSkge1xuICAgICAgICBsZXQgdHJhbnNsYXRpb25zRm9yS2V5ID0gdHJhbnNsYXRpb25NYXBba2V5XTtcbiAgICAgICAgaWYgKCF0cmFuc2xhdGlvbnNGb3JLZXkpIHtcbiAgICAgICAgICB0cmFuc2xhdGlvbnNGb3JLZXkgPSB7fTtcbiAgICAgICAgICB0cmFuc2xhdGlvbk1hcFtrZXldID0gdHJhbnNsYXRpb25zRm9yS2V5O1xuICAgICAgICB9XG5cbiAgICAgICAgdHJhbnNsYXRpb25zRm9yS2V5W2xvY2FsZV0gPSB0cmFuc2xhdGlvbnNbbG9jYWxlXVtrZXldO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyh0cmFuc2xhdGlvbk1hcCkuc29ydCgoYSwgYikgPT4gYS5sb2NhbGVDb21wYXJlKGIpKTtcblxuICAgIHJldHVybiBrZXlzLm1hcChrZXkgPT4gT2JqZWN0LmFzc2lnbih7IGtleSB9LCB0cmFuc2xhdGlvbk1hcFtrZXldKSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgZmlsZXMgb2YgdGhlIHRyYW5zbGF0aW9uIGFwcGxpY2F0aW9uIHdpdGggdGhlIHByb3ZpZGVkIHRyYW5zbGF0aW9ucy5cbiAgICovXG4gIGFzeW5jIHVwZGF0ZVRyYW5zbGF0aW9ucyhcbiAgICB0cmFuc2xhdGlvbnM6IHsga2V5OiBzdHJpbmc7IFtsb2NhbGU6IHN0cmluZ106IHN0cmluZyB9W11cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZmlsZXNUb1VwbG9hZCA9IG5ldyBBcnJheTx7IHBhdGg6IHN0cmluZzsgY29udGVudHM6IEZpbGUgfT4oKTtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnNQZXJMb2NhbGU6IHsgW2xvY2FsZTogc3RyaW5nXTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB9ID0ge307XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiB0cmFuc2xhdGlvbnMpIHtcbiAgICAgIGNvbnN0IGtleSA9IGVudHJ5LmtleTtcbiAgICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIE9iamVjdC5rZXlzKGVudHJ5KSkge1xuICAgICAgICBpZiAobG9jYWxlID09PSAna2V5Jykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdHJhbnNsYXRpb25zUGVyTG9jYWxlW2xvY2FsZV0pIHtcbiAgICAgICAgICB0cmFuc2xhdGlvbnNQZXJMb2NhbGVbbG9jYWxlXSA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVudHJ5W2xvY2FsZV0pIHtcbiAgICAgICAgICB0cmFuc2xhdGlvbnNQZXJMb2NhbGVbbG9jYWxlXVtrZXldID0gZW50cnlbbG9jYWxlXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGxhbmdzID0gdGhpcy5hcHBTdGF0ZS5zdGF0ZS5sYW5ncyBhcyBzdHJpbmdbXTtcblxuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxhbmdzKSB7XG4gICAgICBjb25zdCBmaWxlTmFtZSA9IGAke2xvY2FsZX0uanNvbmA7XG4gICAgICBmaWxlc1RvVXBsb2FkLnB1c2goe1xuICAgICAgICBwYXRoOiBmaWxlTmFtZSxcbiAgICAgICAgY29udGVudHM6IG5ldyBGaWxlKFxuICAgICAgICAgIFtKU09OLnN0cmluZ2lmeSh7IFtsb2NhbGVdOiB0cmFuc2xhdGlvbnNQZXJMb2NhbGVbbG9jYWxlXSB8fCB7fSB9KV0sXG4gICAgICAgICAgZmlsZU5hbWVcbiAgICAgICAgKVxuICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IGFwcCA9IGF3YWl0IHRoaXMuZ2V0T3JDcmVhdGVUcmFuc2xhdGlvbkFwcCgpO1xuICAgIGF3YWl0IHRoaXMuYXBwU2VydmljZS5iaW5hcnkoYXBwKS51cGRhdGVGaWxlcyhmaWxlc1RvVXBsb2FkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyBUaGUgdHJhbnNsYXRpb24gYXBwIGZvciB0aGUgY3VycmVudCB0ZW5hbnQuIElmIGl0IGRvZXMgbm90IGV4aXN0LCBpdCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAqL1xuICBhc3luYyBnZXRPckNyZWF0ZVRyYW5zbGF0aW9uQXBwKCk6IFByb21pc2U8SUFwcGxpY2F0aW9uPiB7XG4gICAgY29uc3QgeyBkYXRhOiBhcHBzIH0gPSBhd2FpdCB0aGlzLmFwcFNlcnZpY2UubGlzdEJ5TmFtZSh0aGlzLnRyYW5zbGF0aW9uQXBwTmFtZSk7XG4gICAgY29uc3Qgb3duQXBwID0gYXBwcy5maW5kKFxuICAgICAgYXBwID0+XG4gICAgICAgIGFwcC5jb250ZXh0UGF0aCA9PT0gdGhpcy50cmFuc2xhdGlvbkFwcENvbnRleHRQYXRoICYmXG4gICAgICAgIGFwcC5vd25lci50ZW5hbnQuaWQgPT09IHRoaXMuYXBwU3RhdGUuY3VycmVudFRlbmFudC52YWx1ZS5uYW1lXG4gICAgKTtcbiAgICBpZiAob3duQXBwKSB7XG4gICAgICByZXR1cm4gb3duQXBwO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZGF0YTogYXBwIH0gPSBhd2FpdCB0aGlzLmFwcFNlcnZpY2UuY3JlYXRlKHtcbiAgICAgIG5hbWU6IHRoaXMudHJhbnNsYXRpb25BcHBOYW1lLFxuICAgICAgY29udGV4dFBhdGg6IHRoaXMudHJhbnNsYXRpb25BcHBDb250ZXh0UGF0aCxcbiAgICAgIGtleTogYCR7dGhpcy50cmFuc2xhdGlvbkFwcENvbnRleHRQYXRofS1hcHAta2V5YCxcbiAgICAgIHR5cGU6IEFwcGxpY2F0aW9uVHlwZS5IT1NURUQsXG4gICAgICBhdmFpbGFiaWxpdHk6IEFwcGxpY2F0aW9uQXZhaWxhYmlsaXR5Lk1BUktFVCxcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBpY29uOiB7XG4gICAgICAgICAgY2xhc3M6ICdsYW5ndWFnZTEnXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBub0FwcFN3aXRjaGVyOiB0cnVlLFxuICAgICAgZGVzY3JpcHRpb246ICdQcm92aWRpbmcgdXNlciBkZWZpbmVkIHRyYW5zbGF0aW9ucydcbiAgICB9KTtcbiAgICBjb25zdCB6aXAgPSBhd2FpdCB0aGlzLnppcC5jcmVhdGVaaXAoW10pO1xuXG4gICAgY29uc3QgeyBkYXRhOiBiaW5hcnkgfSA9IGF3YWl0IHRoaXMuYXBwU2VydmljZS5iaW5hcnkoYXBwKS51cGxvYWQoemlwLCAndHJhbnNsYXRpb25zLnppcCcpO1xuICAgIGNvbnN0IHsgZGF0YTogdXBkYXRlZEFwcCB9ID0gYXdhaXQgdGhpcy5hcHBTZXJ2aWNlLnVwZGF0ZSh7XG4gICAgICBpZDogYXBwLmlkLFxuICAgICAgYWN0aXZlVmVyc2lvbklkOiBiaW5hcnkuaWQgYXMgc3RyaW5nXG4gICAgfSk7XG4gICAgcmV0dXJuIHVwZGF0ZWRBcHA7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldEZpbGVGcm9tVHJhbnNsYXRpb25BcHAoZmlsZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0RmlsZUZyb21QYXRoKGAvYXBwcy9wdWJsaWMvJHt0aGlzLnRyYW5zbGF0aW9uQXBwQ29udGV4dFBhdGh9LyR7ZmlsZX1gKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0RmlsZUZyb21QYXRoKHBhdGg6IHN0cmluZykge1xuICAgIGNvbnN0IGZpbmFsUGF0aCA9IGAke3BhdGh9P25vY2FjaGU9JHtEYXRlLm5vdygpfWA7XG5cbiAgICAvLyB1c2luZyBmZXRjaCBjbGllbnQgaW5zdGVhZCBvZiBmZXRjaCBkaXJlY3RseSBoZXJlIHRvIGVuc3VyZSBsb2FkaW5nIGluZGljYXRvciBpcyBzaG93biBkdXJpbmcgdGhlc2UgcmVxdWVzdHNcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZmV0Y2hDbGllbnQuZmV0Y2goZmluYWxQYXRoKTtcblxuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZmV0Y2ggZmlsZSBmcm9tICR7cGF0aH1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuICB9XG59XG4iXX0=