UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

273 lines 37.9 kB
import { Directive, ElementRef, Input, KeyValueDiffers } from '@angular/core'; import * as i0 from "@angular/core"; /** * SME directive to wrap around telemetry tags for convenience and control. JSLL and 1DS use these to add information to telemetry events. */ export class TelemetryDirective { /** * Initialize differ for data blob so it constantly updates based on object. * Also, check if smeTelemetry specified. If so, search for anything with smeTelemetry prefix and add data-bi telemetry * tags. This allows for any singular addition of a data-bi- tag, as opposed to dataBlob which uses an object to retrieve fields. * Due to Angular limitations we cannot bind to any custom SmeTelemetry____ directive, limiting it to mainly use for * static data-bi- labels. Custom directives, if not part of data blob, should primarily stem from the data-bi- * dictionary for adding target fields in telemetry. * See https://martech.azurewebsites.net/website-tools/jsll/references/data-bi-event-dictionary/ * @param elementRef Element with the directive * @param kvDiffers KeyValue differs for dataBlob */ constructor(elementRef, kvDiffers) { this.elementRef = elementRef; this.kvDiffers = kvDiffers; /** * Internal variable holders */ this.internalId = ''; this.internalAreaName = ''; this.internalSlotNumber = ''; this.internalContentName = ''; this.internalContentSource = ''; this.internalTemplateName = ''; this.internalProductId = ''; this.internalContentType = ''; this.internalDisableAutomaticTracking = false; this.internalDisableElementTracking = false; this.internalDataBlob = {}; this.dataBlobDiffer = this.kvDiffers.find(this.internalDataBlob).create(); } /** * The source name to use for logging */ get logSourceName() { return 'SmeTelemetryDataBlobDirective'; } /** * Adds data-bi-id */ set telemetryId(value) { this.internalId = value; this.elementRef.nativeElement.setAttribute(TelemetryDirective.idLabel, this.internalId); } get telemetryId() { return this.internalId; } /** * Adds data-bi-area */ set areaName(value) { this.internalAreaName = value; this.elementRef.nativeElement.setAttribute(TelemetryDirective.areaNameLabel, this.internalAreaName); } get areaName() { return this.internalAreaName; } /** * Adds data-bi-slot */ set slotNumber(value) { this.internalSlotNumber = value; this.elementRef.nativeElement.setAttribute(TelemetryDirective.slotNumberLabel, this.internalSlotNumber); } get slotNumber() { return this.internalSlotNumber; } /** * Adds data-bi-name */ set contentName(value) { this.internalContentName = value; this.elementRef.nativeElement.setAttribute(TelemetryDirective.contentNameLabel, this.internalContentName); } get contentName() { return this.internalContentName; } /** * Adds data-bi-source */ set contentSource(value) { this.internalContentSource = value; this.elementRef.nativeElement.setAttribute(TelemetryDirective.contentSourceLabel, this.internalContentSource); } get contentSource() { return this.internalContentSource; } /** * Adds data-bi-type */ set contentType(value) { this.internalContentType = value; this.elementRef.nativeElement.setAttribute(TelemetryDirective.contentTypeLabel, this.internalContentType); } get contentType() { return this.internalContentType; } /** * Adds data-bi-view */ set templateName(value) { this.internalTemplateName = value; this.elementRef.nativeElement.setAttribute(TelemetryDirective.templateNameLabel, this.internalTemplateName); } get templateName() { return this.internalTemplateName; } /** * Adds data-bi-product */ set productId(value) { this.internalProductId = value; this.elementRef.nativeElement.setAttribute(TelemetryDirective.productIdLabel, this.internalProductId); } get productId() { return this.internalProductId; } /** * Adds each field in JSON object to element. Allows for custom element typings. Data-m has a similar behavior, but splitting up * the individual fields works together with lineage component, whereas specifying data-m blocks the lineage handling (ie cannot pull * tags from higher or lower in the DOM tree) * This uses the ngDoCheck to change DOM mainly, this setter is used for the initial object set. */ set dataBlob(value) { this.internalDataBlob = value; for (const [key, val] of Object.entries(this.internalDataBlob)) { if (val === '') { // Skip if value is empty, attribute will not be added initially. delete this.internalDataBlob[key]; continue; } const label = `data-bi-${key}`; // use NS function to hold case in attribute name this.elementRef.nativeElement.setAttributeNS(null, label, val); } } get dataBlob() { return this.internalDataBlob; } /** * Adds data-bi-mto * Removes the element from being subject to default automatic tracking. */ set disableAutomaticTracking(value) { this.internalDisableAutomaticTracking = value; // empty quotes will add attribute with no value, null will remove if (this.internalDisableAutomaticTracking) { this.elementRef.nativeElement.setAttribute(TelemetryDirective.disableAutomaticTrackingLabel, ''); } else { this.elementRef.nativeElement.removeAttribute(TelemetryDirective.disableAutomaticTrackingLabel); } } get disableAutomaticTracking() { return this.internalDisableAutomaticTracking; } /** * Adds data-bi-dnt * Removes element from all telemetry events. */ set disableElementTracking(value) { this.internalDisableElementTracking = value; // empty quotes will add attribute with no value, null will remove if (this.internalDisableElementTracking) { this.elementRef.nativeElement.setAttribute(TelemetryDirective.disableElementTrackingLabel, ''); } else { this.elementRef.nativeElement.removeAttribute(TelemetryDirective.disableElementTrackingLabel); } } get disableElementTracking() { return this.internalDisableElementTracking; } ngOnInit() { if (this.elementRef.nativeElement.hasAttribute(TelemetryDirective.directivePrefix)) { const attributes = this.elementRef.nativeElement.getAttributeNames().filter((name) => { const suffix = name.substring(TelemetryDirective.directivePrefix.length); return name.startsWith(TelemetryDirective.directivePrefix.toLowerCase()) && suffix && !(TelemetryDirective.labeledDirectives.includes(suffix)); }).map((attr) => attr.substring(TelemetryDirective.directivePrefix.length)); for (const attributeName of attributes) { const attributeValue = this.elementRef.nativeElement.getAttribute(`${TelemetryDirective.directivePrefix}${attributeName}`); const label = `data-bi-${attributeName}`; this.elementRef.nativeElement.setAttribute(label, attributeValue); } } } /** * Handle changes to data blob object, needed b/c data object will update without triggering setter. * Selectively update DOM fields based on individual changes. */ ngDoCheck() { if (this.dataBlobDiffer) { const changes = this.dataBlobDiffer.diff(this.internalDataBlob); if (changes) { changes.forEachItem((item) => { if (item.currentValue === item.previousValue) { return; } const label = `data-bi-${item.key}`; if (!item.currentValue) { this.elementRef.nativeElement.removeAttributeNS(null, label); delete this.internalDataBlob[item.key]; } else { this.elementRef.nativeElement.setAttributeNS(null, label, item.currentValue); } }); } } } } /** * JSLL/1DS main tag labels - all tags are supported (data-bi-*) but these are the main labels and are * specifically checked for in various cases. */ TelemetryDirective.idLabel = 'data-bi-id'; TelemetryDirective.areaNameLabel = 'data-bi-area'; TelemetryDirective.slotNumberLabel = 'data-bi-slot'; TelemetryDirective.contentNameLabel = 'data-bi-name'; TelemetryDirective.contentSourceLabel = 'data-bi-source'; TelemetryDirective.templateNameLabel = 'data-bi-view'; TelemetryDirective.productIdLabel = 'data-bi-product'; TelemetryDirective.contentTypeLabel = 'data-bi-type'; TelemetryDirective.disableAutomaticTrackingLabel = 'data-bi-mto'; TelemetryDirective.disableElementTrackingLabel = 'data-bi-dnt'; // Sme telemetry prefix - takes place of data-bi- in WAC telemetry tagging TelemetryDirective.directivePrefix = 'smeTelemetry'; // List of all the selectors, without the smeTelemetry prefix. Lower case b/c attributes are forced into lowercase by default. TelemetryDirective.labeledDirectives = [ 'id', 'area', 'slot', 'contentname', 'contentsource', 'contenttype', 'template', 'product', 'datablob', 'disableauto', 'disableelement' ]; /** @nocollapse */ TelemetryDirective.ɵfac = function TelemetryDirective_Factory(t) { return new (t || TelemetryDirective)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.KeyValueDiffers)); }; /** @nocollapse */ TelemetryDirective.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: TelemetryDirective, selectors: [["", "smeTelemetry", ""], ["", "smeTelemetryId", ""], ["", "smeTelemetryArea", ""], ["", "smeTelemetrySlot", ""], ["", "smeTelemetryContentName", ""], ["", "smeTelemetryContentSource", ""], ["", "smeTelemetryContentType", ""], ["", "smeTelemetryTemplate", ""], ["", "smeTelemetryProduct", ""], ["", "smeTelemetryDataBlob", ""], ["", "smeTelemetryDisableAuto", ""], ["", "smeTelemetryDisableElement", ""]], inputs: { smeTelemetry: "smeTelemetry", telemetryId: ["smeTelemetryId", "telemetryId"], areaName: ["smeTelemetryArea", "areaName"], slotNumber: ["smeTelemetrySlot", "slotNumber"], contentName: ["smeTelemetryContentName", "contentName"], contentSource: ["smeTelemetryContentSource", "contentSource"], contentType: ["smeTelemetryContentType", "contentType"], templateName: ["smeTelemetryTemplate", "templateName"], productId: ["smeTelemetryProduct", "productId"], dataBlob: ["smeTelemetryDataBlob", "dataBlob"], disableAutomaticTracking: ["smeTelemetryDisableAuto", "disableAutomaticTracking"], disableElementTracking: ["smeTelemetryDisableElement", "disableElementTracking"] } }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TelemetryDirective, [{ type: Directive, args: [{ selector: `[smeTelemetry], [smeTelemetryId], [smeTelemetryArea], [smeTelemetrySlot], [smeTelemetryContentName], [smeTelemetryContentSource], [smeTelemetryContentType], [smeTelemetryTemplate], [smeTelemetryProduct], [smeTelemetryDataBlob], [smeTelemetryDisableAuto], [smeTelemetryDisableElement]` }] }], function () { return [{ type: i0.ElementRef }, { type: i0.KeyValueDiffers }]; }, { smeTelemetry: [{ type: Input }], telemetryId: [{ type: Input, args: ['smeTelemetryId'] }], areaName: [{ type: Input, args: ['smeTelemetryArea'] }], slotNumber: [{ type: Input, args: ['smeTelemetrySlot'] }], contentName: [{ type: Input, args: ['smeTelemetryContentName'] }], contentSource: [{ type: Input, args: ['smeTelemetryContentSource'] }], contentType: [{ type: Input, args: ['smeTelemetryContentType'] }], templateName: [{ type: Input, args: ['smeTelemetryTemplate'] }], productId: [{ type: Input, args: ['smeTelemetryProduct'] }], dataBlob: [{ type: Input, args: ['smeTelemetryDataBlob'] }], disableAutomaticTracking: [{ type: Input, args: ['smeTelemetryDisableAuto'] }], disableElementTracking: [{ type: Input, args: ['smeTelemetryDisableElement'] }] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVsZW1ldHJ5LmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2FuZ3VsYXIvc3JjL2RpcmVjdGl2ZXMvdGVsZW1ldHJ5L3RlbGVtZXRyeS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVyxVQUFVLEVBQUUsS0FBSyxFQUFrQixlQUFlLEVBQVUsTUFBTSxlQUFlLENBQUM7O0FBRS9HOztHQUVHO0FBTUgsTUFBTSxPQUFPLGtCQUFrQjtJQXVMM0I7Ozs7Ozs7Ozs7T0FVRztJQUNILFlBQW9CLFVBQXNCLEVBQVUsU0FBMEI7UUFBMUQsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUFVLGNBQVMsR0FBVCxTQUFTLENBQWlCO1FBTTlFOztXQUVHO1FBQ0ssZUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNoQixxQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDdEIsdUJBQWtCLEdBQUcsRUFBRSxDQUFDO1FBQ3hCLHdCQUFtQixHQUFHLEVBQUUsQ0FBQztRQUN6QiwwQkFBcUIsR0FBRyxFQUFFLENBQUM7UUFDM0IseUJBQW9CLEdBQUcsRUFBRSxDQUFDO1FBQzFCLHNCQUFpQixHQUFHLEVBQUUsQ0FBQztRQUN2Qix3QkFBbUIsR0FBRyxFQUFFLENBQUM7UUFDekIscUNBQWdDLEdBQUcsS0FBSyxDQUFDO1FBQ3pDLG1DQUE4QixHQUFHLEtBQUssQ0FBQztRQUN2QyxxQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFsQjFCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDOUUsQ0FBQztJQWxLRDs7T0FFRztJQUNILElBQWMsYUFBYTtRQUN2QixPQUFPLCtCQUErQixDQUFDO0lBQzNDLENBQUM7SUFRRDs7T0FFRztJQUNILElBQ1csV0FBVyxD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c0JBQXNCO1lBV2xCLFNBQVM7a0JBRG5CLEtBQUs7bUJBQUMscUJBQXFCO1lBY2pCLFFBQVE7a0JBRGxCLEtBQUs7bUJBQUMsc0JBQXNCO1lBdUJsQix3QkFBd0I7a0JBRGxDLEtBQUs7bUJBQUMseUJBQXlCO1lBaUJyQixzQkFBc0I7a0JBRGhDLEtBQUs7bUJBQUMsNEJBQTRCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBEb0NoZWNrLCBFbGVtZW50UmVmLCBJbnB1dCwgS2V5VmFsdWVEaWZmZXIsIEtleVZhbHVlRGlmZmVycywgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG4vKipcclxuICogU01FIGRpcmVjdGl2ZSB0byB3cmFwIGFyb3VuZCB0ZWxlbWV0cnkgdGFncyBmb3IgY29udmVuaWVuY2UgYW5kIGNvbnRyb2wuIEpTTEwgYW5kIDFEUyB1c2UgdGhlc2UgdG8gYWRkIGluZm9ybWF0aW9uIHRvIHRlbGVtZXRyeSBldmVudHMuXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHtcclxuICAgIHNlbGVjdG9yOiBgW3NtZVRlbGVtZXRyeV0sIFtzbWVUZWxlbWV0cnlJZF0sIFtzbWVUZWxlbWV0cnlBcmVhXSwgW3NtZVRlbGVtZXRyeVNsb3RdLCBbc21lVGVsZW1ldHJ5Q29udGVudE5hbWVdLFxyXG4gICAgW3NtZVRlbGVtZXRyeUNvbnRlbnRTb3VyY2VdLCBbc21lVGVsZW1ldHJ5Q29udGVudFR5cGVdLCBbc21lVGVsZW1ldHJ5VGVtcGxhdGVdLCBbc21lVGVsZW1ldHJ5UHJvZHVjdF0sXHJcbiAgICBbc21lVGVsZW1ldHJ5RGF0YUJsb2JdLCBbc21lVGVsZW1ldHJ5RGlzYWJsZUF1dG9dLCBbc21lVGVsZW1ldHJ5RGlzYWJsZUVsZW1lbnRdYFxyXG59KVxyXG5leHBvcnQgY2xhc3MgVGVsZW1ldHJ5RGlyZWN0aXZlIGltcGxlbWVudHMgRG9DaGVjaywgT25Jbml0IHtcclxuICAgLyoqXHJcbiAgICAgKiBKU0xMLzFEUyBtYWluIHRhZyBsYWJlbHMgLSBhbGwgdGFncyBhcmUgc3VwcG9ydGVkIChkYXRhLWJpLSopIGJ1dCB0aGVzZSBhcmUgdGhlIG1haW4gbGFiZWxzIGFuZCBhcmVcclxuICAgICAqIHNwZWNpZmljYWxseSBjaGVja2VkIGZvciBpbiB2YXJpb3VzIGNhc2VzLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBpZExhYmVsID0gJ2RhdGEtYmktaWQnO1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgYXJlYU5hbWVMYWJlbCA9ICdkYXRhLWJpLWFyZWEnO1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgc2xvdE51bWJlckxhYmVsID0gJ2RhdGEtYmktc2xvdCc7XHJcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBjb250ZW50TmFtZUxhYmVsID0gJ2RhdGEtYmktbmFtZSc7XHJcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBjb250ZW50U291cmNlTGFiZWwgPSAnZGF0YS1iaS1zb3VyY2UnO1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgdGVtcGxhdGVOYW1lTGFiZWwgPSAnZGF0YS1iaS12aWV3JztcclxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IHByb2R1Y3RJZExhYmVsID0gJ2RhdGEtYmktcHJvZHVjdCc7XHJcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBjb250ZW50VHlwZUxhYmVsID0gJ2RhdGEtYmktdHlwZSc7XHJcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBkaXNhYmxlQXV0b21hdGljVHJhY2tpbmdMYWJlbCA9ICdkYXRhLWJpLW10byc7XHJcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBkaXNhYmxlRWxlbWVudFRyYWNraW5nTGFiZWwgPSAnZGF0YS1iaS1kbnQnO1xyXG5cclxuICAgIC8vIFNtZSB0ZWxlbWV0cnkgcHJlZml4IC0gdGFrZXMgcGxhY2Ugb2YgZGF0YS1iaS0gaW4gV0FDIHRlbGVtZXRyeSB0YWdnaW5nXHJcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBkaXJlY3RpdmVQcmVmaXggPSAnc21lVGVsZW1ldHJ5JztcclxuXHJcbiAgICAvLyBMaXN0IG9mIGFsbCB0aGUgc2VsZWN0b3JzLCB3aXRob3V0IHRoZSBzbWVUZWxlbWV0cnkgcHJlZml4LiBMb3dlciBjYXNlIGIvYyBhdHRyaWJ1dGVzIGFyZSBmb3JjZWQgaW50byBsb3dlcmNhc2UgYnkgZGVmYXVsdC5cclxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IGxhYmVsZWREaXJlY3RpdmVzID0gW1xyXG4gICAgICAgICdpZCcsXHJcbiAgICAgICAgJ2FyZWEnLFxyXG4gICAgICAgICdzbG90JyxcclxuICAgICAgICAnY29udGVudG5hbWUnLFxyXG4gICAgICAgICdjb250ZW50c291cmNlJyxcclxuICAgICAgICAnY29udGVudHR5cGUnLFxyXG4gICAgICAgICd0ZW1wbGF0ZScsXHJcbiAgICAgICAgJ3Byb2R1Y3QnLFxyXG4gICAgICAgICdkYXRhYmxvYicsXHJcbiAgICAgICAgJ2Rpc2FibGVhdXRvJyxcclxuICAgICAgICAnZGlzYWJsZWVsZW1lbnQnXHJcbiAgICBdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHNvdXJjZSBuYW1lIHRvIHVzZSBmb3IgbG9nZ2luZ1xyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgZ2V0IGxvZ1NvdXJjZU5hbWUoKSB7XHJcbiAgICAgICAgcmV0dXJuICdTbWVUZWxlbWV0cnlEYXRhQmxvYkRpcmVjdGl2ZSc7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb250ZW50IHRvIHNwZWNpZnkgY3VzdG9tIGRpcmVjdGl2ZXMgb25cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBzbWVUZWxlbWV0cnk6IGFueTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgZGF0YS1iaS1pZFxyXG4gICAgICovXHJcbiAgICBASW5wdXQoJ3NtZVRlbGVtZXRyeUlkJylcclxuICAgIHB1YmxpYyBzZXQgdGVsZW1ldHJ5SWQodmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxJZCA9IHZhbHVlO1xyXG4gICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZShUZWxlbWV0cnlEaXJlY3RpdmUuaWRMYWJlbCwgdGhpcy5pbnRlcm5hbElkKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBnZXQgdGVsZW1ldHJ5SWQoKTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuaW50ZXJuYWxJZDsgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBkYXRhLWJpLWFyZWFcclxuICAgICAqL1xyXG4gICAgQElucHV0KCdzbWVUZWxlbWV0cnlBcmVhJylcclxuICAgIHB1YmxpYyBzZXQgYXJlYU5hbWUodmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxBcmVhTmFtZSA9IHZhbHVlO1xyXG4gICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZShUZWxlbWV0cnlEaXJlY3RpdmUuYXJlYU5hbWVMYWJlbCwgdGhpcy5pbnRlcm5hbEFyZWFOYW1lKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBnZXQgYXJlYU5hbWUoKTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuaW50ZXJuYWxBcmVhTmFtZTsgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBkYXRhLWJpLXNsb3RcclxuICAgICAqL1xyXG4gICAgQElucHV0KCdzbWVUZWxlbWV0cnlTbG90JylcclxuICAgIHB1YmxpYyBzZXQgc2xvdE51bWJlcih2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5pbnRlcm5hbFNsb3ROdW1iZXIgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoVGVsZW1ldHJ5RGlyZWN0aXZlLnNsb3ROdW1iZXJMYWJlbCwgdGhpcy5pbnRlcm5hbFNsb3ROdW1iZXIpO1xyXG4gICAgfVxyXG4gICAgcHVibGljIGdldCBzbG90TnVtYmVyKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLmludGVybmFsU2xvdE51bWJlcjsgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBkYXRhLWJpLW5hbWVcclxuICAgICAqL1xyXG4gICAgQElucHV0KCdzbWVUZWxlbWV0cnlDb250ZW50TmFtZScpXHJcbiAgICBwdWJsaWMgc2V0IGNvbnRlbnROYW1lKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLmludGVybmFsQ29udGVudE5hbWUgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoVGVsZW1ldHJ5RGlyZWN0aXZlLmNvbnRlbnROYW1lTGFiZWwsIHRoaXMuaW50ZXJuYWxDb250ZW50TmFtZSk7XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgZ2V0IGNvbnRlbnROYW1lKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLmludGVybmFsQ29udGVudE5hbWU7IH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgZGF0YS1iaS1zb3VyY2VcclxuICAgICAqL1xyXG4gICAgQElucHV0KCdzbWVUZWxlbWV0cnlDb250ZW50U291cmNlJylcclxuICAgIHB1YmxpYyBzZXQgY29udGVudFNvdXJjZSh2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5pbnRlcm5hbENvbnRlbnRTb3VyY2UgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoVGVsZW1ldHJ5RGlyZWN0aXZlLmNvbnRlbnRTb3VyY2VMYWJlbCwgdGhpcy5pbnRlcm5hbENvbnRlbnRTb3VyY2UpO1xyXG4gICAgfVxyXG4gICAgcHVibGljIGdldCBjb250ZW50U291cmNlKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLmludGVybmFsQ29udGVudFNvdXJjZTsgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBkYXRhLWJpLXR5cGVcclxuICAgICAqL1xyXG4gICAgQElucHV0KCdzbWVUZWxlbWV0cnlDb250ZW50VHlwZScpXHJcbiAgICBwdWJsaWMgc2V0IGNvbnRlbnRUeXBlKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLmludGVybmFsQ29udGVudFR5cGUgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoVGVsZW1ldHJ5RGlyZWN0aXZlLmNvbnRlbnRUeXBlTGFiZWwsIHRoaXMuaW50ZXJuYWxDb250ZW50VHlwZSk7XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgZ2V0IGNvbnRlbnRUeXBlKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLmludGVybmFsQ29udGVudFR5cGU7IH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgZGF0YS1iaS12aWV3XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgnc21lVGVsZW1ldHJ5VGVtcGxhdGUnKVxyXG4gICAgcHVibGljIHNldCB0ZW1wbGF0ZU5hbWUodmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxUZW1wbGF0ZU5hbWUgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoVGVsZW1ldHJ5RGlyZWN0aXZlLnRlbXBsYXRlTmFtZUxhYmVsLCB0aGlzLmludGVybmFsVGVtcGxhdGVOYW1lKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBnZXQgdGVtcGxhdGVOYW1lKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLmludGVybmFsVGVtcGxhdGVOYW1lOyB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIGRhdGEtYmktcHJvZHVjdFxyXG4gICAgICovXHJcbiAgICBASW5wdXQoJ3NtZVRlbGVtZXRyeVByb2R1Y3QnKVxyXG4gICAgcHVibGljIHNldCBwcm9kdWN0SWQodmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxQcm9kdWN0SWQgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoVGVsZW1ldHJ5RGlyZWN0aXZlLnByb2R1Y3RJZExhYmVsLCB0aGlzLmludGVybmFsUHJvZHVjdElkKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBnZXQgcHJvZHVjdElkKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLmludGVybmFsUHJvZHVjdElkOyB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIGVhY2ggZmllbGQgaW4gSlNPTiBvYmplY3QgdG8gZWxlbWVudC4gQWxsb3dzIGZvciBjdXN0b20gZWxlbWVudCB0eXBpbmdzLiBEYXRhLW0gaGFzIGEgc2ltaWxhciBiZWhhdmlvciwgYnV0IHNwbGl0dGluZyB1cFxyXG4gICAgICogdGhlIGluZGl2aWR1YWwgZmllbGRzIHdvcmtzIHRvZ2V0aGVyIHdpdGggbGluZWFnZSBjb21wb25lbnQsIHdoZXJlYXMgc3BlY2lmeWluZyBkYXRhLW0gYmxvY2tzIHRoZSBsaW5lYWdlIGhhbmRsaW5nIChpZSBjYW5ub3QgcHVsbFxyXG4gICAgICogdGFncyBmcm9tIGhpZ2hlciBvciBsb3dlciBpbiB0aGUgRE9NIHRyZWUpXHJcbiAgICAgKiBUaGlzIHVzZXMgdGhlIG5nRG9DaGVjayB0byBjaGFuZ2UgRE9NIG1haW5seSwgdGhpcyBzZXR0ZXIgaXMgdXNlZCBmb3IgdGhlIGluaXRpYWwgb2JqZWN0IHNldC5cclxuICAgICAqL1xyXG4gICAgQElucHV0KCdzbWVUZWxlbWV0cnlEYXRhQmxvYicpXHJcbiAgICBwdWJsaWMgc2V0IGRhdGFCbG9iKHZhbHVlOiBhbnkpIHtcclxuICAgICAgICB0aGlzLmludGVybmFsRGF0YUJsb2IgPSB2YWx1ZTtcclxuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbF0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5pbnRlcm5hbERhdGFCbG9iKSkge1xyXG4gICAgICAgICAgICBpZiAodmFsID09PSAnJykge1xyXG4gICAgICAgICAgICAgICAgLy8gU2tpcCBpZiB2YWx1ZSBpcyBlbXB0eSwgYXR0cmlidXRlIHdpbGwgbm90IGJlIGFkZGVkIGluaXRpYWxseS5cclxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmludGVybmFsRGF0YUJsb2Jba2V5XTtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGxhYmVsID0gYGRhdGEtYmktJHtrZXl9YDtcclxuICAgICAgICAgICAgLy8gdXNlIE5TIGZ1bmN0aW9uIHRvIGhvbGQgY2FzZSBpbiBhdHRyaWJ1dGUgbmFtZVxyXG4gICAgICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBsYWJlbCwgdmFsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgZ2V0IGRhdGFCbG9iKCk6IGFueSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxEYXRhQmxvYjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgZGF0YS1iaS1tdG9cclxuICAgICAqIFJlbW92ZXMgdGhlIGVsZW1lbnQgZnJvbSBiZWluZyBzdWJqZWN0IHRvIGRlZmF1bHQgYXV0b21hdGljIHRyYWNraW5nLlxyXG4gICAgICovXHJcbiAgICBASW5wdXQoJ3NtZVRlbGVtZXRyeURpc2FibGVBdXRvJylcclxuICAgIHB1YmxpYyBzZXQgZGlzYWJsZUF1dG9tYXRpY1RyYWNraW5nKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5pbnRlcm5hbERpc2FibGVBdXRvbWF0aWNUcmFja2luZyA9IHZhbHVlO1xyXG4gICAgICAgIC8vIGVtcHR5IHF1b3RlcyB3aWxsIGFkZCBhdHRyaWJ1dGUgd2l0aCBubyB2YWx1ZSwgbnVsbCB3aWxsIHJlbW92ZVxyXG4gICAgICAgIGlmICh0aGlzLmludGVybmFsRGlzYWJsZUF1dG9tYXRpY1RyYWNraW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZShUZWxlbWV0cnlEaXJlY3RpdmUuZGlzYWJsZUF1dG9tYXRpY1RyYWNraW5nTGFiZWwsICcnKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoVGVsZW1ldHJ5RGlyZWN0aXZlLmRpc2FibGVBdXRvbWF0aWNUcmFja2luZ0xhYmVsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgZ2V0IGRpc2FibGVBdXRvbWF0aWNUcmFja2luZygpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuaW50ZXJuYWxEaXNhYmxlQXV0b21hdGljVHJhY2tpbmc7IH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgZGF0YS1iaS1kbnRcclxuICAgICAqIFJlbW92ZXMgZWxlbWVudCBmcm9tIGFsbCB0ZWxlbWV0cnkgZXZlbnRzLlxyXG4gICAgICovXHJcbiAgICBASW5wdXQoJ3NtZVRlbGVtZXRyeURpc2FibGVFbGVtZW50JylcclxuICAgIHB1YmxpYyBzZXQgZGlzYWJsZUVsZW1lbnRUcmFja2luZyh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxEaXNhYmxlRWxlbWVudFRyYWNraW5nID0gdmFsdWU7XHJcbiAgICAgICAgLy8gZW1wdHkgcXVvdGVzIHdpbGwgYWRkIGF0dHJpYnV0ZSB3aXRoIG5vIHZhbHVlLCBudWxsIHdpbGwgcmVtb3ZlXHJcbiAgICAgICAgaWYgKHRoaXMuaW50ZXJuYWxEaXNhYmxlRWxlbWVudFRyYWNraW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZShUZWxlbWV0cnlEaXJlY3RpdmUuZGlzYWJsZUVsZW1lbnRUcmFja2luZ0xhYmVsLCAnJyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKFRlbGVtZXRyeURpcmVjdGl2ZS5kaXNhYmxlRWxlbWVudFRyYWNraW5nTGFiZWwpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHB1YmxpYyBnZXQgZGlzYWJsZUVsZW1lbnRUcmFja2luZygpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuaW50ZXJuYWxEaXNhYmxlRWxlbWVudFRyYWNraW5nOyB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplIGRpZmZlciBmb3IgZGF0YSBibG9iIHNvIGl0IGNvbnN0YW50bHkgdXBkYXRlcyBiYXNlZCBvbiBvYmplY3QuXHJcbiAgICAgKiBBbHNvLCBjaGVjayBpZiBzbWVUZWxlbWV0cnkgc3BlY2lmaWVkLiBJZiBzbywgc2VhcmNoIGZvciBhbnl0aGluZyB3aXRoIHNtZVRlbGVtZXRyeSBwcmVmaXggYW5kIGFkZCBkYXRhLWJpIHRlbGVtZXRyeVxyXG4gICAgICogdGFncy4gVGhpcyBhbGxvd3MgZm9yIGFueSBzaW5ndWxhciBhZGRpdGlvbiBvZiBhIGRhdGEtYmktIHRhZywgYXMgb3Bwb3NlZCB0byBkYXRhQmxvYiB3aGljaCB1c2VzIGFuIG9iamVjdCB0byByZXRyaWV2ZSBmaWVsZHMuXHJcbiAgICAgKiBEdWUgdG8gQW5ndWxhciBsaW1pdGF0aW9ucyB3ZSBjYW5ub3QgYmluZCB0byBhbnkgY3VzdG9tIFNtZVRlbGVtZXRyeV9fX18gZGlyZWN0aXZlLCBsaW1pdGluZyBpdCB0byBtYWlubHkgdXNlIGZvclxyXG4gICAgICogc3RhdGljIGRhdGEtYmktIGxhYmVscy4gQ3VzdG9tIGRpcmVjdGl2ZXMsIGlmIG5vdCBwYXJ0IG9mIGRhdGEgYmxvYiwgc2hvdWxkIHByaW1hcmlseSBzdGVtIGZyb20gdGhlIGRhdGEtYmktXHJcbiAgICAgKiBkaWN0aW9uYXJ5IGZvciBhZGRpbmcgdGFyZ2V0IGZpZWxkcyBpbiB0ZWxlbWV0cnkuXHJcbiAgICAgKiBTZWUgaHR0cHM6Ly9tYXJ0ZWNoLmF6dXJld2Vic2l0ZXMubmV0L3dlYnNpdGUtdG9vbHMvanNsbC9yZWZlcmVuY2VzL2RhdGEtYmktZXZlbnQtZGljdGlvbmFyeS9cclxuICAgICAqIEBwYXJhbSBlbGVtZW50UmVmICAgIEVsZW1lbnQgd2l0aCB0aGUgZGlyZWN0aXZlXHJcbiAgICAgKiBAcGFyYW0ga3ZEaWZmZXJzICAgICBLZXlWYWx1ZSBkaWZmZXJzIGZvciBkYXRhQmxvYlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsIHByaXZhdGUga3ZEaWZmZXJzOiBLZXlWYWx1ZURpZmZlcnMpIHtcclxuICAgICAgICB0aGlzLmRhdGFCbG9iRGlmZmVyID0gdGhpcy5rdkRpZmZlcnMuZmluZCh0aGlzLmludGVybmFsRGF0YUJsb2IpLmNyZWF0ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZGF0YUJsb2JEaWZmZXI6IEtleVZhbHVlRGlmZmVyPHN0cmluZywgc3RyaW5nPjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEludGVybmFsIHZhcmlhYmxlIGhvbGRlcnNcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpbnRlcm5hbElkID0gJyc7XHJcbiAgICBwcml2YXRlIGludGVybmFsQXJlYU5hbWUgPSAnJztcclxuICAgIHByaXZhdGUgaW50ZXJuYWxTbG90TnVtYmVyID0gJyc7XHJcbiAgICBwcml2YXRlIGludGVybmFsQ29udGVudE5hbWUgPSAnJztcclxuICAgIHByaXZhdGUgaW50ZXJuYWxDb250ZW50U291cmNlID0gJyc7XHJcbiAgICBwcml2YXRlIGludGVybmFsVGVtcGxhdGVOYW1lID0gJyc7XHJcbiAgICBwcml2YXRlIGludGVybmFsUHJvZHVjdElkID0gJyc7XHJcbiAgICBwcml2YXRlIGludGVybmFsQ29udGVudFR5cGUgPSAnJztcclxuICAgIHByaXZhdGUgaW50ZXJuYWxEaXNhYmxlQXV0b21hdGljVHJhY2tpbmcgPSBmYWxzZTtcclxuICAgIHByaXZhdGUgaW50ZXJuYWxEaXNhYmxlRWxlbWVudFRyYWNraW5nID0gZmFsc2U7XHJcbiAgICBwcml2YXRlIGludGVybmFsRGF0YUJsb2IgPSB7fTtcclxuXHJcbiAgICBwdWJsaWMgbmdPbkluaXQoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50Lmhhc0F0dHJpYnV0ZShUZWxlbWV0cnlEaXJlY3RpdmUuZGlyZWN0aXZlUHJlZml4KSkge1xyXG4gICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGVzID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0QXR0cmlidXRlTmFtZXMoKS5maWx0ZXIoKG5hbWU6IHN0cmluZykgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdWZmaXggPSBuYW1lLnN1YnN0cmluZyhUZWxlbWV0cnlEaXJlY3RpdmUuZGlyZWN0aXZlUHJlZml4Lmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuYW1lLnN0YXJ0c1dpdGgoVGVsZW1ldHJ5RGlyZWN0aXZlLmRpcmVjdGl2ZVByZWZpeC50b0xvd2VyQ2FzZSgpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgc3VmZml4ICYmICEoVGVsZW1ldHJ5RGlyZWN0aXZlLmxhYmVsZWREaXJlY3RpdmVzLmluY2x1ZGVzKHN1ZmZpeCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pLm1hcCgoYXR0cjogc3RyaW5nKSA9PiBhdHRyLnN1YnN0cmluZyhUZWxlbWV0cnlEaXJlY3RpdmUuZGlyZWN0aXZlUHJlZml4Lmxlbmd0aCkpO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZU5hbWUgb2YgYXR0cmlidXRlcykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYXR0cmlidXRlVmFsdWUgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRBdHRyaWJ1dGUoYCR7VGVsZW1ldHJ5RGlyZWN0aXZlLmRpcmVjdGl2ZVByZWZpeH0ke2F0dHJpYnV0ZU5hbWV9YCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBsYWJlbCA9IGBkYXRhLWJpLSR7YXR0cmlidXRlTmFtZX1gO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZShsYWJlbCwgYXR0cmlidXRlVmFsdWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlIGNoYW5nZXMgdG8gZGF0YSBibG9iIG9iamVjdCwgbmVlZGVkIGIvYyBkYXRhIG9iamVjdCB3aWxsIHVwZGF0ZSB3aXRob3V0IHRyaWdnZXJpbmcgc2V0dGVyLlxyXG4gICAgICogU2VsZWN0aXZlbHkgdXBkYXRlIERPTSBmaWVsZHMgYmFzZWQgb24gaW5kaXZpZHVhbCBjaGFuZ2VzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbmdEb0NoZWNrKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmRhdGFCbG9iRGlmZmVyKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNoYW5nZXMgPSB0aGlzLmRhdGFCbG9iRGlmZmVyLmRpZmYodGhpcy5pbnRlcm5hbERhdGFCbG9iKTtcclxuICAgICAgICAgICAgaWYgKGNoYW5nZXMpIHtcclxuICAgICAgICAgICAgICAgIGNoYW5nZXMuZm9yRWFjaEl0ZW0oKGl0ZW0pID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS5jdXJyZW50VmFsdWUgPT09IGl0ZW0ucHJldmlvdXNWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxhYmVsID0gYGRhdGEtYmktJHtpdGVtLmtleX1gO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghaXRlbS5jdXJyZW50VmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucmVtb3ZlQXR0cmlidXRlTlMobnVsbCwgbGFiZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbnRlcm5hbERhdGFCbG9iW2l0ZW0ua2V5XTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBsYWJlbCwgaXRlbS5jdXJyZW50VmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiJdfQ==