@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
273 lines • 37.9 kB
JavaScript
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==