ngx-input-color
Version:
Angular color input component and color picker (with HSL, HSV, RGB, CMYK, HEX, alpha, eye-dropper, etc)
248 lines • 31.5 kB
JavaScript
import { Directive, forwardRef, Input, ElementRef, HostListener, Output, EventEmitter, Inject, } from '@angular/core';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS, } from '@angular/forms';
import { ColorInspector } from '../models/ColorInspector.enum';
import { NgxInputColorComponent } from '../lib/ngx-input-color/ngx-input-color.component';
import { NgxColor } from '../utils/color-helper';
import { DOCUMENT } from '@angular/common';
import * as i0 from "@angular/core";
export class NgxInputColorDirective {
set ngxInputColor(el) {
this.isHostInput = false;
if (el instanceof ElementRef) {
this._targetInput = el.nativeElement;
}
else if (el instanceof HTMLInputElement) {
this.isHostInput = true;
this._targetInput = el;
}
else {
this._targetInput = undefined;
}
if (this._targetInput) {
this._targetInput.addEventListener('input', this.boundInputHandler);
}
}
constructor(_doc, el, renderer, viewContainerRef) {
this._doc = _doc;
this.el = el;
this.renderer = renderer;
this.viewContainerRef = viewContainerRef;
this.setInputBackgroundColor = true;
this.defaultInspector = ColorInspector.Picker;
this.simpleMode = false;
this.outputType = 'HEX';
this.theme = 'auto';
this.boundInputHandler = (e) => {
this.writeValue(e.target.value);
};
this.change = new EventEmitter();
this.isHostInput = false;
this.inValid = false;
this.isDisabled = false;
this._onChange = (value) => { };
this._onTouched = () => { };
this._onValidateChange = () => { };
}
ngAfterViewInit() {
setTimeout(() => {
if (this._targetInput && this._targetInput.tagName.toLowerCase() === 'input') {
this.writeValue(this._targetInput.value);
}
});
}
ngOnDestroy() {
this.destroyColorPicker();
}
onClick(ev) {
ev.stopPropagation();
ev.preventDefault();
this.toggleColorPicker();
}
writeValue(value) {
try {
this.color = value ? new NgxColor(value) : undefined;
const colorStr = this.color?.toHexString() ?? '';
// اگر دایرکتیو روی input باشه (ControlValueAccessor)
if (this.isHostInput) {
const input = this.el.nativeElement;
input.value = colorStr;
}
// اگر input خارجی مشخص شده
if (this._targetInput instanceof HTMLInputElement) {
this._targetInput.value = colorStr;
}
if (this.setInputBackgroundColor && colorStr) {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', colorStr);
}
this.inValid = false;
this._onValidateChange();
}
catch (e) {
this.color = new NgxColor('#000'); // مقدار پیشفرض
this.inValid = true;
}
}
registerOnChange(fn) {
this._onChange = fn;
}
registerOnTouched(fn) {
this._onTouched = fn;
}
setDisabledState(disabled) {
this.isDisabled = disabled;
}
registerOnValidatorChange(fn) {
this._onValidateChange = fn;
}
validate(control) {
if ((this.color && this.color.isValid === false) || this.inValid === true) {
return { invalid: true };
}
return null;
}
toggleColorPicker() {
if (this.colorPickerComponentRef) {
this.destroyColorPicker();
return;
}
this.colorPickerComponentRef = this.viewContainerRef.createComponent(NgxInputColorComponent);
const instance = this.colorPickerComponentRef.instance;
instance.defaultInspector = this.defaultInspector;
instance.simpleMode = this.simpleMode;
instance.outputType = this.outputType;
instance.setTheme = this.theme;
if (this.color?.isValid)
instance.initColor(this.color);
instance.change.subscribe((c) => {
this.emitChange(c);
});
this.backdrop = this.renderer.createElement('div');
if (this.backdrop) {
this.backdrop.className = 'ngx-input-color-backdrop';
this.backdrop.style.cssText = `
background: #5e5e5e1e;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: auto;
transition: all 300ms;
z-index: 9998;
`;
this.backdrop.onclick = () => this.destroyColorPicker();
}
this.colorPickerEl = this.colorPickerComponentRef.hostView.rootNodes[0];
this.renderer.appendChild(this.backdrop, this.colorPickerEl);
this.renderer.appendChild(this._doc.body, this.backdrop);
this.setPosition();
}
setPosition() {
// setTimeout(() => {
if (!this.colorPickerEl)
return;
const hostRect = this.el.nativeElement.getBoundingClientRect();
const pickerEl = this.colorPickerEl;
this.renderer.setStyle(pickerEl, 'position', 'absolute');
this.renderer.setStyle(pickerEl, 'z-index', '9999');
this._doc.body.appendChild(pickerEl);
const pickerRect = pickerEl.getBoundingClientRect();
let left = hostRect.left + hostRect.width / 2 - pickerRect.width / 2;
let top = hostRect.bottom;
if (left + pickerRect.width > window.innerWidth)
left = window.innerWidth - pickerRect.width - 8;
if (left < 8)
left = 8;
if (top + pickerRect.height > window.innerHeight)
top = hostRect.top - pickerRect.height;
if (top < 8)
top = 8;
this.renderer.setStyle(pickerEl, 'top', `${top}px`);
this.renderer.setStyle(pickerEl, 'left', `${left}px`);
// });
}
destroyColorPicker() {
this.colorPickerComponentRef?.destroy();
this.colorPickerComponentRef = undefined;
if (this.backdrop) {
this.renderer.removeChild(this._doc.body, this.backdrop);
this.backdrop = undefined;
}
this.colorPickerEl = undefined;
}
async emitChange(c) {
if (this.setInputBackgroundColor) {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', c);
}
// اگر روی input باشیم، مقدار رو در input قرار بده
if (this.isHostInput) {
const input = this.el.nativeElement;
input.value = c;
}
// اگر targetInput وجود داره، در اونم مقدار ست کن
if (this._targetInput instanceof HTMLInputElement) {
this._targetInput.value = c;
const event = new Event('input', { bubbles: true });
this._targetInput.dispatchEvent(event);
}
this._onChange(c);
this.change.emit(c);
this._onTouched();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgxInputColorDirective, deps: [{ token: DOCUMENT }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: NgxInputColorDirective, selector: "[ngxInputColor]", inputs: { setInputBackgroundColor: "setInputBackgroundColor", defaultInspector: "defaultInspector", simpleMode: "simpleMode", outputType: "outputType", theme: "theme", ngxInputColor: "ngxInputColor" }, outputs: { change: "change" }, host: { listeners: { "click": "onClick($event)", "window:resize": "setPosition()" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgxInputColorDirective),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => NgxInputColorDirective),
multi: true,
},
], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgxInputColorDirective, decorators: [{
type: Directive,
args: [{
selector: '[ngxInputColor]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgxInputColorDirective),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => NgxInputColorDirective),
multi: true,
},
],
}]
}], ctorParameters: () => [{ type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }], propDecorators: { setInputBackgroundColor: [{
type: Input
}], defaultInspector: [{
type: Input
}], simpleMode: [{
type: Input
}], outputType: [{
type: Input
}], theme: [{
type: Input
}], ngxInputColor: [{
type: Input,
args: ['ngxInputColor']
}], change: [{
type: Output
}], onClick: [{
type: HostListener,
args: ['click', ['$event']]
}], setPosition: [{
type: HostListener,
args: ['window:resize']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWlucHV0LWNvbG9yLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1pbnB1dC1jb2xvci9zcmMvZGlyZWN0aXZlcy9uZ3gtaW5wdXQtY29sb3IuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUVWLEtBQUssRUFFTCxVQUFVLEVBR1YsWUFBWSxFQUVaLE1BQU0sRUFDTixZQUFZLEVBQ1osTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsYUFBYSxHQUtkLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQy9ELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQzFGLE9BQU8sRUFBRSxRQUFRLEVBQWMsTUFBTSx1QkFBdUIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBaUIzQyxNQUFNLE9BQU8sc0JBQXNCO0lBV2pDLElBQTRCLGFBQWEsQ0FDdkMsRUFBMkU7UUFFM0UsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7UUFDekIsSUFBSSxFQUFFLFlBQVksVUFBVSxFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDO1FBQ3ZDLENBQUM7YUFBTSxJQUFJLEVBQUUsWUFBWSxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3pCLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLFlBQVksR0FBRyxTQUFTLENBQUM7UUFDaEMsQ0FBQztRQUVELElBQUksSUFBSSxD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LEtBQUssRUFBRSxJQUFJO3lCQUNaO3dCQUNEOzRCQUNFLE9BQU8sRUFBRSxhQUFhOzRCQUN0QixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSx1QkFBdUIsQ0FBQzs0QkFDckQsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7aUJBQ0Y7OzBCQTBDSSxNQUFNOzJCQUFDLFFBQVE7eUhBeENULHVCQUF1QjtzQkFBL0IsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFNc0IsYUFBYTtzQkFBeEMsS0FBSzt1QkFBQyxlQUFlO2dCQWlCWixNQUFNO3NCQUFmLE1BQU07Z0JBK0JQLE9BQU87c0JBRE4sWUFBWTt1QkFBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBcUdqQyxXQUFXO3NCQURWLFlBQVk7dUJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgRGlyZWN0aXZlLFxyXG4gIGZvcndhcmRSZWYsXHJcbiAgT25EZXN0cm95LFxyXG4gIElucHV0LFxyXG4gIENvbXBvbmVudFJlZixcclxuICBFbGVtZW50UmVmLFxyXG4gIFJlbmRlcmVyMixcclxuICBWaWV3Q29udGFpbmVyUmVmLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIE91dHB1dCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5qZWN0LFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gIE5HX1ZBTFVFX0FDQ0VTU09SLFxyXG4gIE5HX1ZBTElEQVRPUlMsXHJcbiAgQ29udHJvbFZhbHVlQWNjZXNzb3IsXHJcbiAgVmFsaWRhdG9yLFxyXG4gIEFic3RyYWN0Q29udHJvbCxcclxuICBWYWxpZGF0aW9uRXJyb3JzLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgQ29sb3JJbnNwZWN0b3IgfSBmcm9tICcuLi9tb2RlbHMvQ29sb3JJbnNwZWN0b3IuZW51bSc7XHJcbmltcG9ydCB7IE5neElucHV0Q29sb3JDb21wb25lbnQgfSBmcm9tICcuLi9saWIvbmd4LWlucHV0LWNvbG9yL25neC1pbnB1dC1jb2xvci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBOZ3hDb2xvciwgT3V0cHV0VHlwZSB9IGZyb20gJy4uL3V0aWxzL2NvbG9yLWhlbHBlcic7XHJcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuXHJcbkBEaXJlY3RpdmUoe1xyXG4gIHNlbGVjdG9yOiAnW25neElucHV0Q29sb3JdJyxcclxuICBwcm92aWRlcnM6IFtcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5neElucHV0Q29sb3JEaXJlY3RpdmUpLFxyXG4gICAgICBtdWx0aTogdHJ1ZSxcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTElEQVRPUlMsXHJcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5neElucHV0Q29sb3JEaXJlY3RpdmUpLFxyXG4gICAgICBtdWx0aTogdHJ1ZSxcclxuICAgIH0sXHJcbiAgXSxcclxufSlcclxuZXhwb3J0IGNsYXNzIE5neElucHV0Q29sb3JEaXJlY3RpdmUgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBWYWxpZGF0b3Ige1xyXG4gIEBJbnB1dCgpIHNldElucHV0QmFja2dyb3VuZENvbG9yID0gdHJ1ZTtcclxuICBASW5wdXQoKSBkZWZhdWx0SW5zcGVjdG9yOiBDb2xvckluc3BlY3RvciA9IENvbG9ySW5zcGVjdG9yLlBpY2tlcjtcclxuICBASW5wdXQoKSBzaW1wbGVNb2RlID0gZmFsc2U7XHJcbiAgQElucHV0KCkgb3V0cHV0VHlwZTogT3V0cHV0VHlwZSA9ICdIRVgnO1xyXG4gIEBJbnB1dCgpIHRoZW1lOiAnbGlnaHQnIHwgJ2RhcmsnIHwgJ2F1dG8nID0gJ2F1dG8nO1xyXG4gIHByaXZhdGUgYm91bmRJbnB1dEhhbmRsZXIgPSAoZTogRXZlbnQpID0+IHtcclxuICAgIHRoaXMud3JpdGVWYWx1ZSgoZS50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkudmFsdWUpO1xyXG4gIH07XHJcbiAgcHJpdmF0ZSBfdGFyZ2V0SW5wdXQ/OiBIVE1MSW5wdXRFbGVtZW50O1xyXG5cclxuICBASW5wdXQoJ25neElucHV0Q29sb3InKSBzZXQgbmd4SW5wdXRDb2xvcihcclxuICAgIGVsOiBIVE1MSW5wdXRFbGVtZW50IHwgRWxlbWVudFJlZjxIVE1MSW5wdXRFbGVtZW50PiB8IG51bGwgfCB1bmRlZmluZWQgfCAnJ1xyXG4gICkge1xyXG4gICAgdGhpcy5pc0hvc3RJbnB1dCA9IGZhbHNlO1xyXG4gICAgaWYgKGVsIGluc3RhbmNlb2YgRWxlbWVudFJlZikge1xyXG4gICAgICB0aGlzLl90YXJnZXRJbnB1dCA9IGVsLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB9IGVsc2UgaWYgKGVsIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkge1xyXG4gICAgICB0aGlzLmlzSG9zdElucHV0ID0gdHJ1ZTtcclxuICAgICAgdGhpcy5fdGFyZ2V0SW5wdXQgPSBlbDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX3RhcmdldElucHV0ID0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl90YXJnZXRJbnB1dCkge1xyXG4gICAgICB0aGlzLl90YXJnZXRJbnB1dC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHRoaXMuYm91bmRJbnB1dEhhbmRsZXIpO1xyXG4gICAgfVxyXG4gIH1cclxuICBAT3V0cHV0KCkgY2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcbiAgcHJpdmF0ZSBjb2xvcj86IE5neENvbG9yO1xyXG4gIHByaXZhdGUgY29sb3JQaWNrZXJDb21wb25lbnRSZWY/OiBDb21wb25lbnRSZWY8Tmd4SW5wdXRDb2xvckNvbXBvbmVudD47XHJcbiAgcHJpdmF0ZSBiYWNrZHJvcD86IEhUTUxEaXZFbGVtZW50O1xyXG4gIHByaXZhdGUgY29sb3JQaWNrZXJFbD86IEhUTUxFbGVtZW50O1xyXG4gIHByaXZhdGUgaXNIb3N0SW5wdXQgPSBmYWxzZTtcclxuICBpblZhbGlkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgaXNEaXNhYmxlZCA9IGZhbHNlO1xyXG4gIF9vbkNoYW5nZSA9ICh2YWx1ZTogc3RyaW5nKSA9PiB7fTtcclxuICBfb25Ub3VjaGVkID0gKCkgPT4ge307XHJcbiAgX29uVmFsaWRhdGVDaGFuZ2UgPSAoKSA9PiB7fTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIF9kb2M6IERvY3VtZW50LFxyXG4gICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcclxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcclxuICAgIHByaXZhdGUgdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZlxyXG4gICkge31cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLl90YXJnZXRJbnB1dCAmJiB0aGlzLl90YXJnZXRJbnB1dC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdpbnB1dCcpIHtcclxuICAgICAgICB0aGlzLndyaXRlVmFsdWUodGhpcy5fdGFyZ2V0SW5wdXQudmFsdWUpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLmRlc3Ryb3lDb2xvclBpY2tlcigpO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignY2xpY2snLCBbJyRldmVudCddKVxyXG4gIG9uQ2xpY2soZXY6IEV2ZW50KSB7XHJcbiAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB0aGlzLnRvZ2dsZUNvbG9yUGlja2VyKCk7XHJcbiAgfVxyXG5cclxuICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIHRoaXMuY29sb3IgPSB2YWx1ZSA/IG5ldyBOZ3hDb2xvcih2YWx1ZSkgOiB1bmRlZmluZWQ7XHJcblxyXG4gICAgICBjb25zdCBjb2xvclN0ciA9IHRoaXMuY29sb3I/LnRvSGV4U3RyaW5nKCkgPz8gJyc7XHJcblxyXG4gICAgICAvLyDYp9qv2LEg2K/Yp9uM2LHaqdiq24zZiCDYsdmI24wgaW5wdXQg2KjYp9i02YcgKENvbnRyb2xWYWx1ZUFjY2Vzc29yKVxyXG4gICAgICBpZiAodGhpcy5pc0hvc3RJbnB1dCkge1xyXG4gICAgICAgIGNvbnN0IGlucHV0ID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcbiAgICAgICAgaW5wdXQudmFsdWUgPSBjb2xvclN0cjtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8g2Kfar9ixIGlucHV0INiu2KfYsdis24wg2YXYtNiu2LUg2LTYr9mHXHJcbiAgICAgIGlmICh0aGlzLl90YXJnZXRJbnB1dCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQpIHtcclxuICAgICAgICB0aGlzLl90YXJnZXRJbnB1dC52YWx1ZSA9IGNvbG9yU3RyO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy5zZXRJbnB1dEJhY2tncm91bmRDb2xvciAmJiBjb2xvclN0cikge1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbC5uYXRpdmVFbGVtZW50LCAnYmFja2dyb3VuZENvbG9yJywgY29sb3JTdHIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLmluVmFsaWQgPSBmYWxzZTtcclxuICAgICAgdGhpcy5fb25WYWxpZGF0ZUNoYW5nZSgpO1xyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICB0aGlzLmNvbG9yID0gbmV3IE5neENvbG9yKCcjMDAwJyk7IC8vINmF2YLYr9in2LEg2b7bjNi04oCM2YHYsdi2XHJcbiAgICAgIHRoaXMuaW5WYWxpZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMuX29uQ2hhbmdlID0gZm47XHJcbiAgfVxyXG5cclxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLl9vblRvdWNoZWQgPSBmbjtcclxuICB9XHJcblxyXG4gIHNldERpc2FibGVkU3RhdGUoZGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIHRoaXMuaXNEaXNhYmxlZCA9IGRpc2FibGVkO1xyXG4gIH1cclxuXHJcbiAgcmVnaXN0ZXJPblZhbGlkYXRvckNoYW5nZShmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgdGhpcy5fb25WYWxpZGF0ZUNoYW5nZSA9IGZuO1xyXG4gIH1cclxuXHJcbiAgdmFsaWRhdGUoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xyXG4gICAgaWYgKCh0aGlzLmNvbG9yICYmIHRoaXMuY29sb3IuaXNWYWxpZCA9PT0gZmFsc2UpIHx8IHRoaXMuaW5WYWxpZCA9PT0gdHJ1ZSkge1xyXG4gICAgICByZXR1cm4geyBpbnZhbGlkOiB0cnVlIH07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdG9nZ2xlQ29sb3JQaWNrZXIoKSB7XHJcbiAgICBpZiAodGhpcy5jb2xvclBpY2tlckNvbXBvbmVudFJlZikge1xyXG4gICAgICB0aGlzLmRlc3Ryb3lDb2xvclBpY2tlcigpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5jb2xvclBpY2tlckNvbXBvbmVudFJlZiA9IHRoaXMudmlld0NvbnRhaW5lclJlZi5jcmVhdGVDb21wb25lbnQoTmd4SW5wdXRDb2xvckNvbXBvbmVudCk7XHJcbiAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMuY29sb3JQaWNrZXJDb21wb25lbnRSZWYuaW5zdGFuY2U7XHJcblxyXG4gICAgaW5zdGFuY2UuZGVmYXVsdEluc3BlY3RvciA9IHRoaXMuZGVmYXVsdEluc3BlY3RvcjtcclxuICAgIGluc3RhbmNlLnNpbXBsZU1vZGUgPSB0aGlzLnNpbXBsZU1vZGU7XHJcbiAgICBpbnN0YW5jZS5vdXRwdXRUeXBlID0gdGhpcy5vdXRwdXRUeXBlO1xyXG4gICAgaW5zdGFuY2Uuc2V0VGhlbWUgPSB0aGlzLnRoZW1lO1xyXG5cclxuICAgIGlmICh0aGlzLmNvbG9yPy5pc1ZhbGlkKSBpbnN0YW5jZS5pbml0Q29sb3IodGhpcy5jb2xvcik7XHJcbiAgICBpbnN0YW5jZS5jaGFuZ2Uuc3Vic2NyaWJlKChjOiBzdHJpbmcpID0+IHtcclxuICAgICAgdGhpcy5lbWl0Q2hhbmdlKGMpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5iYWNrZHJvcCA9IHRoaXMucmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICBpZiAodGhpcy5iYWNrZHJvcCkge1xyXG4gICAgICB0aGlzLmJhY2tkcm9wLmNsYXNzTmFtZSA9ICduZ3gtaW5wdXQtY29sb3ItYmFja2Ryb3AnO1xyXG4gICAgICB0aGlzLmJhY2tkcm9wLnN0eWxlLmNzc1RleHQgPSBgXHJcbiAgICAgICAgICBiYWNrZ3JvdW5kOiAjNWU1ZTVlMWU7XHJcbiAgICAgICAgICBwb3NpdGlvbjogZml4ZWQ7XHJcbiAgICAgICAgICB0b3A6IDA7XHJcbiAgICAgICAgICBsZWZ0OiAwO1xyXG4gICAgICAgICAgcmlnaHQ6IDA7XHJcbiAgICAgICAgICBib3R0b206IDA7XHJcbiAgICAgICAgICBvdmVyZmxvdzogYXV0bztcclxuICAgICAgICAgIHRyYW5zaXRpb246IGFsbCAzMDBtcztcclxuICAgICAgICAgIHotaW5kZXg6IDk5OTg7XHJcbiAgICAgICAgYDtcclxuICAgICAgdGhpcy5iYWNrZHJvcC5vbmNsaWNrID0gKCkgPT4gdGhpcy5kZXN0cm95Q29sb3JQaWNrZXIoKTtcclxuICAgIH1cclxuICAgIHRoaXMuY29sb3JQaWNrZXJFbCA9ICh0aGlzLmNvbG9yUGlja2VyQ29tcG9uZW50UmVmLmhvc3RWaWV3IGFzIGFueSkucm9vdE5vZGVzWzBdIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLmJhY2tkcm9wLCB0aGlzLmNvbG9yUGlja2VyRWwpO1xyXG4gICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLl9kb2MuYm9keSwgdGhpcy5iYWNrZHJvcCk7XHJcbiAgICB0aGlzLnNldFBvc2l0aW9uKCk7XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJylcclxuICBzZXRQb3NpdGlvbigpIHtcclxuICAgIC8vIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgaWYgKCF0aGlzLmNvbG9yUGlja2VyRWwpIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBob3N0UmVjdCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIGNvbnN0IHBpY2tlckVsID0gdGhpcy5jb2xvclBpY2tlckVsO1xyXG5cclxuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUocGlja2VyRWwsICdwb3NpdGlvbicsICdhYnNvbHV0ZScpO1xyXG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShwaWNrZXJFbCwgJ3otaW5kZXgnLCAnOTk5OScpO1xyXG5cclxuICAgIHRoaXMuX2RvYy5ib2R5LmFwcGVuZENoaWxkKHBpY2tlckVsKTtcclxuICAgIGNvbnN0IHBpY2tlclJlY3QgPSBwaWNrZXJFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgICBsZXQgbGVmdCA9IGhvc3RSZWN0LmxlZnQgKyBob3N0UmVjdC53aWR0aCAvIDIgLSBwaWNrZXJSZWN0LndpZHRoIC8gMjtcclxuICAgIGxldCB0b3AgPSBob3N0UmVjdC5ib3R0b207XHJcblxyXG4gICAgaWYgKGxlZnQgKyBwaWNrZXJSZWN0LndpZHRoID4gd2luZG93LmlubmVyV2lkdGgpIGxlZnQgPSB3aW5kb3cuaW5uZXJXaWR0aCAtIHBpY2tlclJlY3Qud2lkdGggLSA4O1xyXG4gICAgaWYgKGxlZnQgPCA4KSBsZWZ0ID0gODtcclxuICAgIGlmICh0b3AgKyBwaWNrZXJSZWN0LmhlaWdodCA+IHdpbmRvdy5pbm5lckhlaWdodCkgdG9wID0gaG9zdFJlY3QudG9wIC0gcGlja2VyUmVjdC5oZWlnaHQ7XHJcbiAgICBpZiAodG9wIDwgOCkgdG9wID0gODtcclxuXHJcbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHBpY2tlckVsLCAndG9wJywgYCR7dG9wfXB4YCk7XHJcbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHBpY2tlckVsLCAnbGVmdCcsIGAke2xlZnR9cHhgKTtcclxuICAgIC8vIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkZXN0cm95Q29sb3JQaWNrZXIoKSB7XHJcbiAgICB0aGlzLmNvbG9yUGlja2VyQ29tcG9uZW50UmVmPy5kZXN0cm95KCk7XHJcbiAgICB0aGlzLmNvbG9yUGlja2VyQ29tcG9uZW50UmVmID0gdW5kZWZpbmVkO1xyXG5cclxuICAgIGlmICh0aGlzLmJhY2tkcm9wKSB7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2hpbGQodGhpcy5fZG9jLmJvZHksIHRoaXMuYmFja2Ryb3ApO1xyXG4gICAgICB0aGlzLmJhY2tkcm9wID0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuY29sb3JQaWNrZXJFbCA9IHVuZGVmaW5lZDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgZW1pdENoYW5nZShjOiBzdHJpbmcpIHtcclxuICAgIGlmICh0aGlzLnNldElucHV0QmFja2dyb3VuZENvbG9yKSB7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbC5uYXRpdmVFbGVtZW50LCAnYmFja2dyb3VuZENvbG9yJywgYyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g2Kfar9ixINix2YjbjCBpbnB1dCDYqNin2LTbjNmF2Iwg2YXZgtiv2KfYsSDYsdmIINiv2LEgaW5wdXQg2YLYsdin2LEg2KjYr9mHXHJcbiAgICBpZiAodGhpcy5pc0hvc3RJbnB1dCkge1xyXG4gICAgICBjb25zdCBpbnB1dCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudCBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG4gICAgICBpbnB1dC52YWx1ZSA9IGM7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g2Kfar9ixIHRhcmdldElucHV0INmI2KzZiNivINiv2KfYsdmH2Iwg2K/YsSDYp9mI2YbZhSDZhdmC2K/Yp9ixINiz2Kog2qnZhlxyXG4gICAgaWYgKHRoaXMuX3RhcmdldElucHV0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkge1xyXG4gICAgICB0aGlzLl90YXJnZXRJbnB1dC52YWx1ZSA9IGM7XHJcbiAgICAgIGNvbnN0IGV2ZW50ID0gbmV3IEV2ZW50KCdpbnB1dCcsIHsgYnViYmxlczogdHJ1ZSB9KTtcclxuICAgICAgdGhpcy5fdGFyZ2V0SW5wdXQuZGlzcGF0Y2hFdmVudChldmVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fb25DaGFuZ2UoYyk7XHJcbiAgICB0aGlzLmNoYW5nZS5lbWl0KGMpO1xyXG4gICAgdGhpcy5fb25Ub3VjaGVkKCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==