UNPKG

smart-webcomponents-angular

Version:

[![Price](https://img.shields.io/badge/price-COMMERCIAL-0098f7.svg)](https://jqwidgets.com/license/)

303 lines 48.9 kB
import { Directive, Input, Output, EventEmitter } from '@angular/core'; import { BaseElement, Smart } from './smart.element'; import * as i0 from "@angular/core"; export { Smart } from './smart.element'; export class BarcodeComponent extends BaseElement { constructor(ref) { super(ref); this.eventHandlers = []; /** @description This event is triggered whenever the scanned or entered barcode value does not meet the required validation criteria. It typically occurs when the barcode is missing, formatted incorrectly, or contains unsupported characters, allowing you to handle validation errors and provide appropriate feedback to the user. * @param event. The custom event. Custom event was created with: event.detail( invalidCharacters, lengthValidity, patternValidity, value) * invalidCharacters - An array indicating the invalid characters. * lengthValidity - A boolean indicating the length validity. * patternValidity - A boolean indicating the pattern validity. * value - the invalid value of the barcode. */ this.onInvalid = new EventEmitter(); this.nativeElement = ref.nativeElement; } /** @description Creates the component on demand. * @param properties An optional object of properties, which will be added to the template binded ones. */ createComponent(properties = {}) { this.nativeElement = document.createElement('smart-barcode'); for (let propertyName in properties) { this.nativeElement[propertyName] = properties[propertyName]; } return this.nativeElement; } /** @description Defines the background color that appears behind the barcode element. This setting determines the color fill for the area surrounding and underneath the barcode, helping to improve contrast and overall barcode visibility. Accepts color values in standard CSS formats (e.g., hex, RGB, or color names). */ get backgroundColor() { return this.nativeElement ? this.nativeElement.backgroundColor : undefined; } set backgroundColor(value) { this.nativeElement ? this.nativeElement.backgroundColor = value : undefined; } /** @description Determines whether the barcode label is displayed on the interface. When set to true, the barcode label will be visible; when set to false, the label will be hidden. */ get displayLabel() { return this.nativeElement ? this.nativeElement.displayLabel : undefined; } set displayLabel(value) { this.nativeElement ? this.nativeElement.displayLabel = value : undefined; } /** @description Specifies the color used for the text label displayed below or alongside the barcode. This color determines how the label appears to users and can be set using standard color values, such as hex codes (e.g., #000000 for black) or color names (e.g., "red"). */ get labelColor() { return this.nativeElement ? this.nativeElement.labelColor : undefined; } set labelColor(value) { this.nativeElement ? this.nativeElement.labelColor = value : undefined; } /** @description Specifies the font family to be used for displaying the text on the barcode label. This determines the appearance of the label's text by applying the selected font style. */ get labelFont() { return this.nativeElement ? this.nativeElement.labelFont : undefined; } set labelFont(value) { this.nativeElement ? this.nativeElement.labelFont = value : undefined; } /** @description Specifies the font size used for the text displayed on the barcode label, allowing you to control the readability and appearance of the label’s text. Accepts standard CSS font size units such as px, em, rem, or pt. */ get labelFontSize() { return this.nativeElement ? this.nativeElement.labelFontSize : undefined; } set labelFontSize(value) { this.nativeElement ? this.nativeElement.labelFontSize = value : undefined; } /** @description Specifies the amount of space, in pixels or other units, to be applied as the margin below the barcode label. This determines the distance between the bottom edge of the barcode label and any content or elements directly beneath it. */ get labelMarginBottom() { return this.nativeElement ? this.nativeElement.labelMarginBottom : undefined; } set labelMarginBottom(value) { this.nativeElement ? this.nativeElement.labelMarginBottom = value : undefined; } /** @description Specifies the amount of space added to the top of the barcode label by setting the top margin. This determines how far the label is positioned from the top edge of its container or surrounding elements. Accepts values in units such as pixels (px), em, or percentages (%). */ get labelMarginTop() { return this.nativeElement ? this.nativeElement.labelMarginTop : undefined; } set labelMarginTop(value) { this.nativeElement ? this.nativeElement.labelMarginTop = value : undefined; } /** @description Specifies the exact placement of the barcode label relative to the barcode image, allowing you to control where the label appears (e.g., above, below, left, or right of the barcode). This property ensures the label is positioned according to your layout requirements. */ get labelPosition() { return this.nativeElement ? this.nativeElement.labelPosition : undefined; } set labelPosition(value) { this.nativeElement ? this.nativeElement.labelPosition = value : undefined; } /** @description Specifies the color to be used for the barcode lines or bars, allowing you to customize the appearance of the barcode by changing its foreground color. This setting does not affect the background color of the barcode. Use a valid color value (e.g., HEX, RGB, or color name) as supported by your implementation. */ get lineColor() { return this.nativeElement ? this.nativeElement.lineColor : undefined; } set lineColor(value) { this.nativeElement ? this.nativeElement.lineColor = value : undefined; } /** @description Specifies the height, in pixels, of each individual barcode line. Increasing this value will make the barcode lines taller, while decreasing it will reduce their height. This property is useful for adjusting the overall visibility and scannability of the barcode. */ get lineHeight() { return this.nativeElement ? this.nativeElement.lineHeight : undefined; } set lineHeight(value) { this.nativeElement ? this.nativeElement.lineHeight = value : undefined; } /** @description Specifies the thickness of each individual bar in the barcode, allowing you to control how wide the printed barcode lines appear. Adjusting this value can help improve barcode readability for different scanners and printing methods. */ get lineWidth() { return this.nativeElement ? this.nativeElement.lineWidth : undefined; } set lineWidth(value) { this.nativeElement ? this.nativeElement.lineWidth = value : undefined; } /** @description Specifies the rendering mode used to display the barcode, determining whether it is generated as a vector graphic (such as SVG), a raster image (such as PNG), or using another supported format. This setting affects the appearance, scalability, and performance of the rendered barcode. */ get renderAs() { return this.nativeElement ? this.nativeElement.renderAs : undefined; } set renderAs(value) { this.nativeElement ? this.nativeElement.renderAs = value : undefined; } /** @description Specifies the format or symbology of the barcode to be generated (e.g., Code128, QR Code, EAN-13, UPC-A). This determines how the data will be encoded and displayed within the barcode. */ get type() { return this.nativeElement ? this.nativeElement.type : undefined; } set type(value) { this.nativeElement ? this.nativeElement.type = value : undefined; } /** @description Retrieves the current value of the barcode or updates it with a new value. This property allows you to access the existing barcode data or assign a new barcode value programmatically. */ get value() { return this.nativeElement ? this.nativeElement.value : undefined; } set value(value) { this.nativeElement ? this.nativeElement.value = value : undefined; } /** @description Specifies or retrieves the width of the barcode in pixels. If the width is set to 0, the barcode’s width will be automatically calculated based on its content and type. Use this property to define a fixed width for the barcode, or set it to 0 to allow automatic sizing for optimal readability. */ get width() { return this.nativeElement ? this.nativeElement.width : undefined; } set width(value) { this.nativeElement ? this.nativeElement.width = value : undefined; } /** @description Defines or retrieves the height of the barcode, in pixels. When a value of 0 is assigned, the barcode's height will be determined automatically based on its content and format, ensuring optimal sizing without manual specification. If a positive value is provided, the barcode will be rendered at that exact height. */ get height() { return this.nativeElement ? this.nativeElement.height : undefined; } set height(value) { this.nativeElement ? this.nativeElement.height = value : undefined; } /** @description Exports the generated barcode image or data for use outside the application. This function typically saves or downloads the barcode in formats such as PNG, JPEG, or SVG, making it accessible for printing, sharing, or integration with other systems. * @param {string} format. The format of the exported file - svg, png, jpg * @param {string} fileName?. The name of the exported file */ export(format, fileName) { if (this.nativeElement.isRendered) { this.nativeElement.export(format, fileName); } else { this.nativeElement.whenRendered(() => { this.nativeElement.export(format, fileName); }); } } /** @description Retrieves the barcode image encoded as a Base64 string, allowing for convenient embedding or transmission of the barcode in web applications or APIs without needing a physical image file. * @param {string} format. The dataURL format of the string - svg, png, jpg * @returns {string} */ async getDataURL(format) { const getResultOnRender = () => { return new Promise(resolve => { this.nativeElement.whenRendered(() => { const result = this.nativeElement.getDataURL(format); resolve(result); }); }); }; const result = await getResultOnRender(); return result; } getDataURLSync(format) { if (this.nativeElement.isRendered) { return this.nativeElement.getDataURL(format); } return null; } /** @description Retrieves the barcode image encoded as a Base64 string, allowing you to easily embed or transmit the barcode in formats such as HTML, CSS, or JSON. * @param {string} format. The dataURL format of the string - svg, png, jpg * @returns {any} */ async getDataURLAsync(format) { const getResultOnRender = () => { return new Promise(resolve => { this.nativeElement.whenRendered(() => { const result = this.nativeElement.getDataURLAsync(format); resolve(result); }); }); }; const result = await getResultOnRender(); return result; } getDataURLAsyncSync(format) { if (this.nativeElement.isRendered) { return this.nativeElement.getDataURLAsync(format); } return null; } /** @description Retrieves the validation status of the barcode, indicating whether the scanned barcode meets the required format and integrity checks. * @returns {boolean} */ async isValid() { const getResultOnRender = () => { return new Promise(resolve => { this.nativeElement.whenRendered(() => { const result = this.nativeElement.isValid(); resolve(result); }); }); }; const result = await getResultOnRender(); return result; } isValidSync() { if (this.nativeElement.isRendered) { return this.nativeElement.isValid(); } return null; } get isRendered() { return this.nativeElement ? this.nativeElement.isRendered : false; } ngOnInit() { } ngAfterViewInit() { const that = this; that.onCreate.emit(that.nativeElement); if (Smart) Smart.Render(); this.nativeElement.classList.add('smart-angular'); if (this.nativeElement.whenRendered) this.nativeElement.whenRendered(() => { that.onReady.emit(that.nativeElement); }); this.listen(); } ngOnDestroy() { this.unlisten(); } ngOnChanges(changes) { if (this.nativeElement && this.nativeElement.isRendered) { for (const propName in changes) { if (changes.hasOwnProperty(propName)) { this.nativeElement[propName] = changes[propName].currentValue; } } } } /** @description Add event listeners. */ listen() { const that = this; that.eventHandlers['invalidHandler'] = (event) => { that.onInvalid.emit(event); }; that.nativeElement.addEventListener('invalid', that.eventHandlers['invalidHandler']); } /** @description Remove event listeners. */ unlisten() { const that = this; if (that.eventHandlers['invalidHandler']) { that.nativeElement.removeEventListener('invalid', that.eventHandlers['invalidHandler']); } } } BarcodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.6", ngImport: i0, type: BarcodeComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); BarcodeComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.6", type: BarcodeComponent, selector: "smart-barcode, [smart-barcode]", inputs: { backgroundColor: "backgroundColor", displayLabel: "displayLabel", labelColor: "labelColor", labelFont: "labelFont", labelFontSize: "labelFontSize", labelMarginBottom: "labelMarginBottom", labelMarginTop: "labelMarginTop", labelPosition: "labelPosition", lineColor: "lineColor", lineHeight: "lineHeight", lineWidth: "lineWidth", renderAs: "renderAs", type: "type", value: "value", width: "width", height: "height" }, outputs: { onInvalid: "onInvalid" }, exportAs: ["smart-barcode"], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.6", ngImport: i0, type: BarcodeComponent, decorators: [{ type: Directive, args: [{ exportAs: 'smart-barcode', selector: 'smart-barcode, [smart-barcode]' }] }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { backgroundColor: [{ type: Input }], displayLabel: [{ type: Input }], labelColor: [{ type: Input }], labelFont: [{ type: Input }], labelFontSize: [{ type: Input }], labelMarginBottom: [{ type: Input }], labelMarginTop: [{ type: Input }], labelPosition: [{ type: Input }], lineColor: [{ type: Input }], lineHeight: [{ type: Input }], lineWidth: [{ type: Input }], renderAs: [{ type: Input }], type: [{ type: Input }], value: [{ type: Input }], width: [{ type: Input }], height: [{ type: Input }], onInvalid: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnQuYmFyY29kZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2JhcmNvZGUvc3JjL3NtYXJ0LmJhcmNvZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFhLFNBQVMsRUFBNkIsS0FBSyxFQUErQyxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFKLE9BQU8sRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBRXJELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQVF4QyxNQUFNLE9BQU8sZ0JBQWlCLFNBQVEsV0FBVztJQUNoRCxZQUFZLEdBQXdCO1FBQ25DLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUlKLGtCQUFhLEdBQVUsRUFBRSxDQUFDO1FBNkpsQzs7Ozs7O1VBTUU7UUFDUSxjQUFTLEdBQThCLElBQUksWUFBWSxFQUFFLENBQUM7UUF2S25FLElBQUksQ0FBQyxhQUFhLEdBQUcsR0FBRyxDQUFDLGFBQXdCLENBQUM7SUFDbkQsQ0FBQztJQUtEOztPQUVHO0lBQ0ksZUFBZSxDQUFDLFVBQVUsR0FBRyxFQUFFO1FBQ2xDLElBQUksQ0FBQyxhQUFhLEdBQVksUUFBUSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN6RSxLQUFLLElBQUksWUFBWSxJQUFJLFVBQVUsRUFBRTtZQUNuQyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxHQUFHLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUM3RDtRQUNELE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUMzQixDQUFDO0lBQ0QsZ1VBQWdVO0lBQ2hVLElBQ0ksZUFBZTtRQUNsQixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDNUUsQ0FBQztJ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YSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDMUUsQ0FBQztJQUNELElBQUksYUFBYSxDQUFDLEtBQW9DO1FBQ3JELElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQzNFLENBQUM7SUFFRCwwVUFBMFU7SUFDMVUsSUFDSSxTQUFTO1FBQ1osT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ3RFLENBQUM7SUFDRCxJQUFJLFNBQVMsQ0FBQyxLQUFhO1FBQzFCLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCwyUkFBMlI7SUFDM1IsSUFDSSxVQUFVO1FBQ2IsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ3ZFLENBQUM7SUFDRCxJQUFJLFVBQVUsQ0FBQyxLQUFhO1FBQzNCLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ3hFLENBQUM7SUFFRCw0UEFBNFA7SUFDNVAsSUFDSSxTQUFTO1FBQ1osT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ3RFLENBQUM7SUFDRCxJQUFJLFNBQVMsQ0FBQyxLQUFhO1FBQzFCLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENB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LENBQUMsRUFBRTtZQUN6QyxJQUFJLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztTQUN4RjtJQUVGLENBQUM7OzZHQXhUVyxnQkFBZ0I7aUdBQWhCLGdCQUFnQjsyRkFBaEIsZ0JBQWdCO2tCQUo1QixTQUFTO21CQUFDO29CQUNWLFFBQVEsRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLGdDQUFnQztpQkFDckU7aUdBdUJJLGVBQWU7c0JBRGxCLEtBQUs7Z0JBVUYsWUFBWTtzQkFEZixLQUFLO2dCQVVGLFVBQVU7c0JBRGIsS0FBSztnQkFVRixTQUFTO3NCQURaLEtBQUs7Z0JBVUYsYUFBYTtzQkFEaEIsS0FBSztnQkFVRixpQkFBaUI7c0JBRHBCLEtBQUs7Z0JBVUYsY0FBYztzQkFEakIsS0FBSztnQkFVRixhQUFhO3NCQURoQixLQUFLO2dCQVVGLFNBQVM7c0JBRFosS0FBSztnQkFVRixVQUFVO3NCQURiLEtBQUs7Z0JBVUYsU0FBUztzQkFEWixLQUFLO2dCQVVGLFFBQVE7c0JBRFgsS0FBSztnQkFVRixJQUFJO3NCQURQLEtBQUs7Z0JBVUYsS0FBSztzQkFEUixLQUFLO2dCQVVGLEtBQUs7c0JBRFIsS0FBSztnQkFVRixNQUFNO3NCQURULEtBQUs7Z0JBZUksU0FBUztzQkFBbEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJhcmNvZGUgfSBmcm9tICcuLy4uL2luZGV4JztcbmltcG9ydCB7IEJhcmNvZGVMYWJlbFBvc2l0aW9uLCBCYXJjb2RlUmVuZGVyQXMsIEJhcmNvZGVUeXBlLCBFbGVtZW50UmVuZGVyTW9kZX0gZnJvbSAnLi8uLi9pbmRleCc7XG5pbXBvcnQgeyBDb21wb25lbnQsIERpcmVjdGl2ZSwgQWZ0ZXJWaWV3SW5pdCwgRWxlbWVudFJlZiwgSW5wdXQsIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIFNpbXBsZUNoYW5nZXMsIE91dHB1dCwgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCYXNlRWxlbWVudCwgU21hcnQgfSBmcm9tICcuL3NtYXJ0LmVsZW1lbnQnO1xuZXhwb3J0IHsgQmFyY29kZUxhYmVsUG9zaXRpb24sIEJhcmNvZGVSZW5kZXJBcywgQmFyY29kZVR5cGUsIEVsZW1lbnRSZW5kZXJNb2RlfSBmcm9tICcuLy4uL2luZGV4JztcbmV4cG9ydCB7IFNtYXJ0IH0gZnJvbSAnLi9zbWFydC5lbGVtZW50JztcbmV4cG9ydCB7IEJhcmNvZGUgfSBmcm9tICcuLy4uL2luZGV4JztcblxuXG5ARGlyZWN0aXZlKHtcblx0ZXhwb3J0QXM6ICdzbWFydC1iYXJjb2RlJyxcdHNlbGVjdG9yOiAnc21hcnQtYmFyY29kZSwgW3NtYXJ0LWJhcmNvZGVdJ1xufSlcblxuZXhwb3J0IGNsYXNzIEJhcmNvZGVDb21wb25lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xuXHRjb25zdHJ1Y3RvcihyZWY6IEVsZW1lbnRSZWY8QmFyY29kZT4pIHtcblx0XHRzdXBlcihyZWYpO1xuXHRcdHRoaXMubmF0aXZlRWxlbWVudCA9IHJlZi5uYXRpdmVFbGVtZW50IGFzIEJhcmNvZGU7XG5cdH1cblxuXHRwcml2YXRlIGV2ZW50SGFuZGxlcnM6IGFueVtdID0gW107XG5cblx0cHVibGljIGRlY2xhcmUgbmF0aXZlRWxlbWVudDogQmFyY29kZTtcblx0LyoqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIHRoZSBjb21wb25lbnQgb24gZGVtYW5kLlxuXHQgKiBAcGFyYW0gcHJvcGVydGllcyBBbiBvcHRpb25hbCBvYmplY3Qgb2YgcHJvcGVydGllcywgd2hpY2ggd2lsbCBiZSBhZGRlZCB0byB0aGUgdGVtcGxhdGUgYmluZGVkIG9uZXMuXG5cdCAqL1xuXHRwdWJsaWMgY3JlYXRlQ29tcG9uZW50KHByb3BlcnRpZXMgPSB7fSk6IGFueSB7XG4gICAgXHR0aGlzLm5hdGl2ZUVsZW1lbnQgPSA8QmFyY29kZT5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzbWFydC1iYXJjb2RlJyk7XG5cdFx0Zm9yIChsZXQgcHJvcGVydHlOYW1lIGluIHByb3BlcnRpZXMpIHsgXG4gXHRcdFx0dGhpcy5uYXRpdmVFbGVtZW50W3Byb3BlcnR5TmFtZV0gPSBwcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV07XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQ7XG5cdH1cblx0LyoqIEBkZXNjcmlwdGlvbiBEZWZpbmVzIHRoZSBiYWNrZ3JvdW5kIGNvbG9yIHRoYXQgYXBwZWFycyBiZWhpbmQgdGhlIGJhcmNvZGUgZWxlbWVudC4gVGhpcyBzZXR0aW5nIGRldGVybWluZXMgdGhlIGNvbG9yIGZpbGwgZm9yIHRoZSBhcmVhIHN1cnJvdW5kaW5nIGFuZCB1bmRlcm5lYXRoIHRoZSBiYXJjb2RlLCBoZWxwaW5nIHRvIGltcHJvdmUgY29udHJhc3QgYW5kIG92ZXJhbGwgYmFyY29kZSB2aXNpYmlsaXR5LiBBY2NlcHRzIGNvbG9yIHZhbHVlcyBpbiBzdGFuZGFyZCBDU1MgZm9ybWF0cyAoZS5nLiwgaGV4LCBSR0IsIG9yIGNvbG9yIG5hbWVzKS4gKi9cblx0QElucHV0KClcblx0Z2V0IGJhY2tncm91bmRDb2xvcigpOiBzdHJpbmcge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQuYmFja2dyb3VuZENvbG9yIDogdW5kZWZpbmVkO1xuXHR9XG5cdHNldCBiYWNrZ3JvdW5kQ29sb3IodmFsdWU6IHN0cmluZykge1xuXHRcdHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5iYWNrZ3JvdW5kQ29sb3IgPSB2YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBiYXJjb2RlIGxhYmVsIGlzIGRpc3BsYXllZCBvbiB0aGUgaW50ZXJmYWNlLiBXaGVuIHNldCB0byB0cnVlLCB0aGUgYmFyY29kZSBsYWJlbCB3aWxsIGJlIHZpc2libGU7IHdoZW4gc2V0IHRvIGZhbHNlLCB0aGUgbGFiZWwgd2lsbCBiZSBoaWRkZW4uICovXG5cdEBJbnB1dCgpXG5cdGdldCBkaXNwbGF5TGFiZWwoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5kaXNwbGF5TGFiZWwgOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGRpc3BsYXlMYWJlbCh2YWx1ZTogYm9vbGVhbikge1xuXHRcdHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5kaXNwbGF5TGFiZWwgPSB2YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gU3BlY2lmaWVzIHRoZSBjb2xvciB1c2VkIGZvciB0aGUgdGV4dCBsYWJlbCBkaXNwbGF5ZWQgYmVsb3cgb3IgYWxvbmdzaWRlIHRoZSBiYXJjb2RlLiBUaGlzIGNvbG9yIGRldGVybWluZXMgaG93IHRoZSBsYWJlbCBhcHBlYXJzIHRvIHVzZXJzIGFuZCBjYW4gYmUgc2V0IHVzaW5nIHN0YW5kYXJkIGNvbG9yIHZhbHVlcywgc3VjaCBhcyBoZXggY29kZXMgKGUuZy4sICMwMDAwMDAgZm9yIGJsYWNrKSBvciBjb2xvciBuYW1lcyAoZS5nLiwgXCJyZWRcIikuICovXG5cdEBJbnB1dCgpXG5cdGdldCBsYWJlbENvbG9yKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5sYWJlbENvbG9yIDogdW5kZWZpbmVkO1xuXHR9XG5cdHNldCBsYWJlbENvbG9yKHZhbHVlOiBzdHJpbmcpIHtcblx0XHR0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQubGFiZWxDb2xvciA9IHZhbHVlIDogdW5kZWZpbmVkO1xuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBTcGVjaWZpZXMgdGhlIGZvbnQgZmFtaWx5IHRvIGJlIHVzZWQgZm9yIGRpc3BsYXlpbmcgdGhlIHRleHQgb24gdGhlIGJhcmNvZGUgbGFiZWwuIFRoaXMgZGV0ZXJtaW5lcyB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgbGFiZWwncyB0ZXh0IGJ5IGFwcGx5aW5nIHRoZSBzZWxlY3RlZCBmb250IHN0eWxlLiAqL1xuXHRASW5wdXQoKVxuXHRnZXQgbGFiZWxGb250KCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5sYWJlbEZvbnQgOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGxhYmVsRm9udCh2YWx1ZTogc3RyaW5nKSB7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmxhYmVsRm9udCA9IHZhbHVlIDogdW5kZWZpbmVkO1xuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBTcGVjaWZpZXMgdGhlIGZvbnQgc2l6ZSB1c2VkIGZvciB0aGUgdGV4dCBkaXNwbGF5ZWQgb24gdGhlIGJhcmNvZGUgbGFiZWwsIGFsbG93aW5nIHlvdSB0byBjb250cm9sIHRoZSByZWFkYWJpbGl0eSBhbmQgYXBwZWFyYW5jZSBvZiB0aGUgbGFiZWzigJlzIHRleHQuIEFjY2VwdHMgc3RhbmRhcmQgQ1NTIGZvbnQgc2l6ZSB1bml0cyBzdWNoIGFzIHB4LCBlbSwgcmVtLCBvciBwdC4gKi9cblx0QElucHV0KClcblx0Z2V0IGxhYmVsRm9udFNpemUoKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gdGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmxhYmVsRm9udFNpemUgOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGxhYmVsRm9udFNpemUodmFsdWU6IG51bWJlcikge1xuXHRcdHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5sYWJlbEZvbnRTaXplID0gdmFsdWUgOiB1bmRlZmluZWQ7XG5cdH1cblxuXHQvKiogQGRlc2NyaXB0aW9uIFNwZWNpZmllcyB0aGUgYW1vdW50IG9mIHNwYWNlLCBpbiBwaXhlbHMgb3Igb3RoZXIgdW5pdHMsIHRvIGJlIGFwcGxpZWQgYXMgdGhlIG1hcmdpbiBiZWxvdyB0aGUgYmFyY29kZSBsYWJlbC4gVGhpcyBkZXRlcm1pbmVzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBib3R0b20gZWRnZSBvZiB0aGUgYmFyY29kZSBsYWJlbCBhbmQgYW55IGNvbnRlbnQgb3IgZWxlbWVudHMgZGlyZWN0bHkgYmVuZWF0aCBpdC4gKi9cblx0QElucHV0KClcblx0Z2V0IGxhYmVsTWFyZ2luQm90dG9tKCk6IG51bWJlciB7XG5cdFx0cmV0dXJuIHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5sYWJlbE1hcmdpbkJvdHRvbSA6IHVuZGVmaW5lZDtcblx0fVxuXHRzZXQgbGFiZWxNYXJnaW5Cb3R0b20odmFsdWU6IG51bWJlcikge1xuXHRcdHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5sYWJlbE1hcmdpbkJvdHRvbSA9IHZhbHVlIDogdW5kZWZpbmVkO1xuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBTcGVjaWZpZXMgdGhlIGFtb3VudCBvZiBzcGFjZSBhZGRlZCB0byB0aGUgdG9wIG9mIHRoZSBiYXJjb2RlIGxhYmVsIGJ5IHNldHRpbmcgdGhlIHRvcCBtYXJnaW4uIFRoaXMgZGV0ZXJtaW5lcyBob3cgZmFyIHRoZSBsYWJlbCBpcyBwb3NpdGlvbmVkIGZyb20gdGhlIHRvcCBlZGdlIG9mIGl0cyBjb250YWluZXIgb3Igc3Vycm91bmRpbmcgZWxlbWVudHMuIEFjY2VwdHMgdmFsdWVzIGluIHVuaXRzIHN1Y2ggYXMgcGl4ZWxzIChweCksIGVtLCBvciBwZXJjZW50YWdlcyAoJSkuICovXG5cdEBJbnB1dCgpXG5cdGdldCBsYWJlbE1hcmdpblRvcCgpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQubGFiZWxNYXJnaW5Ub3AgOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGxhYmVsTWFyZ2luVG9wKHZhbHVlOiBudW1iZXIpIHtcblx0XHR0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQubGFiZWxNYXJnaW5Ub3AgPSB2YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gU3BlY2lmaWVzIHRoZSBleGFjdCBwbGFjZW1lbnQgb2YgdGhlIGJhcmNvZGUgbGFiZWwgcmVsYXRpdmUgdG8gdGhlIGJhcmNvZGUgaW1hZ2UsIGFsbG93aW5nIHlvdSB0byBjb250cm9sIHdoZXJlIHRoZSBsYWJlbCBhcHBlYXJzIChlLmcuLCBhYm92ZSwgYmVsb3csIGxlZnQsIG9yIHJpZ2h0IG9mIHRoZSBiYXJjb2RlKS4gVGhpcyBwcm9wZXJ0eSBlbnN1cmVzIHRoZSBsYWJlbCBpcyBwb3NpdGlvbmVkIGFjY29yZGluZyB0byB5b3VyIGxheW91dCByZXF1aXJlbWVudHMuICovXG5cdEBJbnB1dCgpXG5cdGdldCBsYWJlbFBvc2l0aW9uKCk6IEJhcmNvZGVMYWJlbFBvc2l0aW9uIHwgc3RyaW5nIHtcblx0XHRyZXR1cm4gdGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmxhYmVsUG9zaXRpb24gOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGxhYmVsUG9zaXRpb24odmFsdWU6IEJhcmNvZGVMYWJlbFBvc2l0aW9uIHwgc3RyaW5nKSB7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmxhYmVsUG9zaXRpb24gPSB2YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gU3BlY2lmaWVzIHRoZSBjb2xvciB0byBiZSB1c2VkIGZvciB0aGUgYmFyY29kZSBsaW5lcyBvciBiYXJzLCBhbGxvd2luZyB5b3UgdG8gY3VzdG9taXplIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBiYXJjb2RlIGJ5IGNoYW5naW5nIGl0cyBmb3JlZ3JvdW5kIGNvbG9yLiBUaGlzIHNldHRpbmcgZG9lcyBub3QgYWZmZWN0IHRoZSBiYWNrZ3JvdW5kIGNvbG9yIG9mIHRoZSBiYXJjb2RlLiBVc2UgYSB2YWxpZCBjb2xvciB2YWx1ZSAoZS5nLiwgSEVYLCBSR0IsIG9yIGNvbG9yIG5hbWUpIGFzIHN1cHBvcnRlZCBieSB5b3VyIGltcGxlbWVudGF0aW9uLiAqL1xuXHRASW5wdXQoKVxuXHRnZXQgbGluZUNvbG9yKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5saW5lQ29sb3IgOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGxpbmVDb2xvcih2YWx1ZTogc3RyaW5nKSB7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmxpbmVDb2xvciA9IHZhbHVlIDogdW5kZWZpbmVkO1xuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBTcGVjaWZpZXMgdGhlIGhlaWdodCwgaW4gcGl4ZWxzLCBvZiBlYWNoIGluZGl2aWR1YWwgYmFyY29kZSBsaW5lLiBJbmNyZWFzaW5nIHRoaXMgdmFsdWUgd2lsbCBtYWtlIHRoZSBiYXJjb2RlIGxpbmVzIHRhbGxlciwgd2hpbGUgZGVjcmVhc2luZyBpdCB3aWxsIHJlZHVjZSB0aGVpciBoZWlnaHQuIFRoaXMgcHJvcGVydHkgaXMgdXNlZnVsIGZvciBhZGp1c3RpbmcgdGhlIG92ZXJhbGwgdmlzaWJpbGl0eSBhbmQgc2Nhbm5hYmlsaXR5IG9mIHRoZSBiYXJjb2RlLiAqL1xuXHRASW5wdXQoKVxuXHRnZXQgbGluZUhlaWdodCgpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQubGluZUhlaWdodCA6IHVuZGVmaW5lZDtcblx0fVxuXHRzZXQgbGluZUhlaWdodCh2YWx1ZTogbnVtYmVyKSB7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmxpbmVIZWlnaHQgPSB2YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gU3BlY2lmaWVzIHRoZSB0aGlja25lc3Mgb2YgZWFjaCBpbmRpdmlkdWFsIGJhciBpbiB0aGUgYmFyY29kZSwgYWxsb3dpbmcgeW91IHRvIGNvbnRyb2wgaG93IHdpZGUgdGhlIHByaW50ZWQgYmFyY29kZSBsaW5lcyBhcHBlYXIuIEFkanVzdGluZyB0aGlzIHZhbHVlIGNhbiBoZWxwIGltcHJvdmUgYmFyY29kZSByZWFkYWJpbGl0eSBmb3IgZGlmZmVyZW50IHNjYW5uZXJzIGFuZCBwcmludGluZyBtZXRob2RzLiAqL1xuXHRASW5wdXQoKVxuXHRnZXQgbGluZVdpZHRoKCk6IG51bWJlciB7XG5cdFx0cmV0dXJuIHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5saW5lV2lkdGggOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGxpbmVXaWR0aCh2YWx1ZTogbnVtYmVyKSB7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmxpbmVXaWR0aCA9IHZhbHVlIDogdW5kZWZpbmVkO1xuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBTcGVjaWZpZXMgdGhlIHJlbmRlcmluZyBtb2RlIHVzZWQgdG8gZGlzcGxheSB0aGUgYmFyY29kZSwgZGV0ZXJtaW5pbmcgd2hldGhlciBpdCBpcyBnZW5lcmF0ZWQgYXMgYSB2ZWN0b3IgZ3JhcGhpYyAoc3VjaCBhcyBTVkcpLCBhIHJhc3RlciBpbWFnZSAoc3VjaCBhcyBQTkcpLCBvciB1c2luZyBhbm90aGVyIHN1cHBvcnRlZCBmb3JtYXQuIFRoaXMgc2V0dGluZyBhZmZlY3RzIHRoZSBhcHBlYXJhbmNlLCBzY2FsYWJpbGl0eSwgYW5kIHBlcmZvcm1hbmNlIG9mIHRoZSByZW5kZXJlZCBiYXJjb2RlLiAqL1xuXHRASW5wdXQoKVxuXHRnZXQgcmVuZGVyQXMoKTogQmFyY29kZVJlbmRlckFzIHwgc3RyaW5nIHtcblx0XHRyZXR1cm4gdGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LnJlbmRlckFzIDogdW5kZWZpbmVkO1xuXHR9XG5cdHNldCByZW5kZXJBcyh2YWx1ZTogQmFyY29kZVJlbmRlckFzIHwgc3RyaW5nKSB7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LnJlbmRlckFzID0gdmFsdWUgOiB1bmRlZmluZWQ7XG5cdH1cblxuXHQvKiogQGRlc2NyaXB0aW9uIFNwZWNpZmllcyB0aGUgZm9ybWF0IG9yIHN5bWJvbG9neSBvZiB0aGUgYmFyY29kZSB0byBiZSBnZW5lcmF0ZWQgKGUuZy4sIENvZGUxMjgsIFFSIENvZGUsIEVBTi0xMywgVVBDLUEpLiBUaGlzIGRldGVybWluZXMgaG93IHRoZSBkYXRhIHdpbGwgYmUgZW5jb2RlZCBhbmQgZGlzcGxheWVkIHdpdGhpbiB0aGUgYmFyY29kZS4gKi9cblx0QElucHV0KClcblx0Z2V0IHR5cGUoKTogQmFyY29kZVR5cGUgfCBzdHJpbmcge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQudHlwZSA6IHVuZGVmaW5lZDtcblx0fVxuXHRzZXQgdHlwZSh2YWx1ZTogQmFyY29kZVR5cGUgfCBzdHJpbmcpIHtcblx0XHR0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQudHlwZSA9IHZhbHVlIDogdW5kZWZpbmVkO1xuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGJhcmNvZGUgb3IgdXBkYXRlcyBpdCB3aXRoIGEgbmV3IHZhbHVlLiBUaGlzIHByb3BlcnR5IGFsbG93cyB5b3UgdG8gYWNjZXNzIHRoZSBleGlzdGluZyBiYXJjb2RlIGRhdGEgb3IgYXNzaWduIGEgbmV3IGJhcmNvZGUgdmFsdWUgcHJvZ3JhbW1hdGljYWxseS4gKi9cblx0QElucHV0KClcblx0Z2V0IHZhbHVlKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC52YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXHRzZXQgdmFsdWUodmFsdWU6IHN0cmluZykge1xuXHRcdHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC52YWx1ZSA9IHZhbHVlIDogdW5kZWZpbmVkO1xuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBTcGVjaWZpZXMgb3IgcmV0cmlldmVzIHRoZSB3aWR0aCBvZiB0aGUgYmFyY29kZSBpbiBwaXhlbHMuIElmIHRoZSB3aWR0aCBpcyBzZXQgdG8gMCwgdGhlIGJhcmNvZGXigJlzIHdpZHRoIHdpbGwgYmUgYXV0b21hdGljYWxseSBjYWxjdWxhdGVkIGJhc2VkIG9uIGl0cyBjb250ZW50IGFuZCB0eXBlLiBVc2UgdGhpcyBwcm9wZXJ0eSB0byBkZWZpbmUgYSBmaXhlZCB3aWR0aCBmb3IgdGhlIGJhcmNvZGUsIG9yIHNldCBpdCB0byAwIHRvIGFsbG93IGF1dG9tYXRpYyBzaXppbmcgZm9yIG9wdGltYWwgcmVhZGFiaWxpdHkuICovXG5cdEBJbnB1dCgpXG5cdGdldCB3aWR0aCgpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQud2lkdGggOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IHdpZHRoKHZhbHVlOiBudW1iZXIpIHtcblx0XHR0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQud2lkdGggPSB2YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gRGVmaW5lcyBvciByZXRyaWV2ZXMgdGhlIGhlaWdodCBvZiB0aGUgYmFyY29kZSwgaW4gcGl4ZWxzLiBXaGVuIGEgdmFsdWUgb2YgMCBpcyBhc3NpZ25lZCwgdGhlIGJhcmNvZGUncyBoZWlnaHQgd2lsbCBiZSBkZXRlcm1pbmVkIGF1dG9tYXRpY2FsbHkgYmFzZWQgb24gaXRzIGNvbnRlbnQgYW5kIGZvcm1hdCwgZW5zdXJpbmcgb3B0aW1hbCBzaXppbmcgd2l0aG91dCBtYW51YWwgc3BlY2lmaWNhdGlvbi4gSWYgYSBwb3NpdGl2ZSB2YWx1ZSBpcyBwcm92aWRlZCwgdGhlIGJhcmNvZGUgd2lsbCBiZSByZW5kZXJlZCBhdCB0aGF0IGV4YWN0IGhlaWdodC4gKi9cblx0QElucHV0KClcblx0Z2V0IGhlaWdodCgpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQuaGVpZ2h0IDogdW5kZWZpbmVkO1xuXHR9XG5cdHNldCBoZWlnaHQodmFsdWU6IG51bWJlcikge1xuXHRcdHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5oZWlnaHQgPSB2YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gVGhpcyBldmVudCBpcyB0cmlnZ2VyZWQgd2hlbmV2ZXIgdGhlIHNjYW5uZWQgb3IgZW50ZXJlZCBiYXJjb2RlIHZhbHVlIGRvZXMgbm90IG1lZXQgdGhlIHJlcXVpcmVkIHZhbGlkYXRpb24gY3JpdGVyaWEuIEl0IHR5cGljYWxseSBvY2N1cnMgd2hlbiB0aGUgYmFyY29kZSBpcyBtaXNzaW5nLCBmb3JtYXR0ZWQgaW5jb3JyZWN0bHksIG9yIGNvbnRhaW5zIHVuc3VwcG9ydGVkIGNoYXJhY3RlcnMsIGFsbG93aW5nIHlvdSB0byBoYW5kbGUgdmFsaWRhdGlvbiBlcnJvcnMgYW5kIHByb3ZpZGUgYXBwcm9wcmlhdGUgZmVlZGJhY2sgdG8gdGhlIHVzZXIuXG5cdCogIEBwYXJhbSBldmVudC4gVGhlIGN1c3RvbSBldmVudC4gXHRDdXN0b20gZXZlbnQgd2FzIGNyZWF0ZWQgd2l0aDogZXZlbnQuZGV0YWlsKFx0aW52YWxpZENoYXJhY3RlcnMsIFx0bGVuZ3RoVmFsaWRpdHksIFx0cGF0dGVyblZhbGlkaXR5LCBcdHZhbHVlKVxuXHQqICAgaW52YWxpZENoYXJhY3RlcnMgLSBBbiBhcnJheSBpbmRpY2F0aW5nIHRoZSBpbnZhbGlkIGNoYXJhY3RlcnMuXG5cdCogICBsZW5ndGhWYWxpZGl0eSAtIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHRoZSBsZW5ndGggdmFsaWRpdHkuXG5cdCogICBwYXR0ZXJuVmFsaWRpdHkgLSBBIGJvb2xlYW4gaW5kaWNhdGluZyB0aGUgcGF0dGVybiB2YWxpZGl0eS5cblx0KiAgIHZhbHVlIC0gdGhlIGludmFsaWQgdmFsdWUgb2YgdGhlIGJhcmNvZGUuXG5cdCovXG5cdEBPdXRwdXQoKSBvbkludmFsaWQ6IEV2ZW50RW1pdHRlcjxDdXN0b21FdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBFeHBvcnRzIHRoZSBnZW5lcmF0ZWQgYmFyY29kZSBpbWFnZSBvciBkYXRhIGZvciB1c2Ugb3V0c2lkZSB0aGUgYXBwbGljYXRpb24uIFRoaXMgZnVuY3Rpb24gdHlwaWNhbGx5IHNhdmVzIG9yIGRvd25sb2FkcyB0aGUgYmFyY29kZSBpbiBmb3JtYXRzIHN1Y2ggYXMgUE5HLCBKUEVHLCBvciBTVkcsIG1ha2luZyBpdCBhY2Nlc3NpYmxlIGZvciBwcmludGluZywgc2hhcmluZywgb3IgaW50ZWdyYXRpb24gd2l0aCBvdGhlciBzeXN0ZW1zLiBcblx0KiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0LiBUaGUgZm9ybWF0IG9mIHRoZSBleHBvcnRlZCBmaWxlIC0gc3ZnLCBwbmcsIGpwZ1xuXHQqIEBwYXJhbSB7c3RyaW5nfSBmaWxlTmFtZT8uIFRoZSBuYW1lIG9mIHRoZSBleHBvcnRlZCBmaWxlXG5cdCovXG4gICAgcHVibGljIGV4cG9ydChmb3JtYXQ6IHN0cmluZywgZmlsZU5hbWU/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMubmF0aXZlRWxlbWVudC5pc1JlbmRlcmVkKSB7XG4gICAgICAgICAgICB0aGlzLm5hdGl2ZUVsZW1lbnQuZXhwb3J0KGZvcm1hdCwgZmlsZU5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAge1xuICAgICAgICAgICAgdGhpcy5uYXRpdmVFbGVtZW50LndoZW5SZW5kZXJlZCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVFbGVtZW50LmV4cG9ydChmb3JtYXQsIGZpbGVOYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSBiYXJjb2RlIGltYWdlIGVuY29kZWQgYXMgYSBCYXNlNjQgc3RyaW5nLCBhbGxvd2luZyBmb3IgY29udmVuaWVudCBlbWJlZGRpbmcgb3IgdHJhbnNtaXNzaW9uIG9mIHRoZSBiYXJjb2RlIGluIHdlYiBhcHBsaWNhdGlvbnMgb3IgQVBJcyB3aXRob3V0IG5lZWRpbmcgYSBwaHlzaWNhbCBpbWFnZSBmaWxlLiBcblx0KiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0LiBUaGUgZGF0YVVSTCBmb3JtYXQgb2YgdGhlIHN0cmluZyAtIHN2ZywgcG5nLCBqcGdcblx0KiBAcmV0dXJucyB7c3RyaW5nfVxuICAqL1xuXHRwdWJsaWMgYXN5bmMgZ2V0RGF0YVVSTChmb3JtYXQpOiBQcm9taXNlPGFueT4ge1xuXHRcdGNvbnN0IGdldFJlc3VsdE9uUmVuZGVyID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlRWxlbWVudC53aGVuUmVuZGVyZWQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLm5hdGl2ZUVsZW1lbnQuZ2V0RGF0YVVSTChmb3JtYXQpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdClcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBnZXRSZXN1bHRPblJlbmRlcigpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG5cdHB1YmxpYyBnZXREYXRhVVJMU3luYyhmb3JtYXQpOiBzdHJpbmcge1xuICAgICAgICBpZiAodGhpcy5uYXRpdmVFbGVtZW50LmlzUmVuZGVyZWQpIHtcbiBcdCAgICAgICByZXR1cm4gdGhpcy5uYXRpdmVFbGVtZW50LmdldERhdGFVUkwoZm9ybWF0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgdGhlIGJhcmNvZGUgaW1hZ2UgZW5jb2RlZCBhcyBhIEJhc2U2NCBzdHJpbmcsIGFsbG93aW5nIHlvdSB0byBlYXNpbHkgZW1iZWQgb3IgdHJhbnNtaXQgdGhlIGJhcmNvZGUgaW4gZm9ybWF0cyBzdWNoIGFzIEhUTUwsIENTUywgb3IgSlNPTi4gXG5cdCogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdC4gVGhlIGRhdGFVUkwgZm9ybWF0IG9mIHRoZSBzdHJpbmcgLSBzdmcsIHBuZywganBnXG5cdCogQHJldHVybnMge2FueX1cbiAgKi9cblx0cHVibGljIGFzeW5jIGdldERhdGFVUkxBc3luYyhmb3JtYXQpOiBQcm9taXNlPGFueT4ge1xuXHRcdGNvbnN0IGdldFJlc3VsdE9uUmVuZGVyID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlRWxlbWVudC53aGVuUmVuZGVyZWQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLm5hdGl2ZUVsZW1lbnQuZ2V0RGF0YVVSTEFzeW5jKGZvcm1hdCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdldFJlc3VsdE9uUmVuZGVyKCk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cblx0cHVibGljIGdldERhdGFVUkxBc3luY1N5bmMoZm9ybWF0KTogYW55IHtcbiAgICAgICAgaWYgKHRoaXMubmF0aXZlRWxlbWVudC5pc1JlbmRlcmVkKSB7XG4gXHQgICAgICAgcmV0dXJuIHRoaXMubmF0aXZlRWxlbWVudC5nZXREYXRhVVJMQXN5bmMoZm9ybWF0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgdGhlIHZhbGlkYXRpb24gc3RhdHVzIG9mIHRoZSBiYXJjb2RlLCBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHNjYW5uZWQgYmFyY29kZSBtZWV0cyB0aGUgcmVxdWlyZWQgZm9ybWF0IGFuZCBpbnRlZ3JpdHkgY2hlY2tzLiBcblx0KiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgKi9cblx0cHVibGljIGFzeW5jIGlzVmFsaWQoKTogUHJvbWlzZTxhbnk+IHtcblx0XHRjb25zdCBnZXRSZXN1bHRPblJlbmRlciA9ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZUVsZW1lbnQud2hlblJlbmRlcmVkKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5uYXRpdmVFbGVtZW50LmlzVmFsaWQoKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ2V0UmVzdWx0T25SZW5kZXIoKTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuXHRwdWJsaWMgaXNWYWxpZFN5bmMoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLm5hdGl2ZUVsZW1lbnQuaXNSZW5kZXJlZCkge1xuIFx0ICAgICAgIHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQuaXNWYWxpZCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuXG5cdGdldCBpc1JlbmRlcmVkKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQuaXNSZW5kZXJlZCA6IGZhbHNlO1xuXHR9XG5cblx0bmdPbkluaXQoKSB7XG5cdH1cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuXG4gICAgICB0aGF0Lm9uQ3JlYXRlLmVtaXQodGhhdC5uYXRpdmVFbGVtZW50KTtcblxuXHRcdGlmIChTbWFydCkgU21hcnQuUmVuZGVyKCk7XG5cblx0XHR0aGlzLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnc21hcnQtYW5ndWxhcicpO1xuXG5cdFx0aWYgKHRoaXMubmF0aXZlRWxlbWVudC53aGVuUmVuZGVyZWQpIHRoaXMubmF0aXZlRWxlbWVudC53aGVuUmVuZGVyZWQoKCkgPT4geyB0aGF0Lm9uUmVhZHkuZW1pdCh0aGF0Lm5hdGl2ZUVsZW1lbnQpOyB9KTtcblx0XHR0aGlzLmxpc3RlbigpO1xuXHR9XG5cblx0bmdPbkRlc3Ryb3koKSB7XG5cdFx0dGhpcy51bmxpc3RlbigpO1xuXHR9XG5cblx0bmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuXHRcdGlmICh0aGlzLm5hdGl2ZUVsZW1lbnQgJiYgdGhpcy5uYXRpdmVFbGVtZW50LmlzUmVuZGVyZWQpIHtcblx0XHRcdGZvciAoY29uc3QgcHJvcE5hbWUgaW4gY2hhbmdlcykge1xuXHRcdFx0XHRpZiAoY2hhbmdlcy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkpIHtcblx0XHRcdFx0XHR0aGlzLm5hdGl2ZUVsZW1lbnRbcHJvcE5hbWVdID0gY2hhbmdlc1twcm9wTmFtZV0uY3VycmVudFZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBBZGQgZXZlbnQgbGlzdGVuZXJzLiAqL1xuXHRwcml2YXRlIGxpc3RlbigpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG5cdFx0dGhhdC5ldmVudEhhbmRsZXJzWydpbnZhbGlkSGFuZGxlciddID0gKGV2ZW50OiBDdXN0b21FdmVudCkgPT4geyB0aGF0Lm9uSW52YWxpZC5lbWl0KGV2ZW50KTsgfVxuXHRcdHRoYXQubmF0aXZlRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdpbnZhbGlkJywgdGhhdC5ldmVudEhhbmRsZXJzWydpbnZhbGlkSGFuZGxlciddKTtcblxuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBSZW1vdmUgZXZlbnQgbGlzdGVuZXJzLiAqL1xuXHRwcml2YXRlIHVubGlzdGVuKCk6IHZvaWQge1xuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcblx0XHRpZiAodGhhdC5ldmVudEhhbmRsZXJzWydpbnZhbGlkSGFuZGxlciddKSB7XG5cdFx0XHR0aGF0Lm5hdGl2ZUVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignaW52YWxpZCcsIHRoYXQuZXZlbnRIYW5kbGVyc1snaW52YWxpZEhhbmRsZXInXSk7XG5cdFx0fVxuXG5cdH1cbn1cbiJdfQ==