ngx-paypal-with-intent
Version:
Paypal integration for Angular 6, 7 and beyond
506 lines • 59 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('rxjs/operators')) :
typeof define === 'function' && define.amd ? define('ngx-paypal', ['exports', '@angular/core', 'rxjs', 'rxjs/operators'], factory) :
(factory((global['ngx-paypal'] = {}),global.ng.core,global.rxjs,global.rxjs.operators));
}(this, (function (exports,core,rxjs,operators) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {number} */
var PayPalFunding = {
Card: 0,
Credit: 1,
Elv: 2,
};
PayPalFunding[PayPalFunding.Card] = 'Card';
PayPalFunding[PayPalFunding.Credit] = 'Credit';
PayPalFunding[PayPalFunding.Elv] = 'Elv';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {number} */
var PayPalIntegrationType = {
ClientSideREST: 0,
ServerSideREST: 1,
};
PayPalIntegrationType[PayPalIntegrationType.ClientSideREST] = 'ClientSideREST';
PayPalIntegrationType[PayPalIntegrationType.ServerSideREST] = 'ServerSideREST';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var NgxPaypalComponent = /** @class */ (function () {
function NgxPaypalComponent() {
/**
* Indicates if global configuration (provided via 'forRoot') is used
*/
this.useGlobalConfig = false;
/**
* Used for indicating delayed rendered if container is not yet ready in DOM
*/
this.registerPayPalScriptWhenContainerIsReady = false;
/**
* Polling interval if paypal script is pending
*/
this.defaultPollInterval = 50;
/**
* Polling will stop after polling reaches this number
*/
this.maximumPollWaitTime = 5000;
/**
* Name of the global variable where paypal is stored
*/
this.paypalWindowName = 'paypal';
/**
* Name of the global variable indicating that script was initiated (added to page)
*/
this.paypalWindowScriptInitiated = 'ngx-paypal-script-initiated';
/**
* PayPal integration script url
*/
this.paypalScriptUrl = 'https://www.paypalobjects.com/api/checkout.js';
this.payPalButtonContainerIdPrefix = 'ngx-paypal-button-container-';
this.ngUnsubscribe = new rxjs.Subject();
}
Object.defineProperty(NgxPaypalComponent.prototype, "payPalButtonContainerElem", {
set: /**
* @param {?} content
* @return {?}
*/ function (content) {
if (content) {
this._payPalButtonContainerElem = content;
}
},
enumerable: true,
configurable: true
});
/**
* @param {?} changes
* @return {?}
*/
NgxPaypalComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
// init when config once its available
if (this.config) {
this.initPayPal();
}
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
// register script if element is ready in dom
if (this.registerPayPalScriptWhenContainerIsReady && this._payPalButtonContainerElem) {
this.setupScript();
this.registerPayPalScriptWhenContainerIsReady = false;
}
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.initPayPal = /**
* @return {?}
*/
function () {
// set unique paypal container button id
this.payPalButtonContainerId = "" + this.payPalButtonContainerIdPrefix + this.getPseudoUniqueNumber();
// check if paypal was already register and if so, don't add it to page again
if (!window[this.paypalWindowName]) {
// check if script is pending
if (window[this.paypalWindowScriptInitiated] === true) {
this.pollUntilScriptAvailable();
}
else {
// register script and set global flag
window[this.paypalWindowScriptInitiated] = true;
this.addPayPalScriptToPage();
}
}
else {
// just register payment
this.handleScriptRegistering();
}
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.getPseudoUniqueNumber = /**
* @return {?}
*/
function () {
return new Date().valueOf();
};
/**
* Used when there are multiple paypal components on the same page beacuse only 1 of them
* may register paypal script. The other has to be polling until paypal is available or component destroyed
*/
/**
* Used when there are multiple paypal components on the same page beacuse only 1 of them
* may register paypal script. The other has to be polling until paypal is available or component destroyed
* @return {?}
*/
NgxPaypalComponent.prototype.pollUntilScriptAvailable = /**
* Used when there are multiple paypal components on the same page beacuse only 1 of them
* may register paypal script. The other has to be polling until paypal is available or component destroyed
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var obs = rxjs.interval(this.defaultPollInterval)
.pipe(operators.takeUntil(this.ngUnsubscribe), operators.map(function (x) {
if (x >= _this.maximumPollWaitTime) {
console.warn("PayPal script was not loaded after '" + _this.maximumPollWaitTime + "' maximum polling time.");
obs.unsubscribe();
return;
}
// check if paypal script exists
if (window[_this.paypalWindowName]) {
// register script
_this.handleScriptRegistering();
// stop execution
obs.unsubscribe();
}
}))
.subscribe();
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.addPayPalScriptToPage = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var script = document.createElement('script');
script.innerHTML = '';
script.src = this.paypalScriptUrl;
script.onload = function () { return _this.handleScriptRegistering(); };
script.async = true;
script.defer = true;
this.paypalScriptElem.nativeElement.appendChild(script);
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.handleScriptRegistering = /**
* @return {?}
*/
function () {
// check if container with requested id exists
// this is here because dynamically switching between components would cause PayPal to
// throw an error if the container already existed before
if (this._payPalButtonContainerElem && this._payPalButtonContainerElem.nativeElement &&
this._payPalButtonContainerElem.nativeElement.id === this.payPalButtonContainerId) {
// container is ready, setup script right away
this.setupScript();
}
else {
// container is not ready, delay registering until it is
this.registerPayPalScriptWhenContainerIsReady = true;
}
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.setupScript = /**
* @return {?}
*/
function () {
var _this = this;
// first clear container
if (!this._payPalButtonContainerElem) {
throw Error("Cannot setup script because paypal button container with id '" + this.payPalButtonContainerId + "' is not yet ready");
}
this._payPalButtonContainerElem.nativeElement.innerHTML = '';
if (!window[this.paypalWindowName]) {
throw Error('PayPal script is not available');
}
// render PayPal button as per their docs at
// https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/add-paypal-button/
window[this.paypalWindowName].Button.render({
// set environment
env: this.config.environment.toString(),
// Show the buyer a 'Pay Now' button in the checkout flow
commit: this.config.commit,
// init client for client side integration
client: this.getClient(),
// set button config if available
style: this.config.button,
// set funding if available
funding: this.getFunding(),
// payment() is called when the button is clicked
payment: function (data, actions) {
if (_this.config.integrationType === PayPalIntegrationType.ServerSideREST) {
// client needs to create payment on server side
if (!_this.config.payment) {
throw Error("You need set up a create payment method and return\n PayPal's payment id when using server side integration");
}
// Paypal expects promise with payment id (string) to be returned
return _this.config.payment().toPromise()
.then(function (paymentId) {
return paymentId;
});
}
if (_this.config.integrationType === PayPalIntegrationType.ClientSideREST) {
if (!_this.config.transactions || !Array.isArray(_this.config.transactions) || _this.config.transactions.length <= 0) {
throw Error("You need to provide at least 1 transaction for client side integration");
}
/** @type {?} */
var experienceConfig = _this.config.experience;
return actions.payment.create({
// Allow user to specifify intent, else use default 'sale'.
intent: _this.config.intent ? _this.config.intent : 'sale',
payment: {
transactions: _this.config.transactions
},
experience: {
input_fields: {
no_shipping: (experienceConfig && experienceConfig.noShipping) ? 1 : 0
},
presentation: {
brand_name: (experienceConfig && experienceConfig.brandName) ? experienceConfig.brandName : null,
logo_image: (experienceConfig && experienceConfig.logoImage) ? experienceConfig.logoImage : null,
locale_code: (experienceConfig && experienceConfig.localeCode) ? experienceConfig.localeCode : null
}
}
});
}
},
// onAuthorize() is called when the buyer approves the payment
onAuthorize: function (data, actions) {
if (_this.config.integrationType === PayPalIntegrationType.ServerSideREST) {
// client needs to server to execute the payment
if (!_this.config.onAuthorize) {
throw Error("You need set up an execute method when using server side integration");
}
// Paypal expects promise
return _this.config.onAuthorize(data, actions).toPromise();
}
if (_this.config.integrationType === PayPalIntegrationType.ClientSideREST) {
// Make a call to the REST api to execute the payment
return actions.payment.execute().then(function () {
if (!_this.config.onPaymentComplete) {
throw Error("You should provide some callback when payment is finished when using client side integration");
}
_this.config.onPaymentComplete(data, actions);
});
}
},
onError: function (err) {
if (_this.config.onError) {
_this.config.onError(err);
}
},
onCancel: function (data, actions) {
if (_this.config.onCancel) {
_this.config.onCancel(data, actions);
}
},
onClick: function () {
if (_this.config.onClick) {
_this.config.onClick();
}
},
validate: function (actions) {
if (_this.config.validate) {
_this.config.validate(actions);
}
}
}, "#" + this.payPalButtonContainerId);
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.getClient = /**
* @return {?}
*/
function () {
if (this.config.integrationType === PayPalIntegrationType.ClientSideREST) {
if (!this.config.client) {
throw Error("You need to setup client information when using client side integration");
}
return {
production: this.config.client.production,
sandbox: this.config.client.sandbox
};
}
return undefined;
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.getFunding = /**
* @return {?}
*/
function () {
var _this = this;
// resolve funding to use paypal's properties
if (!this.config.funding) {
// no funding provided
return undefined;
}
/** @type {?} */
var allowed = [];
/** @type {?} */
var disallowed = [];
if (this.config.funding.allowed) {
this.config.funding.allowed.forEach(function (type) {
allowed.push(_this.mapFundingType(type));
});
}
if (this.config.funding.disallowed) {
this.config.funding.disallowed.forEach(function (type) {
disallowed.push(_this.mapFundingType(type));
});
}
return {
allowed: allowed,
disallowed: disallowed
};
};
/**
* @param {?} type
* @return {?}
*/
NgxPaypalComponent.prototype.mapFundingType = /**
* @param {?} type
* @return {?}
*/
function (type) {
if (type === PayPalFunding.Card) {
return paypal.FUNDING.CARD;
}
if (type === PayPalFunding.Credit) {
return paypal.FUNDING.CREDIT;
}
if (type === PayPalFunding.Elv) {
return paypal.FUNDING.ELV;
}
throw Error("Unsupported funding type '" + type + "'");
};
NgxPaypalComponent.decorators = [
{ type: core.Component, args: [{
changeDetection: core.ChangeDetectionStrategy.OnPush,
selector: 'ngx-paypal',
template: "\n <div #payPalScriptElem></div>\n <div #payPalButtonContainerElem [id]=\"payPalButtonContainerId\"></div>\n "
}] }
];
/** @nocollapse */
NgxPaypalComponent.ctorParameters = function () { return []; };
NgxPaypalComponent.propDecorators = {
config: [{ type: core.Input }],
useGlobalConfig: [{ type: core.Input }],
paypalScriptElem: [{ type: core.ViewChild, args: ['payPalScriptElem',] }],
payPalButtonContainerElem: [{ type: core.ViewChild, args: ['payPalButtonContainerElem',] }]
};
return NgxPaypalComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var NgxPayPalModule = /** @class */ (function () {
function NgxPayPalModule() {
}
NgxPayPalModule.decorators = [
{ type: core.NgModule, args: [{
imports: [],
declarations: [
NgxPaypalComponent,
],
exports: [
NgxPaypalComponent,
]
},] }
];
return NgxPayPalModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {string} */
var PayPalEnvironment = {
Sandbox: 'sandbox',
Production: 'production',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var PayPalConfig = /** @class */ (function () {
function PayPalConfig(integrationType, environment, config) {
this.integrationType = integrationType;
this.environment = environment;
/**
* Show 'Pay Now' button config
*/
this.commit = true;
/**
* Set the intent of the payment.
*/
this.intent = 'sale';
Object.assign(this, config);
}
return PayPalConfig;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
exports.NgxPayPalModule = NgxPayPalModule;
exports.PayPalEnvironment = PayPalEnvironment;
exports.PayPalFunding = PayPalFunding;
exports.PayPalIntegrationType = PayPalIntegrationType;
exports.PayPalConfig = PayPalConfig;
exports.NgxPaypalComponent = NgxPaypalComponent;
exports.ɵa = NgxPaypalComponent;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXBheXBhbC51bWQuanMubWFwIiwic291cmNlcyI6WyJuZzovL25neC1wYXlwYWwvbGliL21vZGVscy9wYXlwYWwtZnVuZGluZy50cyIsIm5nOi8vbmd4LXBheXBhbC9saWIvbW9kZWxzL3BheXBhbC1pbnRlZ3JhdGlvbi50cyIsIm5nOi8vbmd4LXBheXBhbC9saWIvY29tcG9uZW50cy9wYXlwYWwtY29tcG9uZW50LnRzIiwibmc6Ly9uZ3gtcGF5cGFsL2xpYi9uZ3gtcGF5cGFsLm1vZHVsZS50cyIsIm5nOi8vbmd4LXBheXBhbC9saWIvbW9kZWxzL3BheXBhbC1lbnZpcm9ubWVudC50cyIsIm5nOi8vbmd4LXBheXBhbC9saWIvbW9kZWxzL3BheXBhbC1tb2RlbHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGVudW0gUGF5UGFsRnVuZGluZyB7XG4gICAgQ2FyZCxcbiAgICBDcmVkaXQsXG4gICAgRWx2XG59XG4iLCJleHBvcnQgZW51bSBQYXlQYWxJbnRlZ3JhdGlvblR5cGUge1xuICAgIENsaWVudFNpZGVSRVNULFxuICAgIFNlcnZlclNpZGVSRVNULFxufVxuIiwiaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkRlc3Ryb3ksXG4gICAgU2ltcGxlQ2hhbmdlcyxcbiAgICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgaW50ZXJ2YWwsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBQYXlQYWxGdW5kaW5nIH0gZnJvbSAnLi4vbW9kZWxzL3BheXBhbC1mdW5kaW5nJztcbmltcG9ydCB7IFBheVBhbEludGVncmF0aW9uVHlwZSB9IGZyb20gJy4uL21vZGVscy9wYXlwYWwtaW50ZWdyYXRpb24nO1xuaW1wb3J0IHsgSVBheXBhbENsaWVudCwgSVBheVBhbFBheW1lbnRDb21wbGV0ZURhdGEsIFBheVBhbENvbmZpZyB9IGZyb20gJy4uL21vZGVscy9wYXlwYWwtbW9kZWxzJztcblxuLyoqXG4gKiBHbG9iYWwgdmFyaWFibGUgd2hlcmUgUGF5UGFsIGlzIGxvYWRlZCB0b1xuICovXG5kZWNsYXJlIHZhciBwYXlwYWw6IGFueTtcblxuQENvbXBvbmVudCh7XG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgc2VsZWN0b3I6ICduZ3gtcGF5cGFsJyxcbiAgICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgI3BheVBhbFNjcmlwdEVsZW0+PC9kaXY+XG4gICAgPGRpdiAjcGF5UGFsQnV0dG9uQ29udGFpbmVyRWxlbSBbaWRdPVwicGF5UGFsQnV0dG9uQ29udGFpbmVySWRcIj48L2Rpdj5cbiAgICBgXG59KVxuZXhwb3J0IGNsYXNzIE5neFBheXBhbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcblxuICAgIC8qKlxuICAgICAqIENvbmZpZ3VyYXRpb24gZm9yIHBheXBhbC5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBjb25maWc6IFBheVBhbENvbmZpZztcblxuICAgIC8qKlxuICAgICAqIEluZGljYXRlcyBpZiBnbG9iYWwgY29uZmlndXJhdGlvbiAocHJvdmlkZWQgdmlhICdmb3JSb290JykgaXMgdXNlZFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHVzZUdsb2JhbENvbmZpZyA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQ29udGFpbmVyIGZvciBwYXlwYWwgc2NyaXB0XG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgncGF5UGFsU2NyaXB0RWxlbScpIHBheXBhbFNjcmlwdEVsZW06IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGZvciBpbmRpY2F0aW5nIGRlbGF5ZWQgcmVuZGVyZWQgaWYgY29udGFpbmVyIGlzIG5vdCB5ZXQgcmVhZHkgaW4gRE9NXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWdpc3RlclBheVBhbFNjcmlwdFdoZW5Db250YWluZXJJc1JlYWR5ID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBIb2xkcyBjdXJyZW50IGNvbnRhaW5lciBlbGVtZW50XG4gICAgICovXG4gICAgcHJpdmF0ZSBfcGF5UGFsQnV0dG9uQ29udGFpbmVyRWxlbT86IEVsZW1lbnRSZWY7XG4gICAgQFZpZXdDaGlsZCgncGF5UGFsQnV0dG9uQ29udGFpbmVyRWxlbScpIHNldCBwYXlQYWxCdXR0b25Db250YWluZXJFbGVtKGNvbnRlbnQ6IEVsZW1lbnRSZWYpIHtcbiAgICAgICAgaWYgKGNvbnRlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3BheVBhbEJ1dHRvbkNvbnRhaW5lckVsZW0gPSBjb250ZW50O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUG9sbGluZyBpbnRlcnZhbCBpZiBwYXlwYWwgc2NyaXB0IGlzIHBlbmRpbmdcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRQb2xsSW50ZXJ2YWwgPSA1MDtcblxuICAgIC8qKlxuICAgICAqIFBvbGxpbmcgd2lsbCBzdG9wIGFmdGVyIHBvbGxpbmcgcmVhY2hlcyB0aGlzIG51bWJlclxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgbWF4aW11bVBvbGxXYWl0VGltZSA9IDUwMDA7XG5cbiAgICAvKipcbiAgICAqIE5hbWUgb2YgdGhlIGdsb2JhbCB2YXJpYWJsZSB3aGVyZSBwYXlwYWwgaXMgc3RvcmVkXG4gICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IHBheXBhbFdpbmRvd05hbWUgPSAncGF5cGFsJztcblxuICAgIC8qKlxuICAgICAqIE5hbWUgb2YgdGhlIGdsb2JhbCB2YXJpYWJsZSBpbmRpY2F0aW5nIHRoYXQgc2NyaXB0IHdhcyBpbml0aWF0ZWQgKGFkZGVkIHRvIHBhZ2UpXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBwYXlwYWxXaW5kb3dTY3JpcHRJbml0aWF0ZWQgPSAnbmd4LXBheXBhbC1zY3JpcHQtaW5pdGlhdGVkJztcblxuICAgIC8qKlxuICAgICAqIFBheVBhbCBpbnRlZ3JhdGlvbiBzY3JpcHQgdXJsXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBwYXlwYWxTY3JpcHRVcmwgPSAnaHR0cHM6Ly93d3cucGF5cGFsb2JqZWN0cy5jb20vYXBpL2NoZWNrb3V0LmpzJztcblxuICAgIC8qKlxuICAgICAqIElkIG9mIHRoZSBlbGVtZW50IHdoZXJlIFBheVBhbCBidXR0b24gd2lsbCBiZSByZW5kZXJlZFxuICAgICAqL1xuICAgIHB1YmxpYyBwYXlQYWxCdXR0b25Db250YWluZXJJZD86IHN0cmluZztcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgcGF5UGFsQnV0dG9uQ29udGFpbmVySWRQcmVmaXggPSAnbmd4LXBheXBhbC1idXR0b24tY29udGFpbmVyLSc7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IG5nVW5zdWJzY3JpYmU6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgKSB7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgICAgICAvLyBpbml0IHdoZW4gY29uZmlnIG9uY2UgaXRzIGF2YWlsYWJsZVxuICAgICAgICBpZiAodGhpcy5jb25maWcpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFBheVBhbCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICAvLyByZWdpc3RlciBzY3JpcHQgaWYgZWxlbWVudCBpcyByZWFkeSBpbiBkb21cbiAgICAgICAgaWYgKHRoaXMucmVnaXN0ZXJQYXlQYWxTY3JpcHRXaGVuQ29udGFpbmVySXNSZWFkeSAmJiB0aGlzLl9wYXlQYWxCdXR0b25Db250YWluZXJFbGVtKSB7XG4gICAgICAgICAgICB0aGlzLnNldHVwU2NyaXB0KCk7XG4gICAgICAgICAgICB0aGlzLnJlZ2lzdGVyUGF5UGFsU2NyaXB0V2hlbkNvbnRhaW5lcklzUmVhZHkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLm5nVW5zdWJzY3JpYmUubmV4dCgpO1xuICAgICAgICB0aGlzLm5nVW5zdWJzY3JpYmUuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRQYXlQYWwoKTogdm9pZCB7XG4gICAgICAgIC8vIHNldCB1bmlxdWUgcGF5cGFsIGNvbnRhaW5lciBidXR0b24gaWRcbiAgICAgICAgdGhpcy5wYXlQYWxCdXR0b25Db250YWluZXJJZCA9IGAke3RoaXMucGF5UGFsQnV0dG9uQ29udGFpbmVySWRQcmVmaXh9JHt0aGlzLmdldFBzZXVkb1VuaXF1ZU51bWJlcigpfWA7XG4gICAgICAgIC8vIGNoZWNrIGlmIHBheXBhbCB3YXMgYWxyZWFkeSByZWdpc3RlciBhbmQgaWYgc28sIGRvbid0IGFkZCBpdCB0byBwYWdlIGFnYWluXG4gICAgICAgIGlmICghd2luZG93W3RoaXMucGF5cGFsV2luZG93TmFtZV0pIHtcbiAgICAgICAgICAgIC8vIGNoZWNrIGlmIHNjcmlwdCBpcyBwZW5kaW5nXG4gICAgICAgICAgICBpZiAod2luZG93W3RoaXMucGF5cGFsV2luZG93U2NyaXB0SW5pdGlhdGVkXSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMucG9sbFVudGlsU2NyaXB0QXZhaWxhYmxlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIHJlZ2lzdGVyIHNjcmlwdCBhbmQgc2V0IGdsb2JhbCBmbGFnXG4gICAgICAgICAgICAgICAgd2luZG93W3RoaXMucGF5cGFsV2luZG93U2NyaXB0SW5pdGlhdGVkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRQYXlQYWxTY3JpcHRUb1BhZ2UoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8ganVzdCByZWdpc3RlciBwYXltZW50XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVNjcmlwdFJlZ2lzdGVyaW5nKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFBzZXVkb1VuaXF1ZU51bWJlcigpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gbmV3IERhdGUoKS52YWx1ZU9mKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXNlZCB3aGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBwYXlwYWwgY29tcG9uZW50cyBvbiB0aGUgc2FtZSBwYWdlIGJlYWN1c2Ugb25seSAxIG9mIHRoZW1cbiAgICAgKiBtYXkgcmVnaXN0ZXIgcGF5cGFsIHNjcmlwdC4gVGhlIG90aGVyIGhhcyB0byBiZSBwb2xsaW5nIHVudGlsIHBheXBhbCBpcyBhdmFpbGFibGUgb3IgY29tcG9uZW50IGRlc3Ryb3llZFxuICAgICAqL1xuICAgIHByaXZhdGUgcG9sbFVudGlsU2NyaXB0QXZhaWxhYmxlKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBvYnMgPSBpbnRlcnZhbCh0aGlzLmRlZmF1bHRQb2xsSW50ZXJ2YWwpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICB0YWtlVW50aWwodGhpcy5uZ1Vuc3Vic2NyaWJlKSxcbiAgICAgICAgICAgICAgICBtYXAoKHgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHggPj0gdGhpcy5tYXhpbXVtUG9sbFdhaXRUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFBheVBhbCBzY3JpcHQgd2FzIG5vdCBsb2FkZWQgYWZ0ZXIgJyR7dGhpcy5tYXhpbXVtUG9sbFdhaXRUaW1lfScgbWF4aW11bSBwb2xsaW5nIHRpbWUuYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBvYnMudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIHBheXBhbCBzY3JpcHQgZXhpc3RzXG4gICAgICAgICAgICAgICAgICAgIGlmICh3aW5kb3dbdGhpcy5wYXlwYWxXaW5kb3dOYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVnaXN0ZXIgc2NyaXB0XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZVNjcmlwdFJlZ2lzdGVyaW5nKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0b3AgZXhlY3V0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnMudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhZGRQYXlQYWxTY3JpcHRUb1BhZ2UoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICBzY3JpcHQuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgIHNjcmlwdC5zcmMgPSB0aGlzLnBheXBhbFNjcmlwdFVybDtcbiAgICAgICAgc2NyaXB0Lm9ubG9hZCA9ICgpID0+IHRoaXMuaGFuZGxlU2NyaXB0UmVnaXN0ZXJpbmcoKTtcbiAgICAgICAgc2NyaXB0LmFzeW5jID0gdHJ1ZTtcbiAgICAgICAgc2NyaXB0LmRlZmVyID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLnBheXBhbFNjcmlwdEVsZW0ubmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlU2NyaXB0UmVnaXN0ZXJpbmcoKTogdm9pZCB7XG4gICAgICAgIC8vIGNoZWNrIGlmIGNvbnRhaW5lciB3aXRoIHJlcXVlc3RlZCBpZCBleGlzdHNcbiAgICAgICAgLy8gdGhpcyBpcyBoZXJlIGJlY2F1c2UgZHluYW1pY2FsbHkgc3dpdGNoaW5nIGJldHdlZW4gY29tcG9uZW50cyB3b3VsZCBjYXVzZSBQYXlQYWwgdG9cbiAgICAgICAgLy8gdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGNvbnRhaW5lciBhbHJlYWR5IGV4aXN0ZWQgYmVmb3JlXG4gICAgICAgIGlmICh0aGlzLl9wYXlQYWxCdXR0b25Db250YWluZXJFbGVtICYmIHRoaXMuX3BheVBhbEJ1dHRvbkNvbnRhaW5lckVsZW0ubmF0aXZlRWxlbWVudCAmJlxuICAgICAgICAgICAgdGhpcy5fcGF5UGFsQnV0dG9uQ29udGFpbmVyRWxlbS5uYXRpdmVFbGVtZW50LmlkID09PSB0aGlzLnBheVBhbEJ1dHRvbkNvbnRhaW5lcklkKSB7XG4gICAgICAgICAgICAvLyBjb250YWluZXIgaXMgcmVhZHksIHNldHVwIHNjcmlwdCByaWdodCBhd2F5XG4gICAgICAgICAgICB0aGlzLnNldHVwU2NyaXB0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBjb250YWluZXIgaXMgbm90IHJlYWR5LCBkZWxheSByZWdpc3RlcmluZyB1bnRpbCBpdCBpc1xuICAgICAgICAgICAgdGhpcy5yZWdpc3RlclBheVBhbFNjcmlwdFdoZW5Db250YWluZXJJc1JlYWR5ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2V0dXBTY3JpcHQoKTogdm9pZCB7XG4gICAgICAgIC8vIGZpcnN0IGNsZWFyIGNvbnRhaW5lclxuICAgICAgICBpZiAoIXRoaXMuX3BheVBhbEJ1dHRvbkNvbnRhaW5lckVsZW0pIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKGBDYW5ub3Qgc2V0dXAgc2NyaXB0IGJlY2F1c2UgcGF5cGFsIGJ1dHRvbiBjb250YWluZXIgd2l0aCBpZCAnJHt0aGlzLnBheVBhbEJ1dHRvbkNvbnRhaW5lcklkfScgaXMgbm90IHlldCByZWFkeWApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcGF5UGFsQnV0dG9uQ29udGFpbmVyRWxlbS5uYXRpdmVFbGVtZW50LmlubmVySFRNTCA9ICcnO1xuXG4gICAgICAgIGlmICghd2luZG93W3RoaXMucGF5cGFsV2luZG93TmFtZV0pIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdQYXlQYWwgc2NyaXB0IGlzIG5vdCBhdmFpbGFibGUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlbmRlciBQYXlQYWwgYnV0dG9uIGFzIHBlciB0aGVpciBkb2NzIGF0XG4gICAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLnBheXBhbC5jb20vZG9jcy9pbnRlZ3JhdGlvbi9kaXJlY3QvZXhwcmVzcy1jaGVja291dC9pbnRlZ3JhdGlvbi1qc3Y0L2FkZC1wYXlwYWwtYnV0dG9uL1xuICAgICAgICB3aW5kb3dbdGhpcy5wYXlwYWxXaW5kb3dOYW1lXS5CdXR0b24ucmVuZGVyKHtcbiAgICAgICAgICAgIC8vIHNldCBlbnZpcm9ubWVudFxuICAgICAgICAgICAgZW52OiB0aGlzLmNvbmZpZy5lbnZpcm9ubWVudC50b1N0cmluZygpLFxuXG4gICAgICAgICAgICAvLyBTaG93IHRoZSBidXllciBhICdQYXkgTm93JyBidXR0b24gaW4gdGhlIGNoZWNrb3V0IGZsb3dcbiAgICAgICAgICAgIGNvbW1pdDogdGhpcy5jb25maWcuY29tbWl0LFxuXG4gICAgICAgICAgICAvLyBpbml0IGNsaWVudCBmb3IgY2xpZW50IHNpZGUgaW50ZWdyYXRpb25cbiAgICAgICAgICAgIGNsaWVudDogdGhpcy5nZXRDbGllbnQoKSxcblxuICAgICAgICAgICAgLy8gc2V0IGJ1dHRvbiBjb25maWcgaWYgYXZhaWxhYmxlXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuYnV0dG9uLFxuXG4gICAgICAgICAgICAvLyBzZXQgZnVuZGluZyBpZiBhdmFpbGFibGVcbiAgICAgICAgICAgIGZ1bmRpbmc6IHRoaXMuZ2V0RnVuZGluZygpLFxuXG4gICAgICAgICAgICAvLyBwYXltZW50KCkgaXMgY2FsbGVkIHdoZW4gdGhlIGJ1dHRvbiBpcyBjbGlja2VkXG4gICAgICAgICAgICBwYXltZW50OiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5pbnRlZ3JhdGlvblR5cGUgPT09IFBheVBhbEludGVncmF0aW9uVHlwZS5TZXJ2ZXJTaWRlUkVTVCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBjbGllbnQgbmVlZHMgdG8gY3JlYXRlIHBheW1lbnQgb24gc2VydmVyIHNpZGVcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5wYXltZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgWW91IG5lZWQgc2V0IHVwIGEgY3JlYXRlIHBheW1lbnQgbWV0aG9kIGFuZCByZXR1cm5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXlQYWwncyBwYXltZW50IGlkIHdoZW4gdXNpbmcgc2VydmVyIHNpZGUgaW50ZWdyYXRpb25gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFBheXBhbCBleHBlY3RzIHByb21pc2Ugd2l0aCBwYXltZW50IGlkIChzdHJpbmcpIHRvIGJlIHJldHVybmVkXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5wYXltZW50KCkudG9Qcm9taXNlKClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHBheW1lbnRJZCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBheW1lbnRJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5pbnRlZ3JhdGlvblR5cGUgPT09IFBheVBhbEludGVncmF0aW9uVHlwZS5DbGllbnRTaWRlUkVTVCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnRyYW5zYWN0aW9ucyB8fCAhQXJyYXkuaXNBcnJheSh0aGlzLmNvbmZpZy50cmFuc2FjdGlvbnMpIHx8IHRoaXMuY29uZmlnLnRyYW5zYWN0aW9ucy5sZW5ndGggPD0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoYFlvdSBuZWVkIHRvIHByb3ZpZGUgYXQgbGVhc3QgMSB0cmFuc2FjdGlvbiBmb3IgY2xpZW50IHNpZGUgaW50ZWdyYXRpb25gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cGVyaWVuY2VDb25maWcgPSB0aGlzLmNvbmZpZy5leHBlcmllbmNlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9ucy5wYXltZW50LmNyZWF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBbGxvdyB1c2VyIHRvIHNwZWNpZmlmeSBpbnRlbnQsIGVsc2UgdXNlIGRlZmF1bHQgJ3NhbGUnLlxuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZW50OiB0aGlzLmNvbmZpZy5pbnRlbnQgPyB0aGlzLmNvbmZpZy5pbnRlbnQgOiAnc2FsZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXltZW50OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25zOiB0aGlzLmNvbmZpZy50cmFuc2FjdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlcmllbmNlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRfZmllbGRzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vX3NoaXBwaW5nOiAoZXhwZXJpZW5jZUNvbmZpZyAmJiBleHBlcmllbmNlQ29uZmlnLm5vU2hpcHBpbmcpID8gMSA6IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlbnRhdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFuZF9uYW1lOiAoZXhwZXJpZW5jZUNvbmZpZyAmJiBleHBlcmllbmNlQ29uZmlnLmJyYW5kTmFtZSkgPyBleHBlcmllbmNlQ29uZmlnLmJyYW5kTmFtZSA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ29faW1hZ2U6IChleHBlcmllbmNlQ29uZmlnICYmIGV4cGVyaWVuY2VDb25maWcubG9nb0ltYWdlKSA/IGV4cGVyaWVuY2VDb25maWcubG9nb0ltYWdlIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlX2NvZGU6IChleHBlcmllbmNlQ29uZmlnICYmIGV4cGVyaWVuY2VDb25maWcubG9jYWxlQ29kZSkgPyBleHBlcmllbmNlQ29uZmlnLmxvY2FsZUNvZGUgOiBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvLyBvbkF1dGhvcml6ZSgpIGlzIGNhbGxlZCB3aGVuIHRoZSBidXllciBhcHByb3ZlcyB0aGUgcGF5bWVudFxuICAgICAgICAgICAgb25BdXRob3JpemU6IChkYXRhOiBJUGF5UGFsUGF5bWVudENvbXBsZXRlRGF0YSwgYWN0aW9uczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLmludGVncmF0aW9uVHlwZSA9PT0gUGF5UGFsSW50ZWdyYXRpb25UeXBlLlNlcnZlclNpZGVSRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNsaWVudCBuZWVkcyB0byBzZXJ2ZXIgdG8gZXhlY3V0ZSB0aGUgcGF5bWVudFxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLm9uQXV0aG9yaXplKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgWW91IG5lZWQgc2V0IHVwIGFuIGV4ZWN1dGUgbWV0aG9kIHdoZW4gdXNpbmcgc2VydmVyIHNpZGUgaW50ZWdyYXRpb25gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFBheXBhbCBleHBlY3RzIHByb21pc2VcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLm9uQXV0aG9yaXplKGRhdGEsIGFjdGlvbnMpLnRvUHJvbWlzZSgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5pbnRlZ3JhdGlvblR5cGUgPT09IFBheVBhbEludGVncmF0aW9uVHlwZS5DbGllbnRTaWRlUkVTVCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIGEgY2FsbCB0byB0aGUgUkVTVCBhcGkgdG8gZXhlY3V0ZSB0aGUgcGF5bWVudFxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9ucy5wYXltZW50LmV4ZWN1dGUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5jb25maWcub25QYXltZW50Q29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgWW91IHNob3VsZCBwcm92aWRlIHNvbWUgY2FsbGJhY2sgd2hlbiBwYXltZW50IGlzIGZpbmlzaGVkIHdoZW4gdXNpbmcgY2xpZW50IHNpZGUgaW50ZWdyYXRpb25gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLm9uUGF5bWVudENvbXBsZXRlKGRhdGEsIGFjdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLm9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcub25FcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIG9uQ2FuY2VsOiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5vbkNhbmNlbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5vbkNhbmNlbChkYXRhLCBhY3Rpb25zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb25DbGljazogKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5vbkNsaWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLm9uQ2xpY2soKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmFsaWRhdGU6IChhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLnZhbGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLnZhbGlkYXRlKGFjdGlvbnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgYCMke3RoaXMucGF5UGFsQnV0dG9uQ29udGFpbmVySWR9YCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRDbGllbnQoKTogSVBheXBhbENsaWVudCB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5pbnRlZ3JhdGlvblR5cGUgPT09IFBheVBhbEludGVncmF0aW9uVHlwZS5DbGllbnRTaWRlUkVTVCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5jbGllbnQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgWW91IG5lZWQgdG8gc2V0dXAgY2xpZW50IGluZm9ybWF0aW9uIHdoZW4gdXNpbmcgY2xpZW50IHNpZGUgaW50ZWdyYXRpb25gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBwcm9kdWN0aW9uOiB0aGlzLmNvbmZpZy5jbGllbnQucHJvZHVjdGlvbixcbiAgICAgICAgICAgICAgICBzYW5kYm94OiB0aGlzLmNvbmZpZy5jbGllbnQuc2FuZGJveFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRGdW5kaW5nKCk6IHtcbiAgICAgICAgYWxsb3dlZDogYW55W10sXG4gICAgICAgIGRpc2FsbG93ZWQ6IGFueVtdXG4gICAgfSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIC8vIHJlc29sdmUgZnVuZGluZyB0byB1c2UgcGF5cGFsJ3MgcHJvcGVydGllc1xuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLmZ1bmRpbmcpIHtcbiAgICAgICAgICAgIC8vIG5vIGZ1bmRpbmcgcHJvdmlkZWRcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhbGxvd2VkOiBhbnlbXSA9IFtdO1xuICAgICAgICBjb25zdCBkaXNhbGxvd2VkOiBhbnlbXSA9IFtdO1xuXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5mdW5kaW5nLmFsbG93ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmZ1bmRpbmcuYWxsb3dlZC5mb3JFYWNoKHR5cGUgPT4ge1xuICAgICAgICAgICAgICAgIGFsbG93ZWQucHVzaCh0aGlzLm1hcEZ1bmRpbmdUeXBlKHR5cGUpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmZ1bmRpbmcuZGlzYWxsb3dlZCkge1xuICAgICAgICAgICAgdGhpcy5jb25maWcuZnVuZGluZy5kaXNhbGxvd2VkLmZvckVhY2godHlwZSA9PiB7XG4gICAgICAgICAgICAgICAgZGlzYWxsb3dlZC5wdXNoKHRoaXMubWFwRnVuZGluZ1R5cGUodHlwZSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYWxsb3dlZDogYWxsb3dlZCxcbiAgICAgICAgICAgIGRpc2FsbG93ZWQ6IGRpc2FsbG93ZWRcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG1hcEZ1bmRpbmdUeXBlKHR5cGU6IFBheVBhbEZ1bmRpbmcpOiBhbnkge1xuICAgICAgICBpZiAodHlwZSA9PT0gUGF5UGFsRnVuZGluZy5DYXJkKSB7XG4gICAgICAgICAgICByZXR1cm4gcGF5cGFsLkZVTkRJTkcuQ0FSRDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gUGF5UGFsRnVuZGluZy5DcmVkaXQpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXlwYWwuRlVORElORy5DUkVESVQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09IFBheVBhbEZ1bmRpbmcuRWx2KSB7XG4gICAgICAgICAgICByZXR1cm4gcGF5cGFsLkZVTkRJTkcuRUxWO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IEVycm9yKGBVbnN1cHBvcnRlZCBmdW5kaW5nIHR5cGUgJyR7dHlwZX0nYCk7XG4gICAgfVxufVxuXG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBOZ3hQYXlwYWxDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvcGF5cGFsLWNvbXBvbmVudCc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgXSxcbiAgZGVjbGFyYXRpb25zOiBbXG4gICAgTmd4UGF5cGFsQ29tcG9uZW50LFxuICBdLFxuICBleHBvcnRzOiBbXG4gICAgTmd4UGF5cGFsQ29tcG9uZW50LFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIE5neFBheVBhbE1vZHVsZSB7XG59XG5cblxuIiwiZXhwb3J0IGVudW0gUGF5UGFsRW52aXJvbm1lbnQge1xuICAgIFNhbmRib3ggPSAnc2FuZGJveCcsXG4gICAgUHJvZHVjdGlvbiA9ICdwcm9kdWN0aW9uJ1xufVxuIiwiaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBQYXlQYWxGdW5kaW5nIH0gZnJvbSAnLi9wYXlwYWwtZnVuZGluZyc7XG5pbXBvcnQgeyBQYXlQYWxFbnZpcm9ubWVudCB9IGZyb20gJy4vcGF5cGFsLWVudmlyb25tZW50JztcbmltcG9ydCB7IFBheVBhbEludGVncmF0aW9uVHlwZSB9IGZyb20gJy4vcGF5cGFsLWludGVncmF0aW9uJztcblxuZXhwb3J0IGNsYXNzIFBheVBhbENvbmZpZyB7XG5cbiAgICAvKipcbiAgICAgKiBTaG93ICdQYXkgTm93JyBidXR0b24gY29uZmlnXG4gICAgICovXG4gICAgcHVibGljIGNvbW1pdCA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGludGVudCBvZiB0aGUgcGF5bWVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgaW50ZW50ID0gJ3NhbGUnO1xuXG4gICAgLyoqXG4gICAgICogQ2FsbGVkIHRvIGNyZWF0ZSBuZXcgcGF5bWVudCBmb3Igc2VydmVyIHNpZGUgaW50ZWdyYXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgcGF5bWVudD86ICgpID0+IE9ic2VydmFibGU8c3RyaW5nPjtcblxuICAgIC8qKlxuICAgICAqIENhbGxlZCB0byBleGVjdXRlIHBheW1lbnQgZm9yIHNlcnZlciBzaWRlIGludGVncmF0aW9uXG4gICAgICovXG4gICAgcHVibGljIG9uQXV0aG9yaXplPzogKGRhdGE6IElQYXlQYWxQYXltZW50Q29tcGxldGVEYXRhLCBhY3Rpb25zOiBhbnkpID0+IE9ic2VydmFibGU8dm9pZD47XG5cbiAgICAvKipcbiAgICAgKiBDbGllbnQgdG9rZW5zIGZvciBjbGllbnQgc2lkZSBpbnRlZ3JhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBjbGllbnQ/OiBJUGF5cGFsQ2xpZW50O1xuXG4gICAgLyoqXG4gICAgICogQXJyYXkgb2YgdHJhbnNhY3Rpb24sIHJlcXVpcmVkIGZvciBjbGllbnQgc2lkZSBpbnRlZ3JhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyB0cmFuc2FjdGlvbnM/OiBJUGF5UGFsVHJhbnNhY3Rpb25bXTtcblxuICAgIC8qKlxuICAgICAqIFBheW1lbnQgRXhwZXJpZW5jZSBjb25maWd1cmF0aW9uc1xuICAgICAqL1xuICAgIHB1YmxpYyBleHBlcmllbmNlPzogSVBheVBhbEV4cGVyaWVuY2U7XG5cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgZm9yIGNsaWVudCBzaWRlIGludGVncmF0aW9uIHdoZW4gcGF5bWVudCBpcyBleGVjdXRlZFxuICAgICAqL1xuICAgIHB1YmxpYyBvblBheW1lbnRDb21wbGV0ZT86IChkYXRhOiBJUGF5UGFsUGF5bWVudENvbXBsZXRlRGF0YSwgYWN0aW9uczogYW55KSA9PiB2b2lkO1xuXG4gICAgLyoqXG4gICAgICogQnV0dG9uIGNvbmZpZ3VyYXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgYnV0dG9uPzogSVBheVBhbEJ1dHRvblN0eWxlO1xuXG4gICAgLyoqXG4gICAgICogUGF5cGFsIGZ1bmRpbmcgY29uZmlndXJhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBmdW5kaW5nPzogSVBheVBhbEZ1bmRpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiBQYXlQYWwgZXhwZXJpZW5jZXMgYW4gZXJyb3JcbiAgICAgKi9cbiAgICBwdWJsaWMgb25FcnJvcj86IChlcnI6IGFueSkgPT4gdm9pZDtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgaGFuZGxlciB3aWxsIGJlIGNhbGxlZCBmb3IgZXZlcnkgY2xpY2sgb24gdGhlIFBheVBhbCBidXR0b25cbiAgICAgKi9cbiAgICBwdWJsaWMgb25DbGljaz86ICgpID0+IHZvaWQ7XG5cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiB1c2VyIGNhbmNlbHMgcGF5bWVudFxuICAgICAqL1xuICAgIHB1YmxpYyBvbkNhbmNlbD86IChkYXRhOiBJUGF5UGFsQ2FuY2VsUGF5bWVudCwgYWN0aW9uczogYW55KSA9PiB2b2lkO1xuXG4gICAgLyoqXG4gICAgICogQ2FuIGJlIHVzZWQgdG8gdmFsaWRhdGlvbiBhcyBjYW4gYmUgc2VlbiBoZXJlOiBodHRwczovL2RldmVsb3Blci5wYXlwYWwuY29tL2RlbW8vY2hlY2tvdXQvIy9wYXR0ZXJuL3ZhbGlkYXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgdmFsaWRhdGU/OiAoYWN0aW9uczogYW55KSA9PiB2b2lkO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUeXBlIG9mIHRoZSBpbnRlZ3JhdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgcHVibGljIGludGVncmF0aW9uVHlwZTogUGF5UGFsSW50ZWdyYXRpb25UeXBlLFxuICAgICAgICAvKipcbiAgICAgICAgICogRW52aXJvbm1lbnRcbiAgICAgICAgICovXG4gICAgICAgIHB1YmxpYyBlbnZpcm9ubWVudDogUGF5UGFsRW52aXJvbm1lbnQsXG4gICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgICAgb25FcnJvcj86IChlcnI6IGFueSkgPT4gdm9pZCxcbiAgICAgICAgICAgIG9uQ2xpY2s/OiAoKSA9PiB2b2lkLFxuICAgICAgICAgICAgdmFsaWRhdGU/OiAoYWN0aW9uczogYW55KSA9PiB2b2lkO1xuICAgICAgICAgICAgb25DYW5jZWw/OiAoZGF0YTogSVBheVBhbENhbmNlbFBheW1lbnQsIGFjdGlvbnM6IGFueSkgPT4gdm9pZCxcbiAgICAgICAgICAgIHBheW1lbnQ/OiAoKSA9PiBPYnNlcnZhYmxlPHN0cmluZz4sXG4gICAgICAgICAgICBvbkF1dGhvcml6ZT86IChkYXRhOiBJUGF5UGFsUGF5bWVudENvbXBsZXRlRGF0YSwgYWN0aW9uczogYW55KSA9PiBPYnNlcnZhYmxlPHZvaWQ+LFxuICAgICAgICAgICAgY2xpZW50PzogSVBheXBhbENsaWVudCxcbiAgICAgICAgICAgIG9uUGF5bWVudENvbXBsZXRlPzogKGRhdGE6IElQYXlQYWxQYXltZW50Q29tcGxldGVEYXRhLCBhY3Rpb25zOiBhbnkpID0+IHZvaWQsXG4gICAgICAgICAgICB0cmFuc2FjdGlvbnM/OiBJUGF5UGFsVHJhbnNhY3Rpb25bXSxcbiAgICAgICAgICAgIG5vdGVfdG9fcGF5ZXI/OiBzdHJpbmc7XG4gICAgICAgICAgICBleHBlcmllbmNlPzogSVBheVBhbEV4cGVyaWVuY2UsXG4gICAgICAgICAgICBjb21taXQ/OiBib29sZWFuLFxuICAgICAgICAgICAgYnV0dG9uPzogSVBheVBhbEJ1dHRvblN0eWxlLFxuICAgICAgICAgICAgZnVuZGluZz86IElQYXlQYWxGdW5kaW5nXG4gICAgICAgIH0pIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCBjb25maWcpO1xuICAgIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUGF5UGFsUGF5bWVudENvbXBsZXRlRGF0YSB7XG4gICAgaW50ZW50OiBzdHJpbmc7XG4gICAgb3JkZXJJRDogc3RyaW5nO1xuICAgIHBheWVySUQ6IHN0cmluZztcbiAgICBwYXltZW50SUQ6IHN0cmluZztcbiAgICBwYXltZW50VG9rZW46IHN0cmluZztcbiAgICByZXR1cm5Vcmw6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUGF5UGFsQ2FuY2VsUGF5bWVudCB7XG4gICAgZGF0YTogSVBheVBhbENhbmNlbFBheW1lbnREYXRhO1xuICAgIGFjdGlvbnM6IGFueTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUGF5UGFsQ2FuY2VsUGF5bWVudERhdGEge1xuICAgIGJpbGxpbmdJRDogc3RyaW5nO1xuICAgIGNhbmNlbFVybDogc3RyaW5nO1xuICAgIGludGVudDogc3RyaW5nO1xuICAgIHBheW1lbnRJRDogc3RyaW5nO1xuICAgIHBheW1lbnRUb2tlbjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElQYXlwYWxDbGllbnQge1xuICAgIHNhbmRib3g/OiBzdHJpbmc7XG4gICAgcHJvZHVjdGlvbj86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUGF5UGFsVHJhbnNhY3Rpb24ge1xuICAgIGFtb3VudDogSVBheVBhbEFtb3VudDtcbiAgICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgICBjdXN0b20/OiBzdHJpbmc7XG4gICAgcGF5bWVudF9vcHRpb25zPzogSVBheVBhbFRyYW5zYWN0aW9uUGF5bWVudE9wdGlvbnM7XG4gICAgaW52b2ljZV9udW1iZXI/OiBzdHJpbmc7XG4gICAgc29mdF9kZXNjcmlwdG9yPzogc3RyaW5nO1xuICAgIGl0ZW1fbGlzdD86IElQYXlQYWxUcmFuc2FjdGlvbkl0ZW1MaXN0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElQYXlQYWxUcmFuc2FjdGlvbkl0ZW1MaXN0IHtcbiAgICBpdGVtcz86IElQYXlQYWxUcmFuc2FjdGlvbkl0ZW1bXTtcbiAgICBzaGlwcGluZ19hZGRyZXNzPzogSVBheVBhbFRyYW5zYWN0aW9uU2hpcHBpbmdBZGRyZXNzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElQYXlQYWxUcmFuc2FjdGlvbkl0ZW0ge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBjdXJyZW5jeTogc3RyaW5nO1xuICAgIHByaWNlOiBudW1iZXI7XG4gICAgcXVhbnRpdHk6IG51bWJlcjtcblxuICAgIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICAgIHRheD86IG51bWJlcjtcbiAgICBza3U/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBheVBhbEFtb3VudCB7XG4gICAgdG90YWw6IG51bWJlcjtcbiAgICBjdXJyZW5jeTogc3RyaW5nO1xuICAgIGRldGFpbHM/OiBJUGF5UGFsQW1vdW50RGV0YWlscztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUGF5UGFsVHJhbnNhY3Rpb25TaGlwcGluZ0FkZHJlc3Mge1xuICAgIHJlY2lwaWVudF9uYW1lOiBzdHJpbmc7XG4gICAgbGluZTE6IHN0cmluZztcbiAgICBsaW5lMj86IHN0cmluZztcbiAgICBjaXR5OiBzdHJpbmc7XG4gICAgY291bnRyeV9jb2RlOiBzdHJpbmc7XG4gICAgcG9zdGFsX2NvZGU6IHN0cmluZztcbiAgICBwaG9uZTogc3RyaW5nO1xuICAgIHN0YXRlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBheVBhbEFtb3VudERldGFpbHMge1xuICAgIHN1YnRvdGFsOiBudW1iZXI7XG4gICAgdGF4OiBudW1iZXI7XG4gICAgc2hpcHBpbmc6IG51bWJlcjtcbiAgICBoYW5kbGluZ19mZWU6IG51bWJlcjtcbiAgICBzaGlwcGluZ19kaXNjb3VudDogbnVtYmVyO1xuICAgIGluc3VyYW5jZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElQYXlQYWxUcmFuc2FjdGlvblBheW1lbnRPcHRpb25zIHtcbiAgICBhbGxvd2VkX3BheW1lbnRfbWV0aG9kPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElQYXlQYWxFeHBlcmllbmNlIHtcbiAgICAvKiogSW5kaWNhdGVzIHdoZXRoZXIgUGF5UGFsIGRpc3BsYXlzIHNoaXBwaW5nIGFkZHJlc3MgZmllbGRzIG9uIHRoZSBleHBlcmllbmNlIHBhZ2VzICovXG4gICAgbm9TaGlwcGluZz86IGJvb2xlYW47XG4gICAgLyoqIEEgbGFiZWwgdGhhdCBvdmVycmlkZXMgdGhlIGJ1c2luZXNzIG5hbWUgaW4gdGhlIFBheVBhbCBhY2NvdW50IG9uIHRoZSBQYXlQYWwgcGFnZXMuIE1heCBsZW5ndGg6IDEyNyBjaGFyYWN0ZXJzLiAqL1xuICAgIGJyYW5kTmFtZT86IHN0cmluZztcbiAgICAvKiogVVJMIHRvIHRoZSBsb2dvIGltYWdlIChnaWYsIGpwZywgb3IgcG5nKS4gVGhlIGltYWdlJ3MgbWF4aW11bSB3aWR0aCBpcyAxOTAgcGl4ZWxzIGFuZCBtYXhpbXVtIGhlaWdodCBpcyA2MCBwaXhlbHMuICovXG4gICAgbG9nb0ltYWdlPzogc3RyaW5nO1xuICAgIC8qKiBMb2NhbGUgaW4gd2hpY2ggdG8gZGlzcGxheSBQYXlQYWwgcGFnZSAqL1xuICAgIGxvY2FsZUNvZGU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBheVBhbEJ1dHRvblN0eWxlIHtcbiAgICBsYWJlbD86ICdjaGVja291dCcgfCAncGF5JyB8ICdidXlub3cnIHwgJ3BheXBhbCc7XG4gICAgc2l6ZT86ICdzbWFsbCcgfCAnbWVkaXVtJyB8ICdsYXJnZScgfCAncmVzcG9uc2l2ZSc7XG4gICAgc2hhcGU/OiAncGlsbCcgfCAncmVjdCc7XG4gICAgY29sb3I/OiAnZ29sZCcgfCAnYmx1ZScgfCAnc2lsdmVyJyB8ICdibGFjayc7XG4gICAgbGF5b3V0PzogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJztcbiAgICB0YWdsaW5lPzogZmFsc2U7XG4gICAgZnVuZGluZ2ljb25zPzogYm9vbGVhbjtcbiAgICBicmFuZGluZz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBheVBhbEZ1bmRpbmcge1xuICAgIGFsbG93ZWQ6IFBheVBhbEZ1bmRpbmdbXTtcbiAgICBkaXNhbGxvd2VkOiBQYXlQYWxGdW5kaW5nW107XG59XG5cbiJdLCJuYW1lcyI6WyJTdWJqZWN0IiwiaW50ZXJ2YWwiLCJ0YWtlVW50aWwiLCJtYXAiLCJDb21wb25lbnQiLCJDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSIsIklucHV0IiwiVmlld0NoaWxkIiwi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