ng-beautiful-gauges
Version:
Angular 6+ component wrapper for the canvas-gauges lib written by @Mikhus
444 lines • 35.1 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
/*!
* The MIT License (MIT)
*
* Copyright (c) 2017 Vlad Martynenko <vladimir.martynenko.work@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import { ViewChild, Input, ElementRef } from '@angular/core';
import * as CanvasGauges from 'canvas-gauges';
import * as Rx from 'rx-dom-html';
/**
* Base gauge component for the Gauges rendering
* T - Type of the Gauge to be rendered (Currently RadialGauge, LinearGauge from the original library)
* T2 - Type of config options used by the particular gauge (RadialGaugeOptions, LinearGaugeOptions)
* @abstract
* @template T, T2
*/
var BaseGauge = /** @class */ (function () {
/**
*
* @param el - reference to the element of the whole component, used to scrape options declared on the component itself
* @param zone - required to redraw gauge outside of Angular, due to animation lags caused by the ovewritten function of the ngZone
*/
function BaseGauge(el, zone) {
this.el = el;
this.zone = zone;
/**
* Flag indicating that OnViewInit life-cycle has completed
*/
this.isInited = false;
}
Object.defineProperty(BaseGauge.prototype, "options", {
/**
* Returns gauges properties as an options object.
* Option properties consist of the attribute-based properties and those
* explicitly set.
* @returns <T2>
*/
get: /**
* Returns gauges properties as an options object.
* Option properties consist of the attribute-based properties and those
* explicitly set.
* @return {?} <T2>
*/
function () {
var e_1, _a;
/** @type {?} */
var options = (/** @type {?} */ ({}));
options.renderTo = this.canvas.nativeElement;
try {
// Map attribute-based options onto options.
// Requries converting kebab style attribute names to camelCase property names
for (var _b = tslib_1.__values(this.el.nativeElement.attributes), _c = _b.next(); !_c.done; _c = _b.next()) {
var attr = _c.value;
/** @type {?} */
var prop = attributeName2PropertyName(attr.name);
options[prop] = CanvasGauges.DomObserver.parse(attr.value);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
// merge preOptons with attribute-based properties
// tslint:disable-next-line:forin
for (var prop in this.preInitOptions) {
options[prop] = this.preInitOptions[prop];
}
// clear the preInitOptions as they have already been merged
// with the attribute-based properties
if (this.isInited) {
this.preInitOptions = null;
}
return options;
},
/**
* Assign gauge options at anytime in the lifecycle.
* @param newOptions - assign the style and size properties
*/
set: /**
* Assign gauge options at anytime in the lifecycle.
* @param {?} newOptions - assign the style and size properties
* @return {?}
*/
function (newOptions) {
// cache newOptions as preInitOptions until gauge is ready
if (!this.isInited) {
this.preInitOptions = newOptions;
return;
}
this.update(newOptions);
},
enumerable: true,
configurable: true
});
Object.defineProperty(BaseGauge.prototype, "value", {
/**
* Assign the value of the gauge visual indicator such as a needle or pointer
* @param newValue the guage new value
*/
set: /**
* Assign the value of the gauge visual indicator such as a needle or pointer
* @param {?} newValue the guage new value
* @return {?}
*/
function (newValue) {
var _this = this;
// case new gauge value as preInitValue until the gauge is ready
if (!this.isInited) {
this.preInitValue = newValue;
return;
}
this.zone.runOutsideAngular((/**
* @return {?}
*/
function () {
_this.gauge.value = newValue;
}));
},
enumerable: true,
configurable: true
});
/**
* Update the gauge options. Do not use until after OnViewInit() before using.
*
* Special implementation note - options.properties are maintained as
* attribute name->value on this component's elementRef. Thus this method
* maps each newOptions property onto the property's corresponding attribute.
* The attribute update triggers a DOM mutation event which "this" listens for.
* See #listenForDOMEvents()
*
* @param newOptions - the options to update the gauge
*/
/**
* Update the gauge options. Do not use until after OnViewInit() before using.
*
* Special implementation note - options.properties are maintained as
* attribute name->value on this component's elementRef. Thus this method
* maps each newOptions property onto the property's corresponding attribute.
* The attribute update triggers a DOM mutation event which "this" listens for.
* See #listenForDOMEvents()
*
* @param {?} newOptions - the options to update the gauge
* @return {?}
*/
BaseGauge.prototype.update = /**
* Update the gauge options. Do not use until after OnViewInit() before using.
*
* Special implementation note - options.properties are maintained as
* attribute name->value on this component's elementRef. Thus this method
* maps each newOptions property onto the property's corresponding attribute.
* The attribute update triggers a DOM mutation event which "this" listens for.
* See #listenForDOMEvents()
*
* @param {?} newOptions - the options to update the gauge
* @return {?}
*/
function (newOptions) {
// map all options onto this element's attributes
// Then attribute changes will be detected and pushed to the gauge.update()
if (!newOptions) {
return;
}
// tslint:disable-next-line:forin
for (var prop in newOptions) {
/** @type {?} */
var val = newOptions[prop].toString();
if (prop === 'value') {
// short circuit the value property update by calling
// the gauge.value api directly for efficient animated update
this.value = CanvasGauges.DomObserver.parse(val);
}
else {
/** @type {?} */
var attrName = toKebabCase(prop);
this.el.nativeElement.setAttribute(attrName, val);
}
}
};
/**
* Perform gauge initialization.
* Subclasses that override this method must this super version
* for proper operation.
*/
/**
* Perform gauge initialization.
* Subclasses that override this method must this super version
* for proper operation.
* @return {?}
*/
BaseGauge.prototype.ngAfterViewInit = /**
* Perform gauge initialization.
* Subclasses that override this method must this super version
* for proper operation.
* @return {?}
*/
function () {
// initial update of gauge properties
this.initGauge();
this.listenForDOMEvents();
this.isInited = true;
};
/**
* Listen for attribute-change events that are created when updating
* the options of this gauge.
*/
/**
* Listen for attribute-change events that are created when updating
* the options of this gauge.
* @protected
* @return {?}
*/
BaseGauge.prototype.listenForDOMEvents = /**
* Listen for attribute-change events that are created when updating
* the options of this gauge.
* @protected
* @return {?}
*/
function () {
var _this = this;
// Listen to gauge element for attribute changes
// Convert all changed attribtues into a GenericOptions or subclass
// Update the gauge with the new options.
this.domListener =
Rx.DOM.fromMutationObserver(this.el.nativeElement, { attributes: true }).
subscribe((/**
* @param {?} changes
* @return {?}
*/
function (changes) {
/** @type {?} */
var newOptions = (/** @type {?} */ ({}));
changes.forEach((/**
* @param {?} change
* @return {?}
*/
function (change) {
if ('attributes' === change.type) {
// console.log('DOM, change', change.attributeName);
newOptions[attributeName2PropertyName(change.attributeName)] =
CanvasGauges.DomObserver.parse(_this.el.nativeElement.getAttribute(change.attributeName));
}
}));
_this.basicUpdate(newOptions);
}));
};
/**
* Discontinue listening for attribute change events.
*/
/**
* Discontinue listening for attribute change events.
* @protected
* @return {?}
*/
BaseGauge.prototype.stopListeningForDOMEvents = /**
* Discontinue listening for attribute change events.
* @protected
* @return {?}
*/
function () {
if (this.domListener) {
this.domListener.disconnect();
this.domListener = null;
}
};
/**
* Initalize the gauge with all options defined by attributes and
* parent component options.
*/
/**
* Initalize the gauge with all options defined by attributes and
* parent component options.
* @protected
* @return {?}
*/
BaseGauge.prototype.initGauge = /**
* Initalize the gauge with all options defined by attributes and
* parent component options.
* @protected
* @return {?}
*/
function () {
/** @type {?} */
var options = this.options;
if (this.preInitValue) {
options.value = this.preInitValue;
}
// init options.renderTo if needed
if (!options.hasOwnProperty('renderTo') || !options.renderTo) {
options.renderTo = this.canvas.nativeElement;
}
this.basicUpdate(options);
};
/**
* Performs the gauge update using the current options
* @param options The options for the guage
*/
/**
* Performs the gauge update using the current options
* @protected
* @param {?} options The options for the guage
* @return {?}
*/
BaseGauge.prototype.basicUpdate = /**
* Performs the gauge update using the current options
* @protected
* @param {?} options The options for the guage
* @return {?}
*/
function (options) {
// treat the value property special and update it through the
// value getter.
if (typeof options.value === 'number') {
// use gauge api directly for most efficient update method
this.value = options.value;
// filter value property from options to avoid redundant
// processing by gauge
delete options.value;
}
// do nothing if no option properties to update
if (Object.keys(options).length) {
this.gauge.update(options);
}
};
BaseGauge.propDecorators = {
canvas: [{ type: ViewChild, args: ['gauge',] }],
options: [{ type: Input }],
value: [{ type: Input }]
};
return BaseGauge;
}());
export { BaseGauge };
if (false) {
/**
* Canvas element on the template used by the library to draw gauge element
* @type {?}
* @protected
*/
BaseGauge.prototype.canvas;
/**
* A gauge instance responsible for rendering and updates on the canvas.
* Subclasses should initialize in their ngOnInit implementation.
* @type {?}
* @protected
*/
BaseGauge.prototype.gauge;
/**
* Flag indicating that OnViewInit life-cycle has completed
* @type {?}
* @private
*/
BaseGauge.prototype.isInited;
/**
* value property of gauge prior to component view initialization
* @type {?}
* @private
*/
BaseGauge.prototype.preInitValue;
/**
* options property of gauge prior to component view initialization
* @type {?}
* @private
*/
BaseGauge.prototype.preInitOptions;
/**
* Listen for attribute changes, i.e., options properties that are stored
* as attributes on this ElementRef
* @type {?}
* @private
*/
BaseGauge.prototype.domListener;
/**
* @type {?}
* @private
*/
BaseGauge.prototype.el;
/** @type {?} */
BaseGauge.prototype.zone;
/**
* Subclasses should instantiate the CanvasGauge object in the child component
* @abstract
* @return {?}
*/
BaseGauge.prototype.ngOnInit = function () { };
}
// String utils
/** @type {?} */
var attributeName2PropertyName = (/**
* @param {?} attrName
* @return {?}
*/
function (attrName) { return toCamelCase(attrName); });
var ɵ0 = attributeName2PropertyName;
/** @type {?} */
var propertyName2AttrName = (/**
* @param {?} propName
* @return {?}
*/
function (propName) { return toKebabCase(propName); });
var ɵ1 = propertyName2AttrName;
/** @type {?} */
var toCamelCase = (/**
* @param {?} str
* @return {?}
*/
function (str) { return str.replace(/(\-\w)/g, (/**
* @param {?} m
* @return {?}
*/
function (m) { return m[1].toUpperCase(); })); });
var ɵ2 = toCamelCase;
/** @type {?} */
var toKebabCase = (/**
* @param {?} str
* @return {?}
*/
function (str) { return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase(); });
var ɵ3 = toKebabCase;
export { ɵ0, ɵ1, ɵ2, ɵ3 };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1nYXVnZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLWJlYXV0aWZ1bC1nYXVnZXMvIiwic291cmNlcyI6WyJsaWIvYmFzZS1nYXVnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBd0JBLE9BQU8sRUFBYSxTQUFTLEVBQUUsS0FBSyxFQUFVLFVBQVUsRUFBeUIsTUFBTSxlQUFlLENBQUM7QUFDdkcsT0FBTyxLQUFLLFlBQVksTUFBTSxlQUFlLENBQUM7QUFDOUMsT0FBTyxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7Ozs7Ozs7O0FBT2xDO0lBdUNJOzs7O09BSUc7SUFDSCxtQkFBb0IsRUFBYyxFQUFTLElBQVk7UUFBbkMsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUFTLFNBQUksR0FBSixJQUFJLENBQVE7Ozs7UUF6Qi9DLGFBQVEsR0FBRyxLQUFLLENBQUM7SUEwQnpCLENBQUM7SUFlRCxzQkFBVyw4QkFBTztRQU5sQjs7Ozs7V0FLRzs7Ozs7OztRQUNIOzs7Z0JBRVUsT0FBTyxHQUFHLG1CQUFBLEVBQUUsRUFBTTtZQUN4QixPQUFPLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDOztnQkFFN0MsNENBQTRDO2dCQUM1Qyw4RUFBOEU7Z0JBQzlFLEtBQW1CLElBQUEsS0FBQSxpQkFBQSxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUEsZ0JBQUEsNEJBQUU7b0JBQWhELElBQU0sSUFBSSxXQUFBOzt3QkFDTCxJQUFJLEdBQUcsMEJBQTBCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztvQkFDbEQsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLFlBQVksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDOUQ7Ozs7Ozs7OztZQUVELGtEQUFrRDtZQUNsRCxpQ0FBaUM7WUFDakMsS0FBSyxJQUFNLElB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QUF3RCxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBUaGUgTUlUIExpY2Vuc2UgKE1JVClcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTcgVmxhZCBNYXJ0eW5lbmtvIDx2bGFkaW1pci5tYXJ0eW5lbmtvLndvcmtAZ21haWwuY29tPlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuICogU09GVFdBUkUuXG4gKi9cblxuaW1wb3J0IHsgQ29tcG9uZW50LCBWaWV3Q2hpbGQsIElucHV0LCBOZ1pvbmUsIEVsZW1lbnRSZWYsIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgQ2FudmFzR2F1Z2VzIGZyb20gJ2NhbnZhcy1nYXVnZXMnO1xuaW1wb3J0ICogYXMgUnggZnJvbSAncngtZG9tLWh0bWwnO1xuXG4vKipcbiAqIEJhc2UgZ2F1Z2UgY29tcG9uZW50IGZvciB0aGUgR2F1Z2VzIHJlbmRlcmluZ1xuICogVCAtIFR5cGUgb2YgdGhlIEdhdWdlIHRvIGJlIHJlbmRlcmVkIChDdXJyZW50bHkgUmFkaWFsR2F1Z2UsIExpbmVhckdhdWdlIGZyb20gdGhlIG9yaWdpbmFsIGxpYnJhcnkpXG4gKiBUMiAtIFR5cGUgb2YgY29uZmlnIG9wdGlvbnMgdXNlZCBieSB0aGUgcGFydGljdWxhciBnYXVnZSAoUmFkaWFsR2F1Z2VPcHRpb25zLCBMaW5lYXJHYXVnZU9wdGlvbnMpXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlR2F1Z2U8VCBleHRlbmRzIENhbnZhc0dhdWdlcy5CYXNlR2F1Z2UsIFQyIGV4dGVuZHMgQ2FudmFzR2F1Z2VzLkdlbmVyaWNPcHRpb25zPlxuICAgIGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0IHtcblxuICAgIC8qKlxuICAgICAqIENhbnZhcyBlbGVtZW50IG9uIHRoZSB0ZW1wbGF0ZSB1c2VkIGJ5IHRoZSBsaWJyYXJ5IHRvIGRyYXcgZ2F1Z2UgZWxlbWVudFxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ2dhdWdlJylcbiAgICBwcm90ZWN0ZWQgY2FudmFzOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQSBnYXVnZSBpbnN0YW5jZSByZXNwb25zaWJsZSBmb3IgcmVuZGVyaW5nIGFuZCB1cGRhdGVzIG9uIHRoZSBjYW52YXMuXG4gICAgICogU3ViY2xhc3NlcyBzaG91bGQgaW5pdGlhbGl6ZSBpbiB0aGVpciBuZ09uSW5pdCBpbXBsZW1lbnRhdGlvbi5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgZ2F1Z2U6IFQ7XG5cblxuICAgIC8qKlxuICAgICAqIEZsYWcgaW5kaWNhdGluZyB0aGF0IE9uVmlld0luaXQgbGlmZS1jeWNsZSBoYXMgY29tcGxldGVkXG4gICAgICovXG4gICAgcHJpdmF0ZSBpc0luaXRlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogdmFsdWUgcHJvcGVydHkgb2YgZ2F1Z2UgcHJpb3IgdG8gY29tcG9uZW50IHZpZXcgaW5pdGlhbGl6YXRpb25cbiAgICAgKi9cbiAgICBwcml2YXRlIHByZUluaXRWYWx1ZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogb3B0aW9ucyBwcm9wZXJ0eSBvZiBnYXVnZSBwcmlvciB0byBjb21wb25lbnQgdmlldyBpbml0aWFsaXphdGlvblxuICAgICAqL1xuICAgIHByaXZhdGUgcHJlSW5pdE9wdGlvbnM6IFQyO1xuXG5cbiAgICAvKipcbiAgICAgKiBMaXN0ZW4gZm9yIGF0dHJpYnV0ZSBjaGFuZ2VzLCBpLmUuLCBvcHRpb25zIHByb3BlcnRpZXMgdGhhdCBhcmUgc3RvcmVkXG4gICAgICogYXMgYXR0cmlidXRlcyBvbiB0aGlzIEVsZW1lbnRSZWZcbiAgICAgKi9cbiAgICBwcml2YXRlIGRvbUxpc3RlbmVyOiBNdXRhdGlvbk9ic2VydmVyO1xuXG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbCAtIHJlZmVyZW5jZSB0byB0aGUgZWxlbWVudCBvZiB0aGUgd2hvbGUgY29tcG9uZW50LCB1c2VkIHRvIHNjcmFwZSBvcHRpb25zIGRlY2xhcmVkIG9uIHRoZSBjb21wb25lbnQgaXRzZWxmXG4gICAgICogQHBhcmFtIHpvbmUgLSByZXF1aXJlZCB0byByZWRyYXcgZ2F1Z2Ugb3V0c2lkZSBvZiBBbmd1bGFyLCBkdWUgdG8gYW5pbWF0aW9uIGxhZ3MgY2F1c2VkIGJ5IHRoZSBvdmV3cml0dGVuIGZ1bmN0aW9uIG9mIHRoZSBuZ1pvbmVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsOiBFbGVtZW50UmVmLCBwdWJsaWMgem9uZTogTmdab25lKSB7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdWJjbGFzc2VzIHNob3VsZCBpbnN0YW50aWF0ZSB0aGUgQ2FudmFzR2F1Z2Ugb2JqZWN0IGluIHRoZSBjaGlsZCBjb21wb25lbnRcbiAgICAgKi9cbiAgICBhYnN0cmFjdCBuZ09uSW5pdCgpOiB2b2lkO1xuXG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGdhdWdlcyBwcm9wZXJ0aWVzIGFzIGFuIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIE9wdGlvbiBwcm9wZXJ0aWVzIGNvbnNpc3Qgb2YgdGhlIGF0dHJpYnV0ZS1iYXNlZCBwcm9wZXJ0aWVzIGFuZCB0aG9zZVxuICAgICAqIGV4cGxpY2l0bHkgc2V0LlxuICAgICAqIEByZXR1cm5zIDxUMj5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IG9wdGlvbnMoKTogVDIge1xuXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7fSBhcyBUMjtcbiAgICAgICAgb3B0aW9ucy5yZW5kZXJUbyA9IHRoaXMuY2FudmFzLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICAgICAgLy8gTWFwIGF0dHJpYnV0ZS1iYXNlZCBvcHRpb25zIG9udG8gb3B0aW9ucy5cbiAgICAgICAgLy8gUmVxdXJpZXMgY29udmVydGluZyBrZWJhYiBzdHlsZSBhdHRyaWJ1dGUgbmFtZXMgdG8gY2FtZWxDYXNlIHByb3BlcnR5IG5hbWVzXG4gICAgICAgIGZvciAoY29uc3QgYXR0ciBvZiB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuYXR0cmlidXRlcykge1xuICAgICAgICAgICAgY29uc3QgcHJvcCA9IGF0dHJpYnV0ZU5hbWUyUHJvcGVydHlOYW1lKGF0dHIubmFtZSk7XG4gICAgICAgICAgICBvcHRpb25zW3Byb3BdID0gQ2FudmFzR2F1Z2VzLkRvbU9ic2VydmVyLnBhcnNlKGF0dHIudmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbWVyZ2UgcHJlT3B0b25zIHdpdGggYXR0cmlidXRlLWJhc2VkIHByb3BlcnRpZXNcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmZvcmluXG4gICAgICAgIGZvciAoY29uc3QgcHJvcCBpbiB0aGlzLnByZUluaXRPcHRpb25zKSB7XG4gICAgICAgICAgICBvcHRpb25zW3Byb3BdID0gdGhpcy5wcmVJbml0T3B0aW9uc1twcm9wXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNsZWFyIHRoZSBwcmVJbml0T3B0aW9ucyBhcyB0aGV5IGhhdmUgYWxyZWFkeSBiZWVuIG1lcmdlZFxuICAgICAgICAvLyB3aXRoIHRoZSBhdHRyaWJ1dGUtYmFzZWQgcHJvcGVydGllc1xuICAgICAgICBpZiAodGhpcy5pc0luaXRlZCkge1xuICAgICAgICAgICAgdGhpcy5wcmVJbml0T3B0aW9ucyA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb3B0aW9ucztcbiAgICB9XG5cbiAgICBcbiAgICAvKipcbiAgICAgKiBBc3NpZ24gZ2F1Z2Ugb3B0aW9ucyBhdCBhbnl0aW1lIGluIHRoZSBsaWZlY3ljbGUuXG4gICAgICogQHBhcmFtIG5ld09wdGlvbnMgLSBhc3NpZ24gdGhlIHN0eWxlIGFuZCBzaXplIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgb3B0aW9ucyhuZXdPcHRpb25zOiBUMikge1xuXG4gICAgICAgIC8vIGNhY2hlIG5ld09wdGlvbnMgYXMgcHJlSW5pdE9wdGlvbnMgdW50aWwgZ2F1Z2UgaXMgcmVhZHlcbiAgICAgICAgaWYgKCF0aGlzLmlzSW5pdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnByZUluaXRPcHRpb25zID0gbmV3T3B0aW9ucztcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudXBkYXRlKG5ld09wdGlvbnMpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogQXNzaWduIHRoZSB2YWx1ZSBvZiB0aGUgZ2F1Z2UgdmlzdWFsIGluZGljYXRvciBzdWNoIGFzIGEgbmVlZGxlIG9yIHBvaW50ZXJcbiAgICAgKiBAcGFyYW0gbmV3VmFsdWUgIHRoZSBndWFnZSBuZXcgdmFsdWVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgdmFsdWUobmV3VmFsdWU6IG51bWJlcikge1xuXG4gICAgICAgIC8vIGNhc2UgbmV3IGdhdWdlIHZhbHVlIGFzIHByZUluaXRWYWx1ZSB1bnRpbCB0aGUgZ2F1Z2UgaXMgcmVhZHlcbiAgICAgICAgaWYgKCF0aGlzLmlzSW5pdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnByZUluaXRWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ2F1Z2UudmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGdhdWdlIG9wdGlvbnMuIERvIG5vdCB1c2UgdW50aWwgYWZ0ZXIgT25WaWV3SW5pdCgpIGJlZm9yZSB1c2luZy5cbiAgICAgKlxuICAgICAqIFNwZWNpYWwgaW1wbGVtZW50YXRpb24gbm90ZSAtIG9wdGlvbnMucHJvcGVydGllcyBhcmUgbWFpbnRhaW5lZCBhc1xuICAgICAqIGF0dHJpYnV0ZSBuYW1lLT52YWx1ZSBvbiB0aGlzIGNvbXBvbmVudCdzIGVsZW1lbnRSZWYuICBUaHVzIHRoaXMgbWV0aG9kXG4gICAgICogbWFwcyBlYWNoIG5ld09wdGlvbnMgcHJvcGVydHkgb250byB0aGUgcHJvcGVydHkncyBjb3JyZXNwb25kaW5nIGF0dHJpYnV0ZS5cbiAgICAgKiBUaGUgYXR0cmlidXRlIHVwZGF0ZSB0cmlnZ2VycyBhIERPTSBtdXRhdGlvbiBldmVudCB3aGljaCAgXCJ0aGlzXCIgbGlzdGVucyBmb3IuXG4gICAgICogU2VlICNsaXN0ZW5Gb3JET01FdmVudHMoKVxuICAgICAqXG4gICAgICogQHBhcmFtIG5ld09wdGlvbnMgIC0gdGhlIG9wdGlvbnMgdG8gdXBkYXRlIHRoZSBnYXVnZVxuICAgICAqL1xuICAgIHB1YmxpYyB1cGRhdGUobmV3T3B0aW9uczogVDIgfCB7fSkge1xuXG4gICAgICAgIC8vIG1hcCBhbGwgb3B0aW9ucyBvbnRvIHRoaXMgZWxlbWVudCdzIGF0dHJpYnV0ZXNcbiAgICAgICAgLy8gVGhlbiBhdHRyaWJ1dGUgY2hhbmdlcyB3aWxsIGJlIGRldGVjdGVkIGFuZCBwdXNoZWQgdG8gdGhlIGdhdWdlLnVwZGF0ZSgpXG4gICAgICAgIGlmICghbmV3T3B0aW9ucykgeyByZXR1cm47IH1cblxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Zm9yaW5cbiAgICAgICAgZm9yIChjb25zdCBwcm9wIGluIG5ld09wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbCA9IG5ld09wdGlvbnNbcHJvcF0udG9TdHJpbmcoKTtcblxuICAgICAgICAgICAgaWYgKHByb3AgPT09ICd2YWx1ZScpIHtcbiAgICAgICAgICAgICAgICAvLyBzaG9ydCBjaXJjdWl0IHRoZSB2YWx1ZSBwcm9wZXJ0eSB1cGRhdGUgYnkgY2FsbGluZ1xuICAgICAgICAgICAgICAgIC8vIHRoZSBnYXVnZS52YWx1ZSBhcGkgZGlyZWN0bHkgZm9yIGVmZmljaWVudCBhbmltYXRlZCB1cGRhdGVcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gQ2FudmFzR2F1Z2VzLkRvbU9ic2VydmVyLnBhcnNlKHZhbCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGF0dHJOYW1lID0gdG9LZWJhYkNhc2UocHJvcCk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgdmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybSBnYXVnZSBpbml0aWFsaXphdGlvbi5cbiAgICAgKiBTdWJjbGFzc2VzIHRoYXQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgbXVzdCB0aGlzIHN1cGVyIHZlcnNpb25cbiAgICAgKiBmb3IgcHJvcGVyIG9wZXJhdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xuXG4gICAgICAgIC8vIGluaXRpYWwgdXBkYXRlIG9mIGdhdWdlIHByb3BlcnRpZXNcbiAgICAgICAgdGhpcy5pbml0R2F1Z2UoKTtcblxuICAgICAgICB0aGlzLmxpc3RlbkZvckRPTUV2ZW50cygpO1xuXG4gICAgICAgIHRoaXMuaXNJbml0ZWQgPSB0cnVlO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIGZvciBhdHRyaWJ1dGUtY2hhbmdlIGV2ZW50cyB0aGF0IGFyZSBjcmVhdGVkIHdoZW4gdXBkYXRpbmdcbiAgICAgKiB0aGUgb3B0aW9ucyBvZiB0aGlzIGdhdWdlLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBsaXN0ZW5Gb3JET01FdmVudHMoKSB7XG4gICAgICAgIC8vIExpc3RlbiB0byBnYXVnZSBlbGVtZW50IGZvciBhdHRyaWJ1dGUgY2hhbmdlc1xuICAgICAgICAvLyBDb252ZXJ0IGFsbCBjaGFuZ2VkIGF0dHJpYnR1ZXMgaW50byBhIEdlbmVyaWNPcHRpb25zIG9yIHN1YmNsYXNzXG4gICAgICAgIC8vIFVwZGF0ZSB0aGUgZ2F1Z2Ugd2l0aCB0aGUgbmV3IG9wdGlvbnMuXG4gICAgICAgIHRoaXMuZG9tTGlzdGVuZXIgPVxuICAgICAgICAgICAgUnguRE9NLmZyb21NdXRhdGlvbk9ic2VydmVyKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgeyBhdHRyaWJ1dGVzOiB0cnVlIH0pLlxuICAgICAgICAgICAgICAgIHN1YnNjcmliZShjaGFuZ2VzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3T3B0aW9ucyA9IHt9IGFzIFQyO1xuICAgICAgICAgICAgICAgICAgICBjaGFuZ2VzLmZvckVhY2goY2hhbmdlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgnYXR0cmlidXRlcycgPT09IGNoYW5nZS50eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ0RPTSwgY2hhbmdlJywgY2hhbmdlLmF0dHJpYnV0ZU5hbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld09wdGlvbnNbYXR0cmlidXRlTmFtZTJQcm9wZXJ0eU5hbWUoY2hhbmdlLmF0dHJpYnV0ZU5hbWUpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENhbnZhc0dhdWdlcy5Eb21PYnNlcnZlci5wYXJzZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5nZXRBdHRyaWJ1dGUoY2hhbmdlLmF0dHJpYnV0ZU5hbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5iYXNpY1VwZGF0ZShuZXdPcHRpb25zKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIERpc2NvbnRpbnVlIGxpc3RlbmluZyBmb3IgYXR0cmlidXRlIGNoYW5nZSBldmVudHMuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHN0b3BMaXN0ZW5pbmdGb3JET01FdmVudHMoKSB7XG4gICAgICAgIGlmICh0aGlzLmRvbUxpc3RlbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmRvbUxpc3RlbmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIHRoaXMuZG9tTGlzdGVuZXIgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBJbml0YWxpemUgdGhlIGdhdWdlIHdpdGggYWxsIG9wdGlvbnMgZGVmaW5lZCBieSBhdHRyaWJ1dGVzIGFuZFxuICAgICAqIHBhcmVudCBjb21wb25lbnQgb3B0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgaW5pdEdhdWdlKCkge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAodGhpcy5wcmVJbml0VmFsdWUpIHtcbiAgICAgICAgICAgIG9wdGlvbnMudmFsdWUgPSB0aGlzLnByZUluaXRWYWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGluaXQgb3B0aW9ucy5yZW5kZXJUbyBpZiBuZWVkZWRcbiAgICAgICAgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdyZW5kZXJUbycpIHx8ICFvcHRpb25zLnJlbmRlclRvKSB7XG4gICAgICAgICAgICBvcHRpb25zLnJlbmRlclRvID0gdGhpcy5jYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYmFzaWNVcGRhdGUob3B0aW9ucyk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyB0aGUgZ2F1Z2UgdXBkYXRlIHVzaW5nIHRoZSBjdXJyZW50IG9wdGlvbnNcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAgVGhlIG9wdGlvbnMgZm9yIHRoZSBndWFnZVxuICAgICAqL1xuICAgIHByb3RlY3RlZCBiYXNpY1VwZGF0ZShvcHRpb25zOiBUMikge1xuXG4gICAgICAgIC8vIHRyZWF0IHRoZSB2YWx1ZSBwcm9wZXJ0eSBzcGVjaWFsIGFuZCB1cGRhdGUgaXQgdGhyb3VnaCB0aGVcbiAgICAgICAgLy8gdmFsdWUgZ2V0dGVyLlxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMudmFsdWUgPT09ICdudW1iZXInKSB7XG5cbiAgICAgICAgICAgIC8vIHVzZSBnYXVnZSBhcGkgZGlyZWN0bHkgZm9yIG1vc3QgZWZmaWNpZW50IHVwZGF0ZSBtZXRob2RcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBvcHRpb25zLnZhbHVlO1xuXG4gICAgICAgICAgICAvLyBmaWx0ZXIgdmFsdWUgcHJvcGVydHkgZnJvbSBvcHRpb25zIHRvIGF2b2lkIHJlZHVuZGFudFxuICAgICAgICAgICAgLy8gcHJvY2Vzc2luZyBieSBnYXVnZVxuICAgICAgICAgICAgZGVsZXRlIG9wdGlvbnMudmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkbyBub3RoaW5nIGlmIG5vIG9wdGlvbiBwcm9wZXJ0aWVzIHRvIHVwZGF0ZVxuICAgICAgICBpZiAoT2JqZWN0LmtleXMob3B0aW9ucykubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmdhdWdlLnVwZGF0ZShvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxufVxuXG4vLyBTdHJpbmcgdXRpbHNcbmNvbnN0IGF0dHJpYnV0ZU5hbWUyUHJvcGVydHlOYW1lID0gKGF0dHJOYW1lOiBzdHJpbmcpID0+IHRvQ2FtZWxDYXNlKGF0dHJOYW1lKTtcblxuY29uc3QgcHJvcGVydHlOYW1lMkF0dHJOYW1lID0gKHByb3BOYW1lOiBzdHJpbmcpID0+IHRvS2ViYWJDYXNlKHByb3BOYW1lKTtcblxuY29uc3QgdG9DYW1lbENhc2UgPSAoc3RyKSA9PiBzdHIucmVwbGFjZSgvKFxcLVxcdykvZywgKG0pID0+IG1bMV0udG9VcHBlckNhc2UoKSk7XG5cbmNvbnN0IHRvS2ViYWJDYXNlID0gKHN0cikgPT4gc3RyLnJlcGxhY2UoLyhbYS16MC05XSkoW0EtWl0pL2csICckMS0kMicpLnRvTG93ZXJDYXNlKCk7XG5cblxuIl19