UNPKG

ng-canvas-gauges

Version:

Angular 6+ component wrapper for the canvas-gauges lib written by @Mikhus

437 lines 34.8 kB
/** * @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'; // String utils /** @type {?} */ var toCamelCase = (/** * @param {?} str * @return {?} */ function (str) { return str.replace(/(\-\w)/g, (/** * @param {?} matches * @return {?} */ function (matches) { return matches[1].toUpperCase(); })); }); var ɵ0 = toCamelCase; /** @type {?} */ var toKebabCase = (/** * @param {?} str * @return {?} */ function (str) { return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase(); }); var ɵ1 = toKebabCase; /** @type {?} */ var attributeName2PropertyName = (/** * @param {?} attrName * @return {?} */ function (attrName) { return toCamelCase(attrName); }); var ɵ2 = attributeName2PropertyName; /** * 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 () { }; } export { ɵ0, ɵ1, ɵ2 }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1nYXVnZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLWNhbnZhcy1nYXVnZXMvIiwic291cmNlcyI6WyJsaWIvYmFzZS1nYXVnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBd0JBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLFVBQVUsRUFBeUIsTUFBTSxlQUFlLENBQUM7QUFDNUYsT0FBTyxLQUFLLFlBQVksTUFBTSxlQUFlLENBQUM7QUFDOUMsT0FBTyxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7OztJQUs1QixXQUFXOzs7O0FBQUcsVUFBQyxHQUFXLElBQUssT0FBQSxHQUFHLENBQUMsT0FBTyxDQUFDLFNBQVM7Ozs7QUFBRSxVQUFDLE9BQU8sSUFBSyxPQUFBLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBeEIsQ0FBd0IsRUFBQyxFQUE3RCxDQUE2RCxDQUFBOzs7SUFFNUYsV0FBVzs7OztBQUFHLFVBQUMsR0FBVyxJQUFLLE9BQUEsR0FBRyxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsRUFBRSxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBeEQsQ0FBd0QsQ0FBQTs7O0lBRXZGLDBCQUEwQjs7OztBQUFHLFVBQUMsUUFBZ0IsSUFBSyxPQUFBLFdBQVcsQ0FBQyxRQUFRLENBQUMsRUFBckIsQ0FBcUIsQ0FBQTs7Ozs7Ozs7O0FBVTlFO0lBdUNJOzs7O09BSUc7SUFDSCxtQkFBb0IsRUFBYyxFQUFTLElBQVk7UUFBbkMsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUFTLFNBQUksR0FBSixJQUFJLENBQVE7Ozs7UUF6Qi9DLGFBQVEsR0FBRyxLQUFLLENBQUM7SUEwQnpCLENBQUM7SUFlRCxzQkFBVyw4QkFBTztRQU5sQjs7Ozs7V0FLRzs7Ozs7OztRQUNIOzs7Z0JBRVUsT0FBTyxHQUFHLG1CQUFBLEVBQUUsRUFBTTtZQUN4QixPQUFPLENBQUMsUUFBUSxHQUFH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a0NBQWtDO1FBQ2xDLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRTtZQUMxRCxPQUFPLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDO1NBQ2hEO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBR0Q7OztPQUdHOzs7Ozs7O0lBQ08sK0JBQVc7Ozs7OztJQUFyQixVQUFzQixPQUFXO1FBRTdCLDZEQUE2RDtRQUM3RCxnQkFBZ0I7UUFDaEIsSUFBSSxPQUFPLE9BQU8sQ0FBQyxLQUFLLEtBQUssUUFBUSxFQUFFO1lBRW5DLDBEQUEwRDtZQUMxRCxJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7WUFFM0Isd0RBQXdEO1lBQ3hELHNCQUFzQjtZQUN0QixPQUFPLE9BQU8sQ0FBQyxLQUFLLENBQUM7U0FDeEI7UUFFRCwrQ0FBK0M7UUFDL0MsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRTtZQUM3QixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUM5QjtJQUNMLENBQUM7O3lCQXJQQSxTQUFTLFNBQUMsT0FBTzswQkFzRmpCLEtBQUs7d0JBaUJMLEtBQUs7O0lBZ0pWLGdCQUFDO0NBQUEsQUE3UEQsSUE2UEM7U0E3UHFCLFNBQVM7Ozs7Ozs7SUFNM0IsMkJBQzZCOzs7Ozs7O0lBTTdCLDBCQUFtQjs7Ozs7O0lBTW5CLDZCQUF5Qjs7Ozs7O0lBS3pCLGlDQUE2Qjs7Ozs7O0lBSzdCLG1DQUEyQjs7Ozs7OztJQU8zQixnQ0FBc0M7Ozs7O0lBUTFCLHVCQUFzQjs7SUFBRSx5QkFBbUI7Ozs7OztJQU92RCwrQ0FBMEIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIFRoZSBNSVQgTGljZW5zZSAoTUlUKVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNyBWbGFkIE1hcnR5bmVua28gPHZsYWRpbWlyLm1hcnR5bmVua28ud29ya0BnbWFpbC5jb20+XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4gKiBTT0ZUV0FSRS5cbiAqL1xuXG5pbXBvcnQgeyBWaWV3Q2hpbGQsIElucHV0LCBOZ1pvbmUsIEVsZW1lbnRSZWYsIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgQ2FudmFzR2F1Z2VzIGZyb20gJ2NhbnZhcy1nYXVnZXMnO1xuaW1wb3J0ICogYXMgUnggZnJvbSAncngtZG9tLWh0bWwnO1xuXG5cblxuLy8gU3RyaW5nIHV0aWxzXG5jb25zdCB0b0NhbWVsQ2FzZSA9IChzdHI6IHN0cmluZykgPT4gc3RyLnJlcGxhY2UoLyhcXC1cXHcpL2csIChtYXRjaGVzKSA9PiBtYXRjaGVzWzFdLnRvVXBwZXJDYXNlKCkpO1xuXG5jb25zdCB0b0tlYmFiQ2FzZSA9IChzdHI6IHN0cmluZykgPT4gc3RyLnJlcGxhY2UoLyhbYS16MC05XSkoW0EtWl0pL2csICckMS0kMicpLnRvTG93ZXJDYXNlKCk7XG5cbmNvbnN0IGF0dHJpYnV0ZU5hbWUyUHJvcGVydHlOYW1lID0gKGF0dHJOYW1lOiBzdHJpbmcpID0+IHRvQ2FtZWxDYXNlKGF0dHJOYW1lKTtcblxuXG5cblxuLyoqXG4gKiBCYXNlIGdhdWdlIGNvbXBvbmVudCBmb3IgdGhlIEdhdWdlcyByZW5kZXJpbmdcbiAqIFQgLSBUeXBlIG9mIHRoZSBHYXVnZSB0byBiZSByZW5kZXJlZCAoQ3VycmVudGx5IFJhZGlhbEdhdWdlLCBMaW5lYXJHYXVnZSBmcm9tIHRoZSBvcmlnaW5hbCBsaWJyYXJ5KVxuICogVDIgLSBUeXBlIG9mIGNvbmZpZyBvcHRpb25zIHVzZWQgYnkgdGhlIHBhcnRpY3VsYXIgZ2F1Z2UgKFJhZGlhbEdhdWdlT3B0aW9ucywgTGluZWFyR2F1Z2VPcHRpb25zKVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZUdhdWdlPFQgZXh0ZW5kcyBDYW52YXNHYXVnZXMuQmFzZUdhdWdlLCBUMiBleHRlbmRzIENhbnZhc0dhdWdlcy5HZW5lcmljT3B0aW9ucz5cbiAgICBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCB7XG5cbiAgICAvKipcbiAgICAgKiBDYW52YXMgZWxlbWVudCBvbiB0aGUgdGVtcGxhdGUgdXNlZCBieSB0aGUgbGlicmFyeSB0byBkcmF3IGdhdWdlIGVsZW1lbnRcbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdnYXVnZScpXG4gICAgcHJvdGVjdGVkIGNhbnZhczogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIEEgZ2F1Z2UgaW5zdGFuY2UgcmVzcG9uc2libGUgZm9yIHJlbmRlcmluZyBhbmQgdXBkYXRlcyBvbiB0aGUgY2FudmFzLlxuICAgICAqIFN1YmNsYXNzZXMgc2hvdWxkIGluaXRpYWxpemUgaW4gdGhlaXIgbmdPbkluaXQgaW1wbGVtZW50YXRpb24uXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGdhdWdlOiBUO1xuXG5cbiAgICAvKipcbiAgICAgKiBGbGFnIGluZGljYXRpbmcgdGhhdCBPblZpZXdJbml0IGxpZmUtY3ljbGUgaGFzIGNvbXBsZXRlZFxuICAgICAqL1xuICAgIHByaXZhdGUgaXNJbml0ZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIHZhbHVlIHByb3BlcnR5IG9mIGdhdWdlIHByaW9yIHRvIGNvbXBvbmVudCB2aWV3IGluaXRpYWxpemF0aW9uXG4gICAgICovXG4gICAgcHJpdmF0ZSBwcmVJbml0VmFsdWU6IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIG9wdGlvbnMgcHJvcGVydHkgb2YgZ2F1Z2UgcHJpb3IgdG8gY29tcG9uZW50IHZpZXcgaW5pdGlhbGl6YXRpb25cbiAgICAgKi9cbiAgICBwcml2YXRlIHByZUluaXRPcHRpb25zOiBUMjtcblxuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIGZvciBhdHRyaWJ1dGUgY2hhbmdlcywgaS5lLiwgb3B0aW9ucyBwcm9wZXJ0aWVzIHRoYXQgYXJlIHN0b3JlZFxuICAgICAqIGFzIGF0dHJpYnV0ZXMgb24gdGhpcyBFbGVtZW50UmVmXG4gICAgICovXG4gICAgcHJpdmF0ZSBkb21MaXN0ZW5lcjogTXV0YXRpb25PYnNlcnZlcjtcblxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZWwgLSByZWZlcmVuY2UgdG8gdGhlIGVsZW1lbnQgb2YgdGhlIHdob2xlIGNvbXBvbmVudCwgdXNlZCB0byBzY3JhcGUgb3B0aW9ucyBkZWNsYXJlZCBvbiB0aGUgY29tcG9uZW50IGl0c2VsZlxuICAgICAqIEBwYXJhbSB6b25lIC0gcmVxdWlyZWQgdG8gcmVkcmF3IGdhdWdlIG91dHNpZGUgb2YgQW5ndWxhciwgZHVlIHRvIGFuaW1hdGlvbiBsYWdzIGNhdXNlZCBieSB0aGUgb3Zld3JpdHRlbiBmdW5jdGlvbiBvZiB0aGUgbmdab25lXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBlbDogRWxlbWVudFJlZiwgcHVibGljIHpvbmU6IE5nWm9uZSkge1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU3ViY2xhc3NlcyBzaG91bGQgaW5zdGFudGlhdGUgdGhlIENhbnZhc0dhdWdlIG9iamVjdCBpbiB0aGUgY2hpbGQgY29tcG9uZW50XG4gICAgICovXG4gICAgYWJzdHJhY3QgbmdPbkluaXQoKTogdm9pZDtcblxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBnYXVnZXMgcHJvcGVydGllcyBhcyBhbiBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBPcHRpb24gcHJvcGVydGllcyBjb25zaXN0IG9mIHRoZSBhdHRyaWJ1dGUtYmFzZWQgcHJvcGVydGllcyBhbmQgdGhvc2VcbiAgICAgKiBleHBsaWNpdGx5IHNldC5cbiAgICAgKiBAcmV0dXJucyA8VDI+XG4gICAgICovXG4gICAgcHVibGljIGdldCBvcHRpb25zKCk6IFQyIHtcblxuICAgICAgICBjb25zdCBvcHRpb25zID0ge30gYXMgVDI7XG4gICAgICAgIG9wdGlvbnMucmVuZGVyVG8gPSB0aGlzLmNhbnZhcy5uYXRpdmVFbGVtZW50O1xuXG4gICAgICAgIC8vIE1hcCBhdHRyaWJ1dGUtYmFzZWQgb3B0aW9ucyBvbnRvIG9wdGlvbnMuXG4gICAgICAgIC8vIFJlcXVyaWVzIGNvbnZlcnRpbmcga2ViYWIgc3R5bGUgYXR0cmlidXRlIG5hbWVzIHRvIGNhbWVsQ2FzZSBwcm9wZXJ0eSBuYW1lc1xuICAgICAgICBmb3IgKGNvbnN0IGF0dHIgb2YgdGhpcy5lbC5uYXRpdmVFbGVtZW50LmF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHByb3AgPSBhdHRyaWJ1dGVOYW1lMlByb3BlcnR5TmFtZShhdHRyLm5hbWUpO1xuICAgICAgICAgICAgb3B0aW9uc1twcm9wXSA9IENhbnZhc0dhdWdlcy5Eb21PYnNlcnZlci5wYXJzZShhdHRyLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIG1lcmdlIHByZU9wdG9ucyB3aXRoIGF0dHJpYnV0ZS1iYXNlZCBwcm9wZXJ0aWVzXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpmb3JpblxuICAgICAgICBmb3IgKGNvbnN0IHByb3AgaW4gdGhpcy5wcmVJbml0T3B0aW9ucykge1xuICAgICAgICAgICAgb3B0aW9uc1twcm9wXSA9IHRoaXMucHJlSW5pdE9wdGlvbnNbcHJvcF07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjbGVhciB0aGUgcHJlSW5pdE9wdGlvbnMgYXMgdGhleSBoYXZlIGFscmVhZHkgYmVlbiBtZXJnZWRcbiAgICAgICAgLy8gd2l0aCB0aGUgYXR0cmlidXRlLWJhc2VkIHByb3BlcnRpZXNcbiAgICAgICAgaWYgKHRoaXMuaXNJbml0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHJlSW5pdE9wdGlvbnMgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBBc3NpZ24gZ2F1Z2Ugb3B0aW9ucyBhdCBhbnl0aW1lIGluIHRoZSBsaWZlY3ljbGUuXG4gICAgICogQHBhcmFtIG5ld09wdGlvbnMgLSBhc3NpZ24gdGhlIHN0eWxlIGFuZCBzaXplIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgb3B0aW9ucyhuZXdPcHRpb25zOiBUMikge1xuXG4gICAgICAgIC8vIGNhY2hlIG5ld09wdGlvbnMgYXMgcHJlSW5pdE9wdGlvbnMgdW50aWwgZ2F1Z2UgaXMgcmVhZHlcbiAgICAgICAgaWYgKCF0aGlzLmlzSW5pdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnByZUluaXRPcHRpb25zID0gbmV3T3B0aW9ucztcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudXBkYXRlKG5ld09wdGlvbnMpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogQXNzaWduIHRoZSB2YWx1ZSBvZiB0aGUgZ2F1Z2UgdmlzdWFsIGluZGljYXRvciBzdWNoIGFzIGEgbmVlZGxlIG9yIHBvaW50ZXJcbiAgICAgKiBAcGFyYW0gbmV3VmFsdWUgIHRoZSBndWFnZSBuZXcgdmFsdWVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgdmFsdWUobmV3VmFsdWU6IG51bWJlcikge1xuXG4gICAgICAgIC8vIGNhc2UgbmV3IGdhdWdlIHZhbHVlIGFzIHByZUluaXRWYWx1ZSB1bnRpbCB0aGUgZ2F1Z2UgaXMgcmVhZHlcbiAgICAgICAgaWYgKCF0aGlzLmlzSW5pdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnByZUluaXRWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ2F1Z2UudmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGdhdWdlIG9wdGlvbnMuIERvIG5vdCB1c2UgdW50aWwgYWZ0ZXIgT25WaWV3SW5pdCgpIGJlZm9yZSB1c2luZy5cbiAgICAgKlxuICAgICAqIFNwZWNpYWwgaW1wbGVtZW50YXRpb24gbm90ZSAtIG9wdGlvbnMucHJvcGVydGllcyBhcmUgbWFpbnRhaW5lZCBhc1xuICAgICAqIGF0dHJpYnV0ZSBuYW1lLT52YWx1ZSBvbiB0aGlzIGNvbXBvbmVudCdzIGVsZW1lbnRSZWYuICBUaHVzIHRoaXMgbWV0aG9kXG4gICAgICogbWFwcyBlYWNoIG5ld09wdGlvbnMgcHJvcGVydHkgb250byB0aGUgcHJvcGVydHkncyBjb3JyZXNwb25kaW5nIGF0dHJpYnV0ZS5cbiAgICAgKiBUaGUgYXR0cmlidXRlIHVwZGF0ZSB0cmlnZ2VycyBhIERPTSBtdXRhdGlvbiBldmVudCB3aGljaCAgXCJ0aGlzXCIgbGlzdGVucyBmb3IuXG4gICAgICogU2VlICNsaXN0ZW5Gb3JET01FdmVudHMoKVxuICAgICAqXG4gICAgICogQHBhcmFtIG5ld09wdGlvbnMgIC0gdGhlIG9wdGlvbnMgdG8gdXBkYXRlIHRoZSBnYXVnZVxuICAgICAqL1xuICAgIHB1YmxpYyB1cGRhdGUobmV3T3B0aW9uczogVDIgfCB7fSkge1xuXG4gICAgICAgIC8vIG1hcCBhbGwgb3B0aW9ucyBvbnRvIHRoaXMgZWxlbWVudCdzIGF0dHJpYnV0ZXNcbiAgICAgICAgLy8gVGhlbiBhdHRyaWJ1dGUgY2hhbmdlcyB3aWxsIGJlIGRldGVjdGVkIGFuZCBwdXNoZWQgdG8gdGhlIGdhdWdlLnVwZGF0ZSgpXG4gICAgICAgIGlmICghbmV3T3B0aW9ucykgeyByZXR1cm47IH1cblxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Zm9yaW5cbiAgICAgICAgZm9yIChjb25zdCBwcm9wIGluIG5ld09wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbCA9IG5ld09wdGlvbnNbcHJvcF0udG9TdHJpbmcoKTtcblxuICAgICAgICAgICAgaWYgKHByb3AgPT09ICd2YWx1ZScpIHtcbiAgICAgICAgICAgICAgICAvLyBzaG9ydCBjaXJjdWl0IHRoZSB2YWx1ZSBwcm9wZXJ0eSB1cGRhdGUgYnkgY2FsbGluZ1xuICAgICAgICAgICAgICAgIC8vIHRoZSBnYXVnZS52YWx1ZSBhcGkgZGlyZWN0bHkgZm9yIGVmZmljaWVudCBhbmltYXRlZCB1cGRhdGVcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gQ2FudmFzR2F1Z2VzLkRvbU9ic2VydmVyLnBhcnNlKHZhbCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGF0dHJOYW1lID0gdG9LZWJhYkNhc2UocHJvcCk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgdmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybSBnYXVnZSBpbml0aWFsaXphdGlvbi5cbiAgICAgKiBTdWJjbGFzc2VzIHRoYXQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgbXVzdCB0aGlzIHN1cGVyIHZlcnNpb25cbiAgICAgKiBmb3IgcHJvcGVyIG9wZXJhdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xuXG4gICAgICAgIC8vIGluaXRpYWwgdXBkYXRlIG9mIGdhdWdlIHByb3BlcnRpZXNcbiAgICAgICAgdGhpcy5pbml0R2F1Z2UoKTtcblxuICAgICAgICB0aGlzLmxpc3RlbkZvckRPTUV2ZW50cygpO1xuXG4gICAgICAgIHRoaXMuaXNJbml0ZWQgPSB0cnVlO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIGZvciBhdHRyaWJ1dGUtY2hhbmdlIGV2ZW50cyB0aGF0IGFyZSBjcmVhdGVkIHdoZW4gdXBkYXRpbmdcbiAgICAgKiB0aGUgb3B0aW9ucyBvZiB0aGlzIGdhdWdlLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBsaXN0ZW5Gb3JET01FdmVudHMoKSB7XG4gICAgICAgIC8vIExpc3RlbiB0byBnYXVnZSBlbGVtZW50IGZvciBhdHRyaWJ1dGUgY2hhbmdlc1xuICAgICAgICAvLyBDb252ZXJ0IGFsbCBjaGFuZ2VkIGF0dHJpYnR1ZXMgaW50byBhIEdlbmVyaWNPcHRpb25zIG9yIHN1YmNsYXNzXG4gICAgICAgIC8vIFVwZGF0ZSB0aGUgZ2F1Z2Ugd2l0aCB0aGUgbmV3IG9wdGlvbnMuXG4gICAgICAgIHRoaXMuZG9tTGlzdGVuZXIgPVxuICAgICAgICAgICAgUnguRE9NLmZyb21NdXRhdGlvbk9ic2VydmVyKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgeyBhdHRyaWJ1dGVzOiB0cnVlIH0pLlxuICAgICAgICAgICAgICAgIHN1YnNjcmliZShjaGFuZ2VzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3T3B0aW9ucyA9IHt9IGFzIFQyO1xuICAgICAgICAgICAgICAgICAgICBjaGFuZ2VzLmZvckVhY2goY2hhbmdlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgnYXR0cmlidXRlcycgPT09IGNoYW5nZS50eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ0RPTSwgY2hhbmdlJywgY2hhbmdlLmF0dHJpYnV0ZU5hbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld09wdGlvbnNbYXR0cmlidXRlTmFtZTJQcm9wZXJ0eU5hbWUoY2hhbmdlLmF0dHJpYnV0ZU5hbWUpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENhbnZhc0dhdWdlcy5Eb21PYnNlcnZlci5wYXJzZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5nZXRBdHRyaWJ1dGUoY2hhbmdlLmF0dHJpYnV0ZU5hbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5iYXNpY1VwZGF0ZShuZXdPcHRpb25zKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIERpc2NvbnRpbnVlIGxpc3RlbmluZyBmb3IgYXR0cmlidXRlIGNoYW5nZSBldmVudHMuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHN0b3BMaXN0ZW5pbmdGb3JET01FdmVudHMoKSB7XG4gICAgICAgIGlmICh0aGlzLmRvbUxpc3RlbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmRvbUxpc3RlbmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIHRoaXMuZG9tTGlzdGVuZXIgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBJbml0YWxpemUgdGhlIGdhdWdlIHdpdGggYWxsIG9wdGlvbnMgZGVmaW5lZCBieSBhdHRyaWJ1dGVzIGFuZFxuICAgICAqIHBhcmVudCBjb21wb25lbnQgb3B0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgaW5pdEdhdWdlKCkge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAodGhpcy5wcmVJbml0VmFsdWUpIHtcbiAgICAgICAgICAgIG9wdGlvbnMudmFsdWUgPSB0aGlzLnByZUluaXRWYWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGluaXQgb3B0aW9ucy5yZW5kZXJUbyBpZiBuZWVkZWRcbiAgICAgICAgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdyZW5kZXJUbycpIHx8ICFvcHRpb25zLnJlbmRlclRvKSB7XG4gICAgICAgICAgICBvcHRpb25zLnJlbmRlclRvID0gdGhpcy5jYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYmFzaWNVcGRhdGUob3B0aW9ucyk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyB0aGUgZ2F1Z2UgdXBkYXRlIHVzaW5nIHRoZSBjdXJyZW50IG9wdGlvbnNcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAgVGhlIG9wdGlvbnMgZm9yIHRoZSBndWFnZVxuICAgICAqL1xuICAgIHByb3RlY3RlZCBiYXNpY1VwZGF0ZShvcHRpb25zOiBUMikge1xuXG4gICAgICAgIC8vIHRyZWF0IHRoZSB2YWx1ZSBwcm9wZXJ0eSBzcGVjaWFsIGFuZCB1cGRhdGUgaXQgdGhyb3VnaCB0aGVcbiAgICAgICAgLy8gdmFsdWUgZ2V0dGVyLlxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMudmFsdWUgPT09ICdudW1iZXInKSB7XG5cbiAgICAgICAgICAgIC8vIHVzZSBnYXVnZSBhcGkgZGlyZWN0bHkgZm9yIG1vc3QgZWZmaWNpZW50IHVwZGF0ZSBtZXRob2RcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBvcHRpb25zLnZhbHVlO1xuXG4gICAgICAgICAgICAvLyBmaWx0ZXIgdmFsdWUgcHJvcGVydHkgZnJvbSBvcHRpb25zIHRvIGF2b2lkIHJlZHVuZGFudFxuICAgICAgICAgICAgLy8gcHJvY2Vzc2luZyBieSBnYXVnZVxuICAgICAgICAgICAgZGVsZXRlIG9wdGlvbnMudmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkbyBub3RoaW5nIGlmIG5vIG9wdGlvbiBwcm9wZXJ0aWVzIHRvIHVwZGF0ZVxuICAgICAgICBpZiAoT2JqZWN0LmtleXMob3B0aW9ucykubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmdhdWdlLnVwZGF0ZShvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxufVxuXG5cblxuIl19