UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

136 lines 26 kB
import { NgIf } from '@angular/common'; import { Component, signal, ViewChild, computed } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { ActionBarItemComponent, AlertService, AppStateService, IconDirective, LoadingComponent, TitleComponent } from '@c8y/ngx-components'; import { EditorComponent, MonacoEditorMarkerValidatorDirective } from '@c8y/ngx-components/editor'; import { TranslationStoreService } from '@c8y/ngx-components/translation-editor/data'; import { gettext } from '@c8y/ngx-components/gettext'; import { TranslateService } from '@ngx-translate/core'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/ngx-components"; import * as i2 from "@c8y/ngx-components/translation-editor/data"; import * as i3 from "@ngx-translate/core"; import * as i4 from "@angular/forms"; export class AdvancedTranslationEditorComponent { constructor(appState, translationStore, alert, translation) { this.appState = appState; this.translationStore = translationStore; this.alert = alert; this.translation = translation; this.valueString = signal(''); this.editorOptions = { language: 'json' }; this.isLoading = signal(false); this.isValidJSON = computed(() => { const data = this.valueString(); try { JSON.parse(data); return true; } catch (e) { return false; } }); this.availableLangs = []; this.availableLangs = this.appState.state.langs.sort((a, b) => a.localeCompare(b)); this.refresh(); } onValueChange(data) { this.valueString.set(data); } onEditorInit(_data) { this.editorComponent.monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ validate: true, schemas: [{ schema: this.JSONSchema, fileMatch: ['*'], uri: 'translation' }], enableSchemaRequest: false, allowComments: false }); } async refresh() { this.isLoading.set(true); const translationProperties = this.availableLangs.reduceRight((acc, lang) => { acc[lang] = { type: 'string', description: this.translation.instant(gettext('Translation for "{{ languageCode }}" language.'), { languageCode: lang }) }; return acc; }, { key: { type: 'string', description: this.translation.instant(gettext('The key to be translated.')) } }); this.JSONSchema = { $schema: 'http://json-schema.org/draft-04/schema#', type: 'array', items: { type: 'object', properties: translationProperties, required: ['key'], minProperties: 2 } }; const translations = await this.translationStore.getCombinedListOfTranslationsForPerKey(this.availableLangs); this.valueString.set(JSON.stringify(translations, undefined, 2)); this.isLoading.set(false); } async importTranslationKeys() { try { this.alert.info(gettext('Importing translation from available Web SDK based applications. This may take a while...')); // since we are only interested in the keys, we only need to retrieve the translations for one (well supported) language // we assume that the keys are the same for all other languages, otherwise we would need to perform a lot more requests. const data = await this.translationStore.getAvailableTranslations(['de']); const valueString = this.valueString(); const values = JSON.parse(valueString); const previousNumberOfEntries = values.length; const retrievedKeys = Object.keys(data); for (const key of retrievedKeys) { const foundKey = values.find(value => value.key === key); if (!foundKey) { values.push({ key }); } } const newpreviousNumberOfEntries = values.length; this.valueString.set(JSON.stringify(values, undefined, 2)); this.alert.success(this.translation.instant(gettext('Retrieved {{ numberOfRetrievedKeys }} keys from available applications. {{ numberOfNewKeys }} new translation keys were added.'), { numberOfRetrievedKeys: retrievedKeys.length, numberOfNewKeys: newpreviousNumberOfEntries - previousNumberOfEntries })); } catch (e) { this.alert.danger(gettext('Failed to import translation keys')); this.alert.addServerFailure(e); } } async saveTranslations() { try { await this.translationStore.updateTranslations(JSON.parse(this.valueString())); await this.refresh(); this.alert.success(gettext('Translations saved')); } catch (e) { this.alert.danger(gettext('Failed to save translations')); this.alert.addServerFailure(e); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AdvancedTranslationEditorComponent, deps: [{ token: i1.AppStateService }, { token: i2.TranslationStoreService }, { token: i1.AlertService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AdvancedTranslationEditorComponent, isStandalone: true, selector: "c8y-advanced-translation-editor", viewQueries: [{ propertyName: "editorComponent", first: true, predicate: EditorComponent, descendants: true }], ngImport: i0, template: "<c8y-title translate>Localization</c8y-title>\n\n<ng-container *ngIf=\"!isLoading(); else loading\">\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n [disabled]=\"!isValidJSON()\"\n (click)=\"saveTranslations()\"\n data-cy=\"c8y-translation-editor--save-and-apply\"\n >\n <i c8yIcon=\"save\"></i>\n <span translate>Save & apply</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n [disabled]=\"!isValidJSON()\"\n (click)=\"importTranslationKeys()\"\n data-cy=\"c8y-translation-editor--import-translation-keys\"\n >\n <i [c8yIcon]=\"'import'\"></i>\n <span translate>Import translation keys from Apps</span>\n </button>\n </c8y-action-bar-item>\n\n <div class=\"card card--fullpage content-fullpage\">\n <c8y-editor\n class=\"flex-grow\"\n [editorOptions]=\"editorOptions\"\n [ngModel]=\"valueString()\"\n (ngModelChange)=\"onValueChange($event)\"\n (editorInit)=\"onEditorInit($event)\"\n monacoEditorMarkerValidator\n ></c8y-editor>\n </div>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>", dependencies: [{ kind: "component", type: EditorComponent, selector: "c8y-editor", inputs: ["editorOptions"], outputs: ["editorInit"] }, { kind: "directive", type: MonacoEditorMarkerValidatorDirective, selector: "c8y-editor [monacoEditorMarkerValidator]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AdvancedTranslationEditorComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-advanced-translation-editor', standalone: true, imports: [ EditorComponent, MonacoEditorMarkerValidatorDirective, FormsModule, TitleComponent, LoadingComponent, NgIf, ActionBarItemComponent, IconDirective ], template: "<c8y-title translate>Localization</c8y-title>\n\n<ng-container *ngIf=\"!isLoading(); else loading\">\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n [disabled]=\"!isValidJSON()\"\n (click)=\"saveTranslations()\"\n data-cy=\"c8y-translation-editor--save-and-apply\"\n >\n <i c8yIcon=\"save\"></i>\n <span translate>Save & apply</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n [disabled]=\"!isValidJSON()\"\n (click)=\"importTranslationKeys()\"\n data-cy=\"c8y-translation-editor--import-translation-keys\"\n >\n <i [c8yIcon]=\"'import'\"></i>\n <span translate>Import translation keys from Apps</span>\n </button>\n </c8y-action-bar-item>\n\n <div class=\"card card--fullpage content-fullpage\">\n <c8y-editor\n class=\"flex-grow\"\n [editorOptions]=\"editorOptions\"\n [ngModel]=\"valueString()\"\n (ngModelChange)=\"onValueChange($event)\"\n (editorInit)=\"onEditorInit($event)\"\n monacoEditorMarkerValidator\n ></c8y-editor>\n </div>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>" }] }], ctorParameters: () => [{ type: i1.AppStateService }, { type: i2.TranslationStoreService }, { type: i1.AlertService }, { type: i3.TranslateService }], propDecorators: { editorComponent: [{ type: ViewChild, args: [EditorComponent] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2YW5jZWQtdHJhbnNsYXRpb24tZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3RyYW5zbGF0aW9uLWVkaXRvci9sYXp5L2FkdmFuY2VkLXRyYW5zbGF0aW9uLWVkaXRvci9hZHZhbmNlZC10cmFuc2xhdGlvbi1lZGl0b3IuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vdHJhbnNsYXRpb24tZWRpdG9yL2xhenkvYWR2YW5jZWQtdHJhbnNsYXRpb24tZWRpdG9yL2FkdmFuY2VkLXRyYW5zbGF0aW9uLWVkaXRvci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixZQUFZLEVBQ1osZUFBZSxFQUNmLGFBQWEsRUFDYixnQkFBZ0IsRUFDaEIsY0FBYyxFQUNmLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLGVBQWUsRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ25HLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDZDQUE2QyxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUV0RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7O0FBaUJ2RCxNQUFNLE9BQU8sa0NBQWtDO0lBbUI3QyxZQUNVLFFBQXlCLEVBQ3pCLGdCQUF5QyxFQUN6QyxLQUFtQixFQUNuQixXQUE2QjtRQUg3QixhQUFRLEdBQVIsUUFBUSxDQUFpQjtRQUN6QixxQkFB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bEMsZUFBZSxnRENoRDVCLDR1Q0F5Q2MsNENEbkJWLGVBQWUsMkdBQ2Ysb0NBQW9DLG9GQUNwQyxXQUFXLCtWQUNYLGNBQWMsbUZBQ2QsZ0JBQWdCLG1HQUNoQixJQUFJLDZGQUNKLHNCQUFzQiwwSkFDdEIsYUFBYTs7NEZBR0osa0NBQWtDO2tCQWY5QyxTQUFTOytCQUNFLGlDQUFpQyxjQUUvQixJQUFJLFdBQ1A7d0JBQ1AsZUFBZTt3QkFDZixvQ0FBb0M7d0JBQ3BDLFdBQVc7d0JBQ1gsY0FBYzt3QkFDZCxnQkFBZ0I7d0JBQ2hCLElBQUk7d0JBQ0osc0JBQXNCO3dCQUN0QixhQUFhO3FCQUNkO29MQWtCMkIsZUFBZTtzQkFBMUMsU0FBUzt1QkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdJZiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDb21wb25lbnQsIHNpZ25hbCwgVmlld0NoaWxkLCBjb21wdXRlZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICBBY3Rpb25CYXJJdGVtQ29tcG9uZW50LFxuICBBbGVydFNlcnZpY2UsXG4gIEFwcFN0YXRlU2VydmljZSxcbiAgSWNvbkRpcmVjdGl2ZSxcbiAgTG9hZGluZ0NvbXBvbmVudCxcbiAgVGl0bGVDb21wb25lbnRcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyBFZGl0b3JDb21wb25lbnQsIE1vbmFjb0VkaXRvck1hcmtlclZhbGlkYXRvckRpcmVjdGl2ZSB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvZWRpdG9yJztcbmltcG9ydCB7IFRyYW5zbGF0aW9uU3RvcmVTZXJ2aWNlIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy90cmFuc2xhdGlvbi1lZGl0b3IvZGF0YSc7XG5pbXBvcnQgeyBnZXR0ZXh0IH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9nZXR0ZXh0JztcbmltcG9ydCB0eXBlICogYXMgTW9uYWNvIGZyb20gJ21vbmFjby1lZGl0b3InO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktYWR2YW5jZWQtdHJhbnNsYXRpb24tZWRpdG9yJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2FkdmFuY2VkLXRyYW5zbGF0aW9uLWVkaXRvci5jb21wb25lbnQuaHRtbCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBFZGl0b3JDb21wb25lbnQsXG4gICAgTW9uYWNvRWRpdG9yTWFya2VyVmFsaWRhdG9yRGlyZWN0aXZlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIFRpdGxlQ29tcG9uZW50LFxuICAgIExvYWRpbmdDb21wb25lbnQsXG4gICAgTmdJZixcbiAgICBBY3Rpb25CYXJJdGVtQ29tcG9uZW50LFxuICAgIEljb25EaXJlY3RpdmVcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBBZHZhbmNlZFRyYW5zbGF0aW9uRWRpdG9yQ29tcG9uZW50IHtcbiAgdmFsdWVTdHJpbmcgPSBzaWduYWwoJycpO1xuICBlZGl0b3JPcHRpb25zOiBFZGl0b3JDb21wb25lbnRbJ2VkaXRvck9wdGlvbnMnXSA9IHtcbiAgICBsYW5ndWFnZTogJ2pzb24nXG4gIH07XG4gIGlzTG9hZGluZyA9IHNpZ25hbChmYWxzZSk7XG4gIGlzVmFsaWRKU09OID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLnZhbHVlU3RyaW5nKCk7XG4gICAgdHJ5IHtcbiAgICAgIEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbiAgSlNPTlNjaGVtYTogYW55O1xuICBAVmlld0NoaWxkKEVkaXRvckNvbXBvbmVudCkgZWRpdG9yQ29tcG9uZW50ITogRWRpdG9yQ29tcG9uZW50O1xuICBhdmFpbGFibGVMYW5nczogc3RyaW5nW10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGFwcFN0YXRlOiBBcHBTdGF0ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGlvblN0b3JlOiBUcmFuc2xhdGlvblN0b3JlU2VydmljZSxcbiAgICBwcml2YXRlIGFsZXJ0OiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGlvbjogVHJhbnNsYXRlU2VydmljZVxuICApIHtcbiAgICB0aGlzLmF2YWlsYWJsZUxhbmdzID0gKHRoaXMuYXBwU3RhdGUuc3RhdGUubGFuZ3MgYXMgc3RyaW5nW10pLnNvcnQoKGEsIGIpID0+XG4gICAgICBhLmxvY2FsZUNvbXBhcmUoYilcbiAgICApO1xuICAgIHRoaXMucmVmcmVzaCgpO1xuICB9XG5cbiAgb25WYWx1ZUNoYW5nZShkYXRhOiBzdHJpbmcpIHtcbiAgICB0aGlzLnZhbHVlU3RyaW5nLnNldChkYXRhKTtcbiAgfVxuXG4gIG9uRWRpdG9ySW5pdChfZGF0YTogTW9uYWNvLmVkaXRvci5JU3RhbmRhbG9uZUNvZGVFZGl0b3IpIHtcbiAgICB0aGlzLmVkaXRvckNvbXBvbmVudC5tb25hY28ubGFuZ3VhZ2VzLmpzb24uanNvbkRlZmF1bHRzLnNldERpYWdub3N0aWNzT3B0aW9ucyh7XG4gICAgICB2YWxpZGF0ZTogdHJ1ZSxcbiAgICAgIHNjaGVtYXM6IFt7IHNjaGVtYTogdGhpcy5KU09OU2NoZW1hLCBmaWxlTWF0Y2g6IFsnKiddLCB1cmk6ICd0cmFuc2xhdGlvbicgfV0sXG4gICAgICBlbmFibGVTY2hlbWFSZXF1ZXN0OiBmYWxzZSxcbiAgICAgIGFsbG93Q29tbWVudHM6IGZhbHNlXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyByZWZyZXNoKCkge1xuICAgIHRoaXMuaXNMb2FkaW5nLnNldCh0cnVlKTtcblxuICAgIGNvbnN0IHRyYW5zbGF0aW9uUHJvcGVydGllczogeyBrZXk6IHsgdHlwZTogJ3N0cmluZycgfTsgW2tleTogc3RyaW5nXTogeyB0eXBlOiAnc3RyaW5nJyB9IH0gPVxuICAgICAgdGhpcy5hdmFpbGFibGVMYW5ncy5yZWR1Y2VSaWdodChcbiAgICAgICAgKGFjYywgbGFuZykgPT4ge1xuICAgICAgICAgIGFjY1tsYW5nXSA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHRoaXMudHJhbnNsYXRpb24uaW5zdGFudChcbiAgICAgICAgICAgICAgZ2V0dGV4dCgnVHJhbnNsYXRpb24gZm9yIFwie3sgbGFuZ3VhZ2VDb2RlIH19XCIgbGFuZ3VhZ2UuJyksXG4gICAgICAgICAgICAgIHsgbGFuZ3VhZ2VDb2RlOiBsYW5nIH1cbiAgICAgICAgICAgIClcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBrZXk6IHtcbiAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHRoaXMudHJhbnNsYXRpb24uaW5zdGFudChnZXR0ZXh0KCdUaGUga2V5IHRvIGJlIHRyYW5zbGF0ZWQuJykpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIHRoaXMuSlNPTlNjaGVtYSA9IHtcbiAgICAgICRzY2hlbWE6ICdodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA0L3NjaGVtYSMnLFxuXG4gICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgaXRlbXM6IHtcbiAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgIHByb3BlcnRpZXM6IHRyYW5zbGF0aW9uUHJvcGVydGllcyxcbiAgICAgICAgcmVxdWlyZWQ6IFsna2V5J10sXG4gICAgICAgIG1pblByb3BlcnRpZXM6IDJcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgdHJhbnNsYXRpb25zID0gYXdhaXQgdGhpcy50cmFuc2xhdGlvblN0b3JlLmdldENvbWJpbmVkTGlzdE9mVHJhbnNsYXRpb25zRm9yUGVyS2V5KFxuICAgICAgdGhpcy5hdmFpbGFibGVMYW5nc1xuICAgICk7XG5cbiAgICB0aGlzLnZhbHVlU3RyaW5nLnNldChKU09OLnN0cmluZ2lmeSh0cmFuc2xhdGlvbnMsIHVuZGVmaW5lZCwgMikpO1xuXG4gICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgfVxuXG4gIGFzeW5jIGltcG9ydFRyYW5zbGF0aW9uS2V5cygpIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5hbGVydC5pbmZvKFxuICAgICAgICBnZXR0ZXh0KFxuICAgICAgICAgICdJbXBvcnRpbmcgdHJhbnNsYXRpb24gZnJvbSBhdmFpbGFibGUgV2ViIFNESyBiYXNlZCBhcHBsaWNhdGlvbnMuIFRoaXMgbWF5IHRha2UgYSB3aGlsZS4uLidcbiAgICAgICAgKVxuICAgICAgKTtcblxuICAgICAgLy8gc2luY2Ugd2UgYXJlIG9ubHkgaW50ZXJlc3RlZCBpbiB0aGUga2V5cywgd2Ugb25seSBuZWVkIHRvIHJldHJpZXZlIHRoZSB0cmFuc2xhdGlvbnMgZm9yIG9uZSAod2VsbCBzdXBwb3J0ZWQpIGxhbmd1YWdlXG4gICAgICAvLyB3ZSBhc3N1bWUgdGhhdCB0aGUga2V5cyBhcmUgdGhlIHNhbWUgZm9yIGFsbCBvdGhlciBsYW5ndWFnZXMsIG90aGVyd2lzZSB3ZSB3b3VsZCBuZWVkIHRvIHBlcmZvcm0gYSBsb3QgbW9yZSByZXF1ZXN0cy5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLnRyYW5zbGF0aW9uU3RvcmUuZ2V0QXZhaWxhYmxlVHJhbnNsYXRpb25zKFsnZGUnXSk7XG4gICAgICBjb25zdCB2YWx1ZVN0cmluZyA9IHRoaXMudmFsdWVTdHJpbmcoKTtcbiAgICAgIGNvbnN0IHZhbHVlczogQXJyYXk8eyBrZXk6IHN0cmluZyB9PiA9IEpTT04ucGFyc2UodmFsdWVTdHJpbmcpO1xuICAgICAgY29uc3QgcHJldmlvdXNOdW1iZXJPZkVudHJpZXMgPSB2YWx1ZXMubGVuZ3RoO1xuICAgICAgY29uc3QgcmV0cmlldmVkS2V5cyA9IE9iamVjdC5rZXlzKGRhdGEpO1xuICAgICAgZm9yIChjb25zdCBrZXkgb2YgcmV0cmlldmVkS2V5cykge1xuICAgICAgICBjb25zdCBmb3VuZEtleSA9IHZhbHVlcy5maW5kKHZhbHVlID0+IHZhbHVlLmtleSA9PT0ga2V5KTtcbiAgICAgICAgaWYgKCFmb3VuZEtleSkge1xuICAgICAgICAgIHZhbHVlcy5wdXNoKHsga2V5IH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBuZXdwcmV2aW91c051bWJlck9mRW50cmllcyA9IHZhbHVlcy5sZW5ndGg7XG4gICAgICB0aGlzLnZhbHVlU3RyaW5nLnNldChKU09OLnN0cmluZ2lmeSh2YWx1ZXMsIHVuZGVmaW5lZCwgMikpO1xuICAgICAgdGhpcy5hbGVydC5zdWNjZXNzKFxuICAgICAgICB0aGlzLnRyYW5zbGF0aW9uLmluc3RhbnQoXG4gICAgICAgICAgZ2V0dGV4dChcbiAgICAgICAgICAgICdSZXRyaWV2ZWQge3sgbnVtYmVyT2ZSZXRyaWV2ZWRLZXlzIH19IGtleXMgZnJvbSBhdmFpbGFibGUgYXBwbGljYXRpb25zLiB7eyBudW1iZXJPZk5ld0tleXMgfX0gbmV3IHRyYW5zbGF0aW9uIGtleXMgd2VyZSBhZGRlZC4nXG4gICAgICAgICAgKSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBudW1iZXJPZlJldHJpZXZlZEtleXM6IHJldHJpZXZlZEtleXMubGVuZ3RoLFxuICAgICAgICAgICAgbnVtYmVyT2ZOZXdLZXlzOiBuZXdwcmV2aW91c051bWJlck9mRW50cmllcyAtIHByZXZpb3VzTnVtYmVyT2ZFbnRyaWVzXG4gICAgICAgICAgfVxuICAgICAgICApXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuYWxlcnQuZGFuZ2VyKGdldHRleHQoJ0ZhaWxlZCB0byBpbXBvcnQgdHJhbnNsYXRpb24ga2V5cycpKTtcbiAgICAgIHRoaXMuYWxlcnQuYWRkU2VydmVyRmFpbHVyZShlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlVHJhbnNsYXRpb25zKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnRyYW5zbGF0aW9uU3RvcmUudXBkYXRlVHJhbnNsYXRpb25zKEpTT04ucGFyc2UodGhpcy52YWx1ZVN0cmluZygpKSk7XG4gICAgICBhd2FpdCB0aGlzLnJlZnJlc2goKTtcbiAgICAgIHRoaXMuYWxlcnQuc3VjY2VzcyhnZXR0ZXh0KCdUcmFuc2xhdGlvbnMgc2F2ZWQnKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5hbGVydC5kYW5nZXIoZ2V0dGV4dCgnRmFpbGVkIHRvIHNhdmUgdHJhbnNsYXRpb25zJykpO1xuICAgICAgdGhpcy5hbGVydC5hZGRTZXJ2ZXJGYWlsdXJlKGUpO1xuICAgIH1cbiAgfVxufVxuIiwiPGM4eS10aXRsZSB0cmFuc2xhdGU+TG9jYWxpemF0aW9uPC9jOHktdGl0bGU+XG5cbjxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNMb2FkaW5nKCk7IGVsc2UgbG9hZGluZ1wiPlxuICA8Yzh5LWFjdGlvbi1iYXItaXRlbSBwbGFjZW1lbnQ9XCJyaWdodFwiPlxuICAgIDxidXR0b25cbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1saW5rXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhaXNWYWxpZEpTT04oKVwiXG4gICAgICAoY2xpY2spPVwic2F2ZVRyYW5zbGF0aW9ucygpXCJcbiAgICAgIGRhdGEtY3k9XCJjOHktdHJhbnNsYXRpb24tZWRpdG9yLS1zYXZlLWFuZC1hcHBseVwiXG4gICAgPlxuICAgICAgPGkgYzh5SWNvbj1cInNhdmVcIj48L2k+XG4gICAgICA8c3BhbiB0cmFuc2xhdGU+U2F2ZSAmIGFwcGx5PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICA8L2M4eS1hY3Rpb24tYmFyLWl0ZW0+XG5cbiAgPGM4eS1hY3Rpb24tYmFyLWl0ZW0gcGxhY2VtZW50PVwicmlnaHRcIj5cbiAgICA8YnV0dG9uXG4gICAgICBjbGFzcz1cImJ0biBidG4tbGlua1wiXG4gICAgICBbZGlzYWJsZWRdPVwiIWlzVmFsaWRKU09OKClcIlxuICAgICAgKGNsaWNrKT1cImltcG9ydFRyYW5zbGF0aW9uS2V5cygpXCJcbiAgICAgIGRhdGEtY3k9XCJjOHktdHJhbnNsYXRpb24tZWRpdG9yLS1pbXBvcnQtdHJhbnNsYXRpb24ta2V5c1wiXG4gICAgPlxuICAgICAgPGkgW2M4eUljb25dPVwiJ2ltcG9ydCdcIj48L2k+XG4gICAgICA8c3BhbiB0cmFuc2xhdGU+SW1wb3J0IHRyYW5zbGF0aW9uIGtleXMgZnJvbSBBcHBzPC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICA8L2M4eS1hY3Rpb24tYmFyLWl0ZW0+XG5cbiAgPGRpdiBjbGFzcz1cImNhcmQgY2FyZC0tZnVsbHBhZ2UgY29udGVudC1mdWxscGFnZVwiPlxuICAgIDxjOHktZWRpdG9yXG4gICAgICBjbGFzcz1cImZsZXgtZ3Jvd1wiXG4gICAgICBbZWRpdG9yT3B0aW9uc109XCJlZGl0b3JPcHRpb25zXCJcbiAgICAgIFtuZ01vZGVsXT1cInZhbHVlU3RyaW5nKClcIlxuICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25WYWx1ZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgIChlZGl0b3JJbml0KT1cIm9uRWRpdG9ySW5pdCgkZXZlbnQpXCJcbiAgICAgIG1vbmFjb0VkaXRvck1hcmtlclZhbGlkYXRvclxuICAgID48L2M4eS1lZGl0b3I+XG4gIDwvZGl2PlxuPC9uZy1jb250YWluZXI+XG5cbjxuZy10ZW1wbGF0ZSAjbG9hZGluZz5cbiAgPGM4eS1sb2FkaW5nPjwvYzh5LWxvYWRpbmc+XG48L25nLXRlbXBsYXRlPiJdfQ==