cm-angular-tooltip
Version:
Tooltip for Angular
207 lines • 33.1 kB
JavaScript
import { Component, HostListener, HostBinding, Input, EventEmitter } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class TooltipComponent {
transitionEnd(event) {
if (this.show) {
this.events.emit({
type: 'shown'
});
}
}
set show(value) {
if (value) {
this.setPosition();
}
this._show = this.hostClassShow = value;
}
get show() {
return this._show;
}
get placement() {
return this.data.options.placement;
}
get autoPlacement() {
return this.data.options.autoPlacement;
}
get element() {
return this.data.element;
}
get elementPosition() {
return this.data.elementPosition;
}
get options() {
return this.data.options;
}
get value() {
return this.data.value;
}
get tooltipOffset() {
return Number(this.data.options.offset);
}
get isThemeLight() {
return this.options['theme'] === 'light';
}
constructor(elementRef, renderer) {
this.elementRef = elementRef;
this.renderer = renderer;
this._show = false;
this.events = new EventEmitter();
}
ngOnInit() {
this.setCustomClass();
this.setStyles();
}
setPosition() {
if (this.setHostStyle(this.placement)) {
this.setPlacementClass(this.placement);
return;
}
else {
/* Is tooltip outside the visible area */
const placements = ['top', 'right', 'bottom', 'left'];
let isPlacementSet;
for (const placement of placements) {
if (this.setHostStyle(placement)) {
this.setPlacementClass(placement);
isPlacementSet = true;
return;
}
}
/* Set original placement */
if (!isPlacementSet) {
this.setHostStyle(this.placement, true);
this.setPlacementClass(this.placement);
}
}
}
setPlacementClass(placement) {
this.renderer.addClass(this.elementRef.nativeElement, 'tooltip-' + placement);
}
setHostStyle(placement, disableAutoPlacement = false) {
const isSvg = this.element instanceof SVGElement;
const tooltip = this.elementRef.nativeElement;
const isCustomPosition = !this.elementPosition.right;
let elementHeight = isSvg ? this.element.getBoundingClientRect().height : this.element.offsetHeight;
let elementWidth = isSvg ? this.element.getBoundingClientRect().width : this.element.offsetWidth;
const tooltipHeight = tooltip.clientHeight;
const tooltipWidth = tooltip.clientWidth;
const scrollY = window.pageYOffset;
if (isCustomPosition) {
elementHeight = 0;
elementWidth = 0;
}
let topStyle;
let leftStyle;
if (placement === 'top') {
topStyle = (this.elementPosition.top + scrollY) - (tooltipHeight + this.tooltipOffset);
}
if (placement === 'bottom') {
topStyle = (this.elementPosition.top + scrollY) + elementHeight + this.tooltipOffset;
}
if (placement === 'top' || placement === 'bottom') {
leftStyle = (this.elementPosition.left + elementWidth / 2) - tooltipWidth / 2;
}
if (placement === 'left') {
leftStyle = this.elementPosition.left - tooltipWidth - this.tooltipOffset;
}
if (placement === 'right') {
leftStyle = this.elementPosition.left + elementWidth + this.tooltipOffset;
}
if (placement === 'left' || placement === 'right') {
topStyle = (this.elementPosition.top + scrollY) + elementHeight / 2 - tooltip.clientHeight / 2;
}
/* Is tooltip outside the visible area */
if (this.autoPlacement && !disableAutoPlacement) {
const topEdge = topStyle;
const bottomEdge = topStyle + tooltipHeight;
const leftEdge = leftStyle;
const rightEdge = leftStyle + tooltipWidth;
const bodyHeight = window.innerHeight + scrollY;
const bodyWidth = document.body.clientWidth;
if (topEdge < 0 || bottomEdge > bodyHeight || leftEdge < 0 || rightEdge > bodyWidth) {
return false;
}
}
this.hostStyleTop = topStyle + 'px';
this.hostStyleLeft = leftStyle + 'px';
return true;
}
setZIndex() {
if (this.options['zIndex'] !== 0) {
this.hostStyleZIndex = this.options['zIndex'];
}
}
setPointerEvents() {
if (this.options['pointerEvents']) {
this.hostStylePointerEvents = this.options['pointerEvents'];
}
}
setCustomClass() {
if (this.options['tooltipClass']) {
this.options['tooltipClass'].split(' ').forEach((className) => {
this.renderer.addClass(this.elementRef.nativeElement, className);
});
}
}
setAnimationDuration() {
if (Number(this.options['animationDuration']) != this.options['animationDurationDefault']) {
this.hostStyleTransition = 'opacity ' + this.options['animationDuration'] + 'ms';
}
}
setStyles() {
this.setZIndex();
this.setPointerEvents();
this.setAnimationDuration();
this.hostClassShadow = this.options['shadow'];
this.hostClassLight = this.isThemeLight;
this.hostStyleMaxWidth = this.options['maxWidth'];
this.hostStyleWidth = this.options['width'] ? this.options['width'] : '';
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TooltipComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TooltipComponent, selector: "tooltip", inputs: { data: "data", show: "show" }, host: { listeners: { "transitionend": "transitionEnd($event)" }, properties: { "style.top": "this.hostStyleTop", "style.left": "this.hostStyleLeft", "style.z-index": "this.hostStyleZIndex", "style.transition": "this.hostStyleTransition", "style.width": "this.hostStyleWidth", "style.max-width": "this.hostStyleMaxWidth", "style.pointer-events": "this.hostStylePointerEvents", "class.tooltip-show": "this.hostClassShow", "class.tooltip-shadow": "this.hostClassShadow", "class.tooltip-light": "this.hostClassLight" }, classAttribute: "tooltip" }, ngImport: i0, template: "<div *ngIf=\"isThemeLight\" class=\"tooltip-arrow\"></div>\r\n\r\n<div *ngIf=\"options['contentType'] === 'template' else htmlOrStringTemplate\">\r\n\r\n\t<ng-container *ngTemplateOutlet=\"value\"></ng-container>\r\n</div>\r\n\r\n<ng-template #htmlOrStringTemplate>\r\n\t<div [innerHTML]=\"value\"></div>\r\n</ng-template>", styles: [":host{max-width:200px;background-color:#000;color:#fff;text-align:center;border-radius:6px;padding:5px 8px;position:absolute;pointer-events:none;z-index:1000;display:block;opacity:0;-webkit-transition:opacity .3s;-moz-transition:opacity .3s;-o-transition:opacity .3s;transition:opacity .3s;top:0;left:0}:host.tooltip-show{opacity:1}:host.tooltip-shadow{box-shadow:0 7px 15px -5px #0006}:host.tooltip-light.tooltip-shadow{box-shadow:0 5px 15px -5px #0006}:host.tooltip:after{content:\"\";position:absolute;border-style:solid}:host.tooltip-top:after{top:100%;left:50%;margin-left:-5px;border-width:5px;border-color:black transparent transparent transparent}:host.tooltip-bottom:after{bottom:100%;left:50%;margin-left:-5px;border-width:5px;border-color:transparent transparent black transparent}:host.tooltip-left:after{top:50%;left:100%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent black}:host.tooltip-right:after{top:50%;right:100%;margin-top:-5px;border-width:5px;border-color:transparent black transparent transparent}:host.tooltip-light:after{display:none}:host.tooltip-light{border:1px solid rgba(0,0,0,.06);background-color:#fff;color:#000}:host.tooltip-light .tooltip-arrow{position:absolute;width:10px;height:10px;transform:rotate(135deg);background-color:#00000012}:host.tooltip-light .tooltip-arrow:after{background-color:#fff;content:\"\";display:block;position:absolute;width:10px;height:10px}:host.tooltip-top.tooltip-light{margin-top:-2px}:host.tooltip-top.tooltip-light .tooltip-arrow{top:100%;left:50%;margin-top:-4px;margin-left:-5px;background:linear-gradient(to bottom left,rgba(0,0,0,.07) 50%,transparent 50%)}:host.tooltip-top.tooltip-light .tooltip-arrow:after{top:1px;right:1px}:host.tooltip-bottom.tooltip-light .tooltip-arrow{bottom:100%;left:50%;margin-bottom:-4px;margin-left:-5px;background:linear-gradient(to top right,rgba(0,0,0,.1) 50%,transparent 50%)}:host.tooltip-bottom.tooltip-light .tooltip-arrow:after{top:-1px;right:-1px}:host.tooltip-left.tooltip-light .tooltip-arrow{top:50%;left:100%;margin-top:-5px;margin-left:-4px;background:linear-gradient(to bottom right,rgba(0,0,0,.07) 50%,transparent 50%)}:host.tooltip-left.tooltip-light .tooltip-arrow:after{top:1px;right:-1px}:host.tooltip-right.tooltip-light .tooltip-arrow{top:50%;right:100%;margin-top:-5px;margin-right:-4px;background:linear-gradient(to top left,rgba(0,0,0,.07) 50%,transparent 50%)}:host.tooltip-right.tooltip-light .tooltip-arrow:after{top:-1px;right:1px}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TooltipComponent, decorators: [{
type: Component,
args: [{ selector: 'tooltip', host: {
'class': 'tooltip'
}, template: "<div *ngIf=\"isThemeLight\" class=\"tooltip-arrow\"></div>\r\n\r\n<div *ngIf=\"options['contentType'] === 'template' else htmlOrStringTemplate\">\r\n\r\n\t<ng-container *ngTemplateOutlet=\"value\"></ng-container>\r\n</div>\r\n\r\n<ng-template #htmlOrStringTemplate>\r\n\t<div [innerHTML]=\"value\"></div>\r\n</ng-template>", styles: [":host{max-width:200px;background-color:#000;color:#fff;text-align:center;border-radius:6px;padding:5px 8px;position:absolute;pointer-events:none;z-index:1000;display:block;opacity:0;-webkit-transition:opacity .3s;-moz-transition:opacity .3s;-o-transition:opacity .3s;transition:opacity .3s;top:0;left:0}:host.tooltip-show{opacity:1}:host.tooltip-shadow{box-shadow:0 7px 15px -5px #0006}:host.tooltip-light.tooltip-shadow{box-shadow:0 5px 15px -5px #0006}:host.tooltip:after{content:\"\";position:absolute;border-style:solid}:host.tooltip-top:after{top:100%;left:50%;margin-left:-5px;border-width:5px;border-color:black transparent transparent transparent}:host.tooltip-bottom:after{bottom:100%;left:50%;margin-left:-5px;border-width:5px;border-color:transparent transparent black transparent}:host.tooltip-left:after{top:50%;left:100%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent black}:host.tooltip-right:after{top:50%;right:100%;margin-top:-5px;border-width:5px;border-color:transparent black transparent transparent}:host.tooltip-light:after{display:none}:host.tooltip-light{border:1px solid rgba(0,0,0,.06);background-color:#fff;color:#000}:host.tooltip-light .tooltip-arrow{position:absolute;width:10px;height:10px;transform:rotate(135deg);background-color:#00000012}:host.tooltip-light .tooltip-arrow:after{background-color:#fff;content:\"\";display:block;position:absolute;width:10px;height:10px}:host.tooltip-top.tooltip-light{margin-top:-2px}:host.tooltip-top.tooltip-light .tooltip-arrow{top:100%;left:50%;margin-top:-4px;margin-left:-5px;background:linear-gradient(to bottom left,rgba(0,0,0,.07) 50%,transparent 50%)}:host.tooltip-top.tooltip-light .tooltip-arrow:after{top:1px;right:1px}:host.tooltip-bottom.tooltip-light .tooltip-arrow{bottom:100%;left:50%;margin-bottom:-4px;margin-left:-5px;background:linear-gradient(to top right,rgba(0,0,0,.1) 50%,transparent 50%)}:host.tooltip-bottom.tooltip-light .tooltip-arrow:after{top:-1px;right:-1px}:host.tooltip-left.tooltip-light .tooltip-arrow{top:50%;left:100%;margin-top:-5px;margin-left:-4px;background:linear-gradient(to bottom right,rgba(0,0,0,.07) 50%,transparent 50%)}:host.tooltip-left.tooltip-light .tooltip-arrow:after{top:1px;right:-1px}:host.tooltip-right.tooltip-light .tooltip-arrow{top:50%;right:100%;margin-top:-5px;margin-right:-4px;background:linear-gradient(to top left,rgba(0,0,0,.07) 50%,transparent 50%)}:host.tooltip-right.tooltip-light .tooltip-arrow:after{top:-1px;right:1px}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { data: [{
type: Input
}], hostStyleTop: [{
type: HostBinding,
args: ['style.top']
}], hostStyleLeft: [{
type: HostBinding,
args: ['style.left']
}], hostStyleZIndex: [{
type: HostBinding,
args: ['style.z-index']
}], hostStyleTransition: [{
type: HostBinding,
args: ['style.transition']
}], hostStyleWidth: [{
type: HostBinding,
args: ['style.width']
}], hostStyleMaxWidth: [{
type: HostBinding,
args: ['style.max-width']
}], hostStylePointerEvents: [{
type: HostBinding,
args: ['style.pointer-events']
}], hostClassShow: [{
type: HostBinding,
args: ['class.tooltip-show']
}], hostClassShadow: [{
type: HostBinding,
args: ['class.tooltip-shadow']
}], hostClassLight: [{
type: HostBinding,
args: ['class.tooltip-light']
}], transitionEnd: [{
type: HostListener,
args: ['transitionend', ['$event']]
}], show: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHRpcC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jbS1hbmd1bGFyLXRvb2x0aXAvc3JjL2xpYi90b29sdGlwLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NtLWFuZ3VsYXItdG9vbHRpcC9zcmMvbGliL3Rvb2x0aXAuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBYyxZQUFZLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBVSxZQUFZLEVBQWEsTUFBTSxlQUFlLENBQUM7OztBQVd6SCxNQUFNLE9BQU8sZ0JBQWdCO0lBa0J6QixhQUFhLENBQUMsS0FBVTtRQUNwQixJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNaLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO2dCQUNiLElBQUksRUFBRSxPQUFPO2FBQ2hCLENBQUMsQ0FBQztRQUNQLENBQUM7SUFDTCxDQUFDO0lBRUQsSUFBYSxJQUFJLENBQUMsS0FBYztRQUM1QixJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZCLENBQUM7UUFDRCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO0lBQzVDLENBQUM7SUFDRCxJQUFJLElBQUk7UUFDSixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDdEIsQ0FBQztJQUVELElBQUksU0FBUztRQUNULE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxJQUFJLGFBQWE7UUFDYixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQztJQUMzQyxDQUFDO0lBRUQsSUFBSSxPQUFPO1FBQ1AsT0FBTyxJQUFJLENBQUMsSUFBSSxD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IEhvc3RMaXN0ZW5lciwgSG9zdEJpbmRpbmcsIElucHV0LCBPbkluaXQsIEV2ZW50RW1pdHRlciwgUmVuZGVyZXIyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAndG9vbHRpcCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vdG9vbHRpcC5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBob3N0OiB7XHJcbiAgICAgICAgJ2NsYXNzJzogJ3Rvb2x0aXAnXHJcbiAgICB9LFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vdG9vbHRpcC5jb21wb25lbnQuc2FzcyddXHJcbn0pXHJcblxyXG5leHBvcnQgY2xhc3MgVG9vbHRpcENvbXBvbmVudCB7XHJcbiAgICBfc2hvdzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgZXZlbnRzID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICAgIEBJbnB1dCgpIGRhdGE6IGFueTtcclxuXHJcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLnRvcCcpIGhvc3RTdHlsZVRvcCE6IHN0cmluZztcclxuICAgIEBIb3N0QmluZGluZygnc3R5bGUubGVmdCcpIGhvc3RTdHlsZUxlZnQhOiBzdHJpbmc7XHJcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLnotaW5kZXgnKSBob3N0U3R5bGVaSW5kZXghOiBudW1iZXI7XHJcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLnRyYW5zaXRpb24nKSBob3N0U3R5bGVUcmFuc2l0aW9uITogc3RyaW5nO1xyXG4gICAgQEhvc3RCaW5kaW5nKCdzdHlsZS53aWR0aCcpIGhvc3RTdHlsZVdpZHRoITogc3RyaW5nO1xyXG4gICAgQEhvc3RCaW5kaW5nKCdzdHlsZS5tYXgtd2lkdGgnKSBob3N0U3R5bGVNYXhXaWR0aCE6IHN0cmluZztcclxuICAgIEBIb3N0QmluZGluZygnc3R5bGUucG9pbnRlci1ldmVudHMnKSBob3N0U3R5bGVQb2ludGVyRXZlbnRzITogc3RyaW5nO1xyXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy50b29sdGlwLXNob3cnKSBob3N0Q2xhc3NTaG93ITogYm9vbGVhbjtcclxuICAgIEBIb3N0QmluZGluZygnY2xhc3MudG9vbHRpcC1zaGFkb3cnKSBob3N0Q2xhc3NTaGFkb3chOiBib29sZWFuO1xyXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy50b29sdGlwLWxpZ2h0JykgaG9zdENsYXNzTGlnaHQhOiBib29sZWFuO1xyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCBbJyRldmVudCddKVxyXG4gICAgdHJhbnNpdGlvbkVuZChldmVudDogYW55KSB7XHJcbiAgICAgICAgaWYgKHRoaXMuc2hvdykge1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHtcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdzaG93bidcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEBJbnB1dCgpIHNldCBzaG93KHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0UG9zaXRpb24oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fc2hvdyA9IHRoaXMuaG9zdENsYXNzU2hvdyA9IHZhbHVlO1xyXG4gICAgfVxyXG4gICAgZ2V0IHNob3coKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Nob3c7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHBsYWNlbWVudCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhLm9wdGlvbnMucGxhY2VtZW50O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBhdXRvUGxhY2VtZW50KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEub3B0aW9ucy5hdXRvUGxhY2VtZW50O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBlbGVtZW50KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEuZWxlbWVudDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgZWxlbWVudFBvc2l0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEuZWxlbWVudFBvc2l0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBvcHRpb25zKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEub3B0aW9ucztcclxuICAgIH1cclxuXHJcbiAgICBnZXQgdmFsdWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgdG9vbHRpcE9mZnNldCgpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiBOdW1iZXIodGhpcy5kYXRhLm9wdGlvbnMub2Zmc2V0KTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgaXNUaGVtZUxpZ2h0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnNbJ3RoZW1lJ10gPT09ICdsaWdodCc7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLCBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIpIHsgfVxyXG5cclxuICAgIG5nT25Jbml0KCkge1xyXG4gICAgICAgIHRoaXMuc2V0Q3VzdG9tQ2xhc3MoKTtcclxuICAgICAgICB0aGlzLnNldFN0eWxlcygpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldFBvc2l0aW9uKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLnNldEhvc3RTdHlsZSh0aGlzLnBsYWNlbWVudCkpIHtcclxuICAgICAgICAgICAgdGhpcy5zZXRQbGFjZW1lbnRDbGFzcyh0aGlzLnBsYWNlbWVudCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvKiBJcyB0b29sdGlwIG91dHNpZGUgdGhlIHZpc2libGUgYXJlYSAqL1xyXG4gICAgICAgICAgICBjb25zdCBwbGFjZW1lbnRzID0gWyd0b3AnLCAncmlnaHQnLCAnYm90dG9tJywgJ2xlZnQnXTtcclxuICAgICAgICAgICAgbGV0IGlzUGxhY2VtZW50U2V0O1xyXG5cclxuICAgICAgICAgICAgZm9yIChjb25zdCBwbGFjZW1lbnQgb2YgcGxhY2VtZW50cykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0SG9zdFN0eWxlKHBsYWNlbWVudCkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFBsYWNlbWVudENsYXNzKHBsYWNlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaXNQbGFjZW1lbnRTZXQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyogU2V0IG9yaWdpbmFsIHBsYWNlbWVudCAqL1xyXG4gICAgICAgICAgICBpZiAoIWlzUGxhY2VtZW50U2V0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldEhvc3RTdHlsZSh0aGlzLnBsYWNlbWVudCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldFBsYWNlbWVudENsYXNzKHRoaXMucGxhY2VtZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG4gICAgc2V0UGxhY2VtZW50Q2xhc3MocGxhY2VtZW50OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAndG9vbHRpcC0nICsgcGxhY2VtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICBzZXRIb3N0U3R5bGUocGxhY2VtZW50OiBzdHJpbmcsIGRpc2FibGVBdXRvUGxhY2VtZW50OiBib29sZWFuID0gZmFsc2UpOiBib29sZWFuIHtcclxuICAgICAgICBjb25zdCBpc1N2ZyA9IHRoaXMuZWxlbWVudCBpbnN0YW5jZW9mIFNWR0VsZW1lbnQ7XHJcbiAgICAgICAgY29uc3QgdG9vbHRpcCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgIGNvbnN0IGlzQ3VzdG9tUG9zaXRpb24gPSAhdGhpcy5lbGVtZW50UG9zaXRpb24ucmlnaHQ7XHJcblxyXG4gICAgICAgIGxldCBlbGVtZW50SGVpZ2h0ID0gaXNTdmcgPyB0aGlzLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0IDogdGhpcy5lbGVtZW50Lm9mZnNldEhlaWdodDtcclxuICAgICAgICBsZXQgZWxlbWVudFdpZHRoID0gaXNTdmcgPyB0aGlzLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGggOiB0aGlzLmVsZW1lbnQub2Zmc2V0V2lkdGg7XHJcbiAgICAgICAgY29uc3QgdG9vbHRpcEhlaWdodCA9IHRvb2x0aXAuY2xpZW50SGVpZ2h0O1xyXG4gICAgICAgIGNvbnN0IHRvb2x0aXBXaWR0aCA9IHRvb2x0aXAuY2xpZW50V2lkdGg7XHJcbiAgICAgICAgY29uc3Qgc2Nyb2xsWSA9IHdpbmRvdy5wYWdlWU9mZnNldDtcclxuXHJcbiAgICAgICAgaWYgKGlzQ3VzdG9tUG9zaXRpb24pIHtcclxuICAgICAgICAgICAgZWxlbWVudEhlaWdodCA9IDA7XHJcbiAgICAgICAgICAgIGVsZW1lbnRXaWR0aCA9IDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgdG9wU3R5bGU7XHJcbiAgICAgICAgbGV0IGxlZnRTdHlsZTtcclxuXHJcbiAgICAgICAgaWYgKHBsYWNlbWVudCA9PT0gJ3RvcCcpIHtcclxuICAgICAgICAgICAgdG9wU3R5bGUgPSAodGhpcy5lbGVtZW50UG9zaXRpb24udG9wICsgc2Nyb2xsWSkgLSAodG9vbHRpcEhlaWdodCArIHRoaXMudG9vbHRpcE9mZnNldCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGxhY2VtZW50ID09PSAnYm90dG9tJykge1xyXG4gICAgICAgICAgICB0b3BTdHlsZSA9ICh0aGlzLmVsZW1lbnRQb3NpdGlvbi50b3AgKyBzY3JvbGxZKSArIGVsZW1lbnRIZWlnaHQgKyB0aGlzLnRvb2x0aXBPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGxhY2VtZW50ID09PSAndG9wJyB8fCBwbGFjZW1lbnQgPT09ICdib3R0b20nKSB7XHJcbiAgICAgICAgICAgIGxlZnRTdHlsZSA9ICh0aGlzLmVsZW1lbnRQb3NpdGlvbi5sZWZ0ICsgZWxlbWVudFdpZHRoIC8gMikgLSB0b29sdGlwV2lkdGggLyAyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBsYWNlbWVudCA9PT0gJ2xlZnQnKSB7XHJcbiAgICAgICAgICAgIGxlZnRTdHlsZSA9IHRoaXMuZWxlbWVudFBvc2l0aW9uLmxlZnQgLSB0b29sdGlwV2lkdGggLSB0aGlzLnRvb2x0aXBPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGxhY2VtZW50ID09PSAncmlnaHQnKSB7XHJcbiAgICAgICAgICAgIGxlZnRTdHlsZSA9IHRoaXMuZWxlbWVudFBvc2l0aW9uLmxlZnQgKyBlbGVtZW50V2lkdGggKyB0aGlzLnRvb2x0aXBPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGxhY2VtZW50ID09PSAnbGVmdCcgfHwgcGxhY2VtZW50ID09PSAncmlnaHQnKSB7XHJcbiAgICAgICAgICAgIHRvcFN0eWxlID0gKHRoaXMuZWxlbWVudFBvc2l0aW9uLnRvcCArIHNjcm9sbFkpICsgZWxlbWVudEhlaWdodCAvIDIgLSB0b29sdGlwLmNsaWVudEhlaWdodCAvIDI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBJcyB0b29sdGlwIG91dHNpZGUgdGhlIHZpc2libGUgYXJlYSAqL1xyXG4gICAgICAgIGlmICh0aGlzLmF1dG9QbGFjZW1lbnQgJiYgIWRpc2FibGVBdXRvUGxhY2VtZW50KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRvcEVkZ2UgPSB0b3BTdHlsZTtcclxuICAgICAgICAgICAgY29uc3QgYm90dG9tRWRnZSA9IHRvcFN0eWxlICsgdG9vbHRpcEhlaWdodDtcclxuICAgICAgICAgICAgY29uc3QgbGVmdEVkZ2UgPSBsZWZ0U3R5bGU7XHJcbiAgICAgICAgICAgIGNvbnN0IHJpZ2h0RWRnZSA9IGxlZnRTdHlsZSArIHRvb2x0aXBXaWR0aDtcclxuICAgICAgICAgICAgY29uc3QgYm9keUhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodCArIHNjcm9sbFk7XHJcbiAgICAgICAgICAgIGNvbnN0IGJvZHlXaWR0aCA9IGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGg7XHJcblxyXG4gICAgICAgICAgICBpZiAodG9wRWRnZSA8IDAgfHwgYm90dG9tRWRnZSA+IGJvZHlIZWlnaHQgfHwgbGVmdEVkZ2UgPCAwIHx8IHJpZ2h0RWRnZSA+IGJvZHlXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmhvc3RTdHlsZVRvcCA9IHRvcFN0eWxlICsgJ3B4JztcclxuICAgICAgICB0aGlzLmhvc3RTdHlsZUxlZnQgPSBsZWZ0U3R5bGUgKyAncHgnO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHNldFpJbmRleCgpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5vcHRpb25zWyd6SW5kZXgnXSAhPT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLmhvc3RTdHlsZVpJbmRleCA9IHRoaXMub3B0aW9uc1snekluZGV4J107XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHNldFBvaW50ZXJFdmVudHMoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9uc1sncG9pbnRlckV2ZW50cyddKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaG9zdFN0eWxlUG9pbnRlckV2ZW50cyA9IHRoaXMub3B0aW9uc1sncG9pbnRlckV2ZW50cyddO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzZXRDdXN0b21DbGFzcygpIHtcclxuICAgICAgICBpZiAodGhpcy5vcHRpb25zWyd0b29sdGlwQ2xhc3MnXSkge1xyXG4gICAgICAgICAgICB0aGlzLm9wdGlvbnNbJ3Rvb2x0aXBDbGFzcyddLnNwbGl0KCcgJykuZm9yRWFjaCgoY2xhc3NOYW1lOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIGNsYXNzTmFtZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzZXRBbmltYXRpb25EdXJhdGlvbigpIHtcclxuICAgICAgICBpZiAoTnVtYmVyKHRoaXMub3B0aW9uc1snYW5pbWF0aW9uRHVyYXRpb24nXSkgIT0gdGhpcy5vcHRpb25zWydhbmltYXRpb25EdXJhdGlvbkRlZmF1bHQnXSkge1xyXG4gICAgICAgICAgICB0aGlzLmhvc3RTdHlsZVRyYW5zaXRpb24gPSAnb3BhY2l0eSAnICsgdGhpcy5vcHRpb25zWydhbmltYXRpb25EdXJhdGlvbiddICsgJ21zJztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc2V0U3R5bGVzKCkge1xyXG4gICAgICAgIHRoaXMuc2V0WkluZGV4KCk7XHJcbiAgICAgICAgdGhpcy5zZXRQb2ludGVyRXZlbnRzKCk7XHJcbiAgICAgICAgdGhpcy5zZXRBbmltYXRpb25EdXJhdGlvbigpO1xyXG5cclxuICAgICAgICB0aGlzLmhvc3RDbGFzc1NoYWRvdyA9IHRoaXMub3B0aW9uc1snc2hhZG93J107XHJcbiAgICAgICAgdGhpcy5ob3N0Q2xhc3NMaWdodCA9IHRoaXMuaXNUaGVtZUxpZ2h0O1xyXG4gICAgICAgIHRoaXMuaG9zdFN0eWxlTWF4V2lkdGggPSB0aGlzLm9wdGlvbnNbJ21heFdpZHRoJ107XHJcbiAgICAgICAgdGhpcy5ob3N0U3R5bGVXaWR0aCA9IHRoaXMub3B0aW9uc1snd2lkdGgnXSA/IHRoaXMub3B0aW9uc1snd2lkdGgnXSA6ICcnO1xyXG4gICAgfVxyXG59IiwiPGRpdiAqbmdJZj1cImlzVGhlbWVMaWdodFwiIGNsYXNzPVwidG9vbHRpcC1hcnJvd1wiPjwvZGl2PlxyXG5cclxuPGRpdiAqbmdJZj1cIm9wdGlvbnNbJ2NvbnRlbnRUeXBlJ10gPT09ICd0ZW1wbGF0ZScgZWxzZSBodG1sT3JTdHJpbmdUZW1wbGF0ZVwiPlxyXG5cclxuXHQ8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidmFsdWVcIj48L25nLWNvbnRhaW5lcj5cclxuPC9kaXY+XHJcblxyXG48bmctdGVtcGxhdGUgI2h0bWxPclN0cmluZ1RlbXBsYXRlPlxyXG5cdDxkaXYgW2lubmVySFRNTF09XCJ2YWx1ZVwiPjwvZGl2PlxyXG48L25nLXRlbXBsYXRlPiJdfQ==