@clr/angular
Version:
Angular components for Clarity
266 lines • 34.9 kB
JavaScript
/*
* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { Subject } from 'rxjs';
export var Point;
(function (Point) {
Point[Point["RIGHT_CENTER"] = 0] = "RIGHT_CENTER";
Point[Point["RIGHT_TOP"] = 1] = "RIGHT_TOP";
Point[Point["RIGHT_BOTTOM"] = 2] = "RIGHT_BOTTOM";
Point[Point["TOP_CENTER"] = 3] = "TOP_CENTER";
Point[Point["TOP_RIGHT"] = 4] = "TOP_RIGHT";
Point[Point["TOP_LEFT"] = 5] = "TOP_LEFT";
Point[Point["BOTTOM_CENTER"] = 6] = "BOTTOM_CENTER";
Point[Point["BOTTOM_RIGHT"] = 7] = "BOTTOM_RIGHT";
Point[Point["BOTTOM_LEFT"] = 8] = "BOTTOM_LEFT";
Point[Point["LEFT_CENTER"] = 9] = "LEFT_CENTER";
Point[Point["LEFT_TOP"] = 10] = "LEFT_TOP";
Point[Point["LEFT_BOTTOM"] = 11] = "LEFT_BOTTOM";
})(Point || (Point = {}));
const POSITION_RELATIVE = 'relative';
const POSITION_ABSOLUTE = 'absolute';
const POSITION_FIXED = 'fixed';
const OVERFLOW_SCROLL = 'scroll';
const OVERFLOW_AUTO = 'auto';
export class Popover {
constructor(element) {
this.element = element;
this.boundOnScrollListener = this.emitScrollEvent.bind(this);
/*
* Containers up to the first positioned one will have an event on scroll
*/
this.scrollableElements = [];
// Browsers don't agree with what to do if some of these are not specified, so we set them all to be safe.
element.style.position = POSITION_ABSOLUTE;
element.style.top = 0;
element.style.bottom = 'auto';
element.style.left = 0;
element.style.right = 'auto';
}
// TODO: need a way to account for parameters that change dynamically (positioning).
anchor(anchor, anchorAlign, popoverAlign, { offsetX = 0, offsetY = 0, useAnchorParent = false } = {}) {
// TODO: we are assuming here that the popover is inside or next to the anchor.
// We'd need to go up the popover tree too otherwise
this.addScrollEventListeners(anchor);
if (useAnchorParent) {
anchor = anchor.parentNode;
}
// explicitly override anchor's style to static
anchor.style.position = 'static';
const anchorRect = anchor.getBoundingClientRect();
const popoverRect = this.element.getBoundingClientRect();
// position of left top corner of anchor + the offset
let leftDiff = anchorRect.left - popoverRect.left + offsetX;
let topDiff = anchorRect.top - popoverRect.top + offsetY;
// first, adjust positioning based on anchor's align point
switch (anchorAlign) {
case Point.LEFT_TOP:
case Point.TOP_LEFT:
break;
case Point.TOP_CENTER:
leftDiff += anchorRect.width / 2;
break;
case Point.TOP_RIGHT:
leftDiff += anchorRect.width;
break;
case Point.RIGHT_TOP:
leftDiff += anchorRect.width;
break;
case Point.LEFT_BOTTOM:
topDiff += anchorRect.height;
break;
case Point.BOTTOM_LEFT:
topDiff += anchorRect.height;
break;
case Point.BOTTOM_CENTER:
topDiff += anchorRect.height;
leftDiff += anchorRect.width / 2;
break;
case Point.BOTTOM_RIGHT:
topDiff += anchorRect.height;
leftDiff += anchorRect.width;
break;
case Point.RIGHT_BOTTOM:
topDiff += anchorRect.height;
leftDiff += anchorRect.width;
break;
case Point.LEFT_CENTER:
topDiff += anchorRect.height / 2;
break;
case Point.RIGHT_CENTER:
topDiff += anchorRect.height / 2;
leftDiff += anchorRect.width;
break;
default:
}
// second, adjust positioning based on popover's align point
switch (popoverAlign) {
case Point.LEFT_TOP:
case Point.TOP_LEFT:
break;
case Point.TOP_CENTER:
leftDiff -= popoverRect.width / 2;
break;
case Point.TOP_RIGHT:
leftDiff -= popoverRect.width;
break;
case Point.RIGHT_TOP:
leftDiff -= popoverRect.width;
break;
case Point.LEFT_BOTTOM:
topDiff -= popoverRect.height;
break;
case Point.BOTTOM_LEFT:
topDiff -= popoverRect.height;
break;
case Point.BOTTOM_CENTER:
topDiff -= popoverRect.height;
leftDiff -= popoverRect.width / 2;
break;
case Point.BOTTOM_RIGHT:
topDiff -= popoverRect.height;
leftDiff -= popoverRect.width;
break;
case Point.RIGHT_BOTTOM:
topDiff -= popoverRect.height;
leftDiff -= popoverRect.width;
break;
case Point.LEFT_CENTER:
topDiff -= popoverRect.height / 2;
break;
case Point.RIGHT_CENTER:
topDiff -= popoverRect.height / 2;
leftDiff -= popoverRect.width;
break;
default:
}
// Third, adjust with popover's margins based on the two align points.
// Here, we make an assumption that popover is primarily positioned outside the
// anchor with minor offset. Without this assumption, it's impossible to apply
// the popover's margins in a predictable way. For example, assume that a popover
// and its anchor are exactly the same size. if a popover is positioned inside the
// anchor (which is technically possible), then it becomes impossible to know what to do
// if the popover has a non-zero margin value all around (because applying the margin in
// all four directions will result in no margin visually, which isn't what we want).
// Therefore, our logic makes assumptions about margins of interest given the points,
// and only covers the cases where popover is outside the anchor.
const popoverComputedStyle = getComputedStyle(this.element);
const marginLeft = parseInt(popoverComputedStyle.marginLeft, 10);
const marginRight = parseInt(popoverComputedStyle.marginRight, 10);
const marginTop = parseInt(popoverComputedStyle.marginTop, 10);
const marginBottom = parseInt(popoverComputedStyle.marginBottom, 10);
switch (anchorAlign) {
case Point.LEFT_TOP:
case Point.TOP_LEFT:
case Point.TOP_RIGHT:
case Point.RIGHT_TOP:
if (popoverAlign === Point.BOTTOM_RIGHT || popoverAlign === Point.RIGHT_BOTTOM) {
topDiff -= marginBottom;
leftDiff -= marginRight;
}
if (popoverAlign === Point.BOTTOM_LEFT || popoverAlign === Point.LEFT_BOTTOM) {
topDiff -= marginTop;
leftDiff += marginLeft;
}
if (popoverAlign === Point.TOP_LEFT || popoverAlign === Point.LEFT_TOP) {
topDiff += marginTop;
leftDiff += marginLeft;
}
if (popoverAlign === Point.TOP_RIGHT || popoverAlign === Point.RIGHT_TOP) {
topDiff += marginTop;
leftDiff -= marginRight;
}
break;
case Point.LEFT_BOTTOM:
case Point.BOTTOM_LEFT:
case Point.BOTTOM_RIGHT:
case Point.RIGHT_BOTTOM:
if (popoverAlign === Point.BOTTOM_LEFT || popoverAlign === Point.LEFT_BOTTOM) {
topDiff -= marginBottom;
leftDiff += marginLeft;
}
if (popoverAlign === Point.BOTTOM_RIGHT || popoverAlign === Point.RIGHT_BOTTOM) {
topDiff -= marginBottom;
leftDiff -= marginRight;
}
if (popoverAlign === Point.TOP_LEFT || popoverAlign === Point.LEFT_TOP) {
topDiff += marginTop;
leftDiff += marginLeft;
}
if (popoverAlign === Point.TOP_RIGHT || popoverAlign === Point.RIGHT_TOP) {
topDiff += marginTop;
leftDiff -= marginRight;
}
break;
case Point.TOP_CENTER:
topDiff -= marginBottom;
leftDiff += marginLeft;
leftDiff -= marginRight;
break;
case Point.BOTTOM_CENTER:
topDiff += marginTop;
leftDiff += marginLeft;
leftDiff -= marginRight;
break;
case Point.LEFT_CENTER:
topDiff += marginTop;
topDiff -= marginBottom;
leftDiff -= marginRight;
break;
case Point.RIGHT_CENTER:
topDiff += marginTop;
topDiff -= marginBottom;
leftDiff += marginLeft;
break;
default:
}
this.element.style.transform = `translateX(${Math.round(leftDiff)}px) translateY(${Math.round(topDiff)}px)`;
return this._scroll.asObservable();
}
release() {
this.element.style.transform = '';
this.removeScrollEventListeners();
}
isPositioned(container) {
const position = getComputedStyle(container).position;
return position === POSITION_RELATIVE || position === POSITION_ABSOLUTE || position === POSITION_FIXED;
}
emitScrollEvent() {
this._scroll.next();
}
addScrollEventListeners(e) {
this._scroll = new Subject();
const anchor = e;
let current = e;
while (current && current !== document) {
if (this.scrolls(current)) {
current.addEventListener('scroll', this.boundOnScrollListener);
this.scrollableElements.push(current);
}
if (current !== anchor && this.isPositioned(current)) {
break;
}
current = current.parentNode;
}
}
removeScrollEventListeners() {
for (const elem of this.scrollableElements) {
elem.removeEventListener('scroll', this.boundOnScrollListener);
}
this.scrollableElements.length = 0;
if (this._scroll) {
this._scroll.complete();
delete this._scroll;
}
}
scrolls(container) {
const computedStyles = getComputedStyle(container);
return (computedStyles.overflowX === OVERFLOW_SCROLL ||
computedStyles.overflowX === OVERFLOW_AUTO ||
computedStyles.overflowY === OVERFLOW_SCROLL ||
computedStyles.overflowY === OVERFLOW_AUTO);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9wb3Zlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXIvc3JjL3BvcG92ZXIvY29tbW9uL3BvcG92ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQVFILE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFHL0IsTUFBTSxDQUFOLElBQVksS0FhWDtBQWJELFdBQVksS0FBSztJQUNmLGlEQUFZLENBQUE7SUFDWiwyQ0FBUyxDQUFBO0lBQ1QsaURBQVksQ0FBQTtJQUNaLDZDQUFVLENBQUE7SUFDViwyQ0FBUyxDQUFBO0lBQ1QseUNBQVEsQ0FBQTtJQUNSLG1EQUFhLENBQUE7SUFDYixpREFBWSxDQUFBO0lBQ1osK0NBQVcsQ0FBQTtJQUNYLCtDQUFXLENBQUE7SUFDWCwwQ0FBUSxDQUFBO0lBQ1IsZ0RBQVcsQ0FBQTtBQUNiLENBQUMsRUFiVyxLQUFLLEtBQUwsS0FBSyxRQWFoQjtBQUVELE1BQU0saUJBQWlCLEdBQUcsVUFBVSxDQUFDO0FBQ3JDLE1BQU0saUJBQWlCLEdBQUcsVUFBVSxDQUFDO0FBQ3JDLE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQztBQUUvQixNQUFNLGVBQWUsR0FBRyxRQUFRLENBQUM7QUFDakMsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDO0FBRTdCLE1BQU0sT0FBTyxPQUFPO0lBU2xCLFlBQW9CLE9BQVk7UUFBWixZQUFPLEdBQVAsT0FBTyxDQUFLO1FBUHhCLDBCQUFxQixHQUFRLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXJFOztXQUVHO1FBQ0ssdUJBQWtCLEdBQWtCLEVBQUUsQ0FBQztRQUc3QywwR0FBMEc7UUFDMUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsaUJBQWlCLENBQUM7UUFDM0MsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFD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Q0FBQyxPQUFPLEVBQUU7WUFDaEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN4QixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7U0FDckI7SUFDSCxDQUFDO0lBRU8sT0FBTyxDQUFDLFNBQWM7UUFDNUIsTUFBTSxjQUFjLEdBQUcsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbkQsT0FBTyxDQUNMLGNBQWMsQ0FBQyxTQUFTLEtBQUssZUFBZTtZQUM1QyxjQUFjLENBQUMsU0FBUyxLQUFLLGFBQWE7WUFDMUMsY0FBYyxDQUFDLFNBQVMsS0FBSyxlQUFlO1lBQzVDLGNBQWMsQ0FBQyxTQUFTLEtBQUssYUFBYSxDQUMzQyxDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDIzIFZNd2FyZSwgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogVGhpcyBzb2Z0d2FyZSBpcyByZWxlYXNlZCB1bmRlciBNSVQgbGljZW5zZS5cbiAqIFRoZSBmdWxsIGxpY2Vuc2UgaW5mb3JtYXRpb24gY2FuIGJlIGZvdW5kIGluIExJQ0VOU0UgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgcHJvamVjdC5cbiAqL1xuXG4vKlxuICogRG8gTk9UIEFuZ3VsYXIgdGhpcyB1cC4gSXQgYXNzdW1lcyB3ZSdyZSBpbiB0aGUgRE9NLCBwbGF5cyB3aXRoIG5hdGl2ZSBlbGVtZW50cywgLi4uXG4gKiBJdCBjb3VsZCBwb3RlbnRpYWxseSBiZSB1c2VkIGFzIHBhcnQgb2YgQGNsci91aSBhcyBhIHZhbmlsbGEgSmF2YXNjcmlwdCBoZWxwZXIuXG4gKi9cblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBQb3BvdmVyT3B0aW9ucyB9IGZyb20gJy4vcG9wb3Zlci1vcHRpb25zLmludGVyZmFjZSc7XG5leHBvcnQgZW51bSBQb2ludCB7XG4gIFJJR0hUX0NFTlRFUixcbiAgUklHSFRfVE9QLFxuICBSSUdIVF9CT1RUT00sXG4gIFRPUF9DRU5URVIsXG4gIFRPUF9SSUdIVCxcbiAgVE9QX0xFRlQsXG4gIEJPVFRPTV9DRU5URVIsXG4gIEJPVFRPTV9SSUdIVCxcbiAgQk9UVE9NX0xFRlQsXG4gIExFRlRfQ0VOVEVSLFxuICBMRUZUX1RPUCxcbiAgTEVGVF9CT1RUT00sXG59XG5cbmNvbnN0IFBPU0lUSU9OX1JFTEFUSVZFID0gJ3JlbGF0aXZlJztcbmNvbnN0IFBPU0lUSU9OX0FCU09MVVRFID0gJ2Fic29sdXRlJztcbmNvbnN0IFBPU0lUSU9OX0ZJWEVEID0gJ2ZpeGVkJztcblxuY29uc3QgT1ZFUkZMT1dfU0NST0xMID0gJ3Njcm9sbCc7XG5jb25zdCBPVkVSRkxPV19BVVRPID0gJ2F1dG8nO1xuXG5leHBvcnQgY2xhc3MgUG9wb3ZlciB7XG4gIHByaXZhdGUgX3Njcm9sbDogU3ViamVjdDx2b2lkPjtcbiAgcHJpdmF0ZSBib3VuZE9uU2Nyb2xsTGlzdGVuZXI6IGFueSA9IHRoaXMuZW1pdFNjcm9sbEV2ZW50LmJpbmQodGhpcyk7XG5cbiAgLypcbiAgICogQ29udGFpbmVycyB1cCB0byB0aGUgZmlyc3QgcG9zaXRpb25lZCBvbmUgd2lsbCBoYXZlIGFuIGV2ZW50IG9uIHNjcm9sbFxuICAgKi9cbiAgcHJpdmF0ZSBzY3JvbGxhYmxlRWxlbWVudHM6IEhUTUxFbGVtZW50W10gPSBbXTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnQ6IGFueSkge1xuICAgIC8vIEJyb3dzZXJzIGRvbid0IGFncmVlIHdpdGggd2hhdCB0byBkbyBpZiBzb21lIG9mIHRoZXNlIGFyZSBub3Qgc3BlY2lmaWVkLCBzbyB3ZSBzZXQgdGhlbSBhbGwgdG8gYmUgc2FmZS5cbiAgICBlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gUE9TSVRJT05fQUJTT0xVVEU7XG4gICAgZWxlbWVudC5zdHlsZS50b3AgPSAwO1xuICAgIGVsZW1lbnQuc3R5bGUuYm90dG9tID0gJ2F1dG8nO1xuICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IDA7XG4gICAgZWxlbWVudC5zdHlsZS5yaWdodCA9ICdhdXRvJztcbiAgfVxuXG4gIC8vIFRPRE86IG5lZWQgYSB3YXkgdG8gYWNjb3VudCBmb3IgcGFyYW1ldGVycyB0aGF0IGNoYW5nZSBkeW5hbWljYWxseSAocG9zaXRpb25pbmcpLlxuICBhbmNob3IoXG4gICAgYW5jaG9yOiBhbnksXG4gICAgYW5jaG9yQWxpZ246IFBvaW50LFxuICAgIHBvcG92ZXJBbGlnbjogUG9pbnQsXG4gICAgeyBvZmZzZXRYID0gMCwgb2Zmc2V0WSA9IDAsIHVzZUFuY2hvclBhcmVudCA9IGZhbHNlIH06IFBvcG92ZXJPcHRpb25zID0ge31cbiAgKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICAvLyBUT0RPOiB3ZSBhcmUgYXNzdW1pbmcgaGVyZSB0aGF0IHRoZSBwb3BvdmVyIGlzIGluc2lkZSBvciBuZXh0IHRvIHRoZSBhbmNob3IuXG4gICAgLy8gV2UnZCBuZWVkIHRvIGdvIHVwIHRoZSBwb3BvdmVyIHRyZWUgdG9vIG90aGVyd2lzZVxuXG4gICAgdGhpcy5hZGRTY3JvbGxFdmVudExpc3RlbmVycyhhbmNob3IpO1xuICAgIGlmICh1c2VBbmNob3JQYXJlbnQpIHtcbiAgICAgIGFuY2hvciA9IGFuY2hvci5wYXJlbnROb2RlO1xuICAgIH1cbiAgICAvLyBleHBsaWNpdGx5IG92ZXJyaWRlIGFuY2hvcidzIHN0eWxlIHRvIHN0YXRpY1xuICAgIGFuY2hvci5zdHlsZS5wb3NpdGlvbiA9ICdzdGF0aWMnO1xuXG4gICAgY29uc3QgYW5jaG9yUmVjdCA9IGFuY2hvci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBwb3BvdmVyUmVjdCA9IHRoaXMuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIC8vIHBvc2l0aW9uIG9mIGxlZnQgdG9wIGNvcm5lciBvZiBhbmNob3IgKyB0aGUgb2Zmc2V0XG4gICAgbGV0IGxlZnREaWZmOiBudW1iZXIgPSBhbmNob3JSZWN0LmxlZnQgLSBwb3BvdmVyUmVjdC5sZWZ0ICsgb2Zmc2V0WDtcbiAgICBsZXQgdG9wRGlmZjogbnVtYmVyID0gYW5jaG9yUmVjdC50b3AgLSBwb3BvdmVyUmVjdC50b3AgKyBvZmZzZXRZO1xuXG4gICAgLy8gZmlyc3QsIGFkanVzdCBwb3NpdGlvbmluZyBiYXNlZCBvbiBhbmNob3IncyBhbGlnbiBwb2ludFxuICAgIHN3aXRjaCAoYW5jaG9yQWxpZ24pIHtcbiAgICAgIGNhc2UgUG9pbnQuTEVGVF9UT1A6XG4gICAgICBjYXNlIFBvaW50LlRPUF9MRUZUOlxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUG9pbnQuVE9QX0NFTlRFUjpcbiAgICAgICAgbGVmdERpZmYgKz0gYW5jaG9yUmVjdC53aWR0aCAvIDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5UT1BfUklHSFQ6XG4gICAgICAgIGxlZnREaWZmICs9IGFuY2hvclJlY3Qud2lkdGg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5SSUdIVF9UT1A6XG4gICAgICAgIGxlZnREaWZmICs9IGFuY2hvclJlY3Qud2lkdGg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5MRUZUX0JPVFRPTTpcbiAgICAgICAgdG9wRGlmZiArPSBhbmNob3JSZWN0LmhlaWdodDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFBvaW50LkJPVFRPTV9MRUZUOlxuICAgICAgICB0b3BEaWZmICs9IGFuY2hvclJlY3QuaGVpZ2h0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUG9pbnQuQk9UVE9NX0NFTlRFUjpcbiAgICAgICAgdG9wRGlmZiArPSBhbmNob3JSZWN0LmhlaWdodDtcbiAgICAgICAgbGVmdERpZmYgKz0gYW5jaG9yUmVjdC53aWR0aCAvIDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5CT1RUT01fUklHSFQ6XG4gICAgICAgIHRvcERpZmYgKz0gYW5jaG9yUmVjdC5oZWlnaHQ7XG4gICAgICAgIGxlZnREaWZmICs9IGFuY2hvclJlY3Qud2lkdGg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5SSUdIVF9CT1RUT006XG4gICAgICAgIHRvcERpZmYgKz0gYW5jaG9yUmVjdC5oZWlnaHQ7XG4gICAgICAgIGxlZnREaWZmICs9IGFuY2hvclJlY3Qud2lkdGg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5MRUZUX0NFTlRFUjpcbiAgICAgICAgdG9wRGlmZiArPSBhbmNob3JSZWN0LmhlaWdodCAvIDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5SSUdIVF9DRU5URVI6XG4gICAgICAgIHRvcERpZmYgKz0gYW5jaG9yUmVjdC5oZWlnaHQgLyAyO1xuICAgICAgICBsZWZ0RGlmZiArPSBhbmNob3JSZWN0LndpZHRoO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgfVxuXG4gICAgLy8gc2Vjb25kLCBhZGp1c3QgcG9zaXRpb25pbmcgYmFzZWQgb24gcG9wb3ZlcidzIGFsaWduIHBvaW50XG4gICAgc3dpdGNoIChwb3BvdmVyQWxpZ24pIHtcbiAgICAgIGNhc2UgUG9pbnQuTEVGVF9UT1A6XG4gICAgICBjYXNlIFBvaW50LlRPUF9MRUZUOlxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUG9pbnQuVE9QX0NFTlRFUjpcbiAgICAgICAgbGVmdERpZmYgLT0gcG9wb3ZlclJlY3Qud2lkdGggLyAyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUG9pbnQuVE9QX1JJR0hUOlxuICAgICAgICBsZWZ0RGlmZiAtPSBwb3BvdmVyUmVjdC53aWR0aDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFBvaW50LlJJR0hUX1RPUDpcbiAgICAgICAgbGVmdERpZmYgLT0gcG9wb3ZlclJlY3Qud2lkdGg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5MRUZUX0JPVFRPTTpcbiAgICAgICAgdG9wRGlmZiAtPSBwb3BvdmVyUmVjdC5oZWlnaHQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5CT1RUT01fTEVGVDpcbiAgICAgICAgdG9wRGlmZiAtPSBwb3BvdmVyUmVjdC5oZWlnaHQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5CT1RUT01fQ0VOVEVSOlxuICAgICAgICB0b3BEaWZmIC09IHBvcG92ZXJSZWN0LmhlaWdodDtcbiAgICAgICAgbGVmdERpZmYgLT0gcG9wb3ZlclJlY3Qud2lkdGggLyAyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUG9pbnQuQk9UVE9NX1JJR0hUOlxuICAgICAgICB0b3BEaWZmIC09IHBvcG92ZXJSZWN0LmhlaWdodDtcbiAgICAgICAgbGVmdERpZmYgLT0gcG9wb3ZlclJlY3Qud2lkdGg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5SSUdIVF9CT1RUT006XG4gICAgICAgIHRvcERpZmYgLT0gcG9wb3ZlclJlY3QuaGVpZ2h0O1xuICAgICAgICBsZWZ0RGlmZiAtPSBwb3BvdmVyUmVjdC53aWR0aDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFBvaW50LkxFRlRfQ0VOVEVSOlxuICAgICAgICB0b3BEaWZmIC09IHBvcG92ZXJSZWN0LmhlaWdodCAvIDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5SSUdIVF9DRU5URVI6XG4gICAgICAgIHRvcERpZmYgLT0gcG9wb3ZlclJlY3QuaGVpZ2h0IC8gMjtcbiAgICAgICAgbGVmdERpZmYgLT0gcG9wb3ZlclJlY3Qud2lkdGg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICB9XG5cbiAgICAvLyBUaGlyZCwgYWRqdXN0IHdpdGggcG9wb3ZlcidzIG1hcmdpbnMgYmFzZWQgb24gdGhlIHR3byBhbGlnbiBwb2ludHMuXG4gICAgLy8gSGVyZSwgd2UgbWFrZSBhbiBhc3N1bXB0aW9uIHRoYXQgcG9wb3ZlciBpcyBwcmltYXJpbHkgcG9zaXRpb25lZCBvdXRzaWRlIHRoZVxuICAgIC8vIGFuY2hvciB3aXRoIG1pbm9yIG9mZnNldC4gV2l0aG91dCB0aGlzIGFzc3VtcHRpb24sIGl0J3MgaW1wb3NzaWJsZSB0byBhcHBseVxuICAgIC8vIHRoZSBwb3BvdmVyJ3MgbWFyZ2lucyBpbiBhIHByZWRpY3RhYmxlIHdheS4gRm9yIGV4YW1wbGUsIGFzc3VtZSB0aGF0IGEgcG9wb3ZlclxuICAgIC8vIGFuZCBpdHMgYW5jaG9yIGFyZSBleGFjdGx5IHRoZSBzYW1lIHNpemUuIGlmIGEgcG9wb3ZlciBpcyBwb3NpdGlvbmVkIGluc2lkZSB0aGVcbiAgICAvLyBhbmNob3IgKHdoaWNoIGlzIHRlY2huaWNhbGx5IHBvc3NpYmxlKSwgdGhlbiBpdCBiZWNvbWVzIGltcG9zc2libGUgdG8ga25vdyB3aGF0IHRvIGRvXG4gICAgLy8gaWYgdGhlIHBvcG92ZXIgaGFzIGEgbm9uLXplcm8gbWFyZ2luIHZhbHVlIGFsbCBhcm91bmQgKGJlY2F1c2UgYXBwbHlpbmcgdGhlIG1hcmdpbiBpblxuICAgIC8vIGFsbCBmb3VyIGRpcmVjdGlvbnMgd2lsbCByZXN1bHQgaW4gbm8gbWFyZ2luIHZpc3VhbGx5LCB3aGljaCBpc24ndCB3aGF0IHdlIHdhbnQpLlxuICAgIC8vIFRoZXJlZm9yZSwgb3VyIGxvZ2ljIG1ha2VzIGFzc3VtcHRpb25zIGFib3V0IG1hcmdpbnMgb2YgaW50ZXJlc3QgZ2l2ZW4gdGhlIHBvaW50cyxcbiAgICAvLyBhbmQgb25seSBjb3ZlcnMgdGhlIGNhc2VzIHdoZXJlIHBvcG92ZXIgaXMgb3V0c2lkZSB0aGUgYW5jaG9yLlxuXG4gICAgY29uc3QgcG9wb3ZlckNvbXB1dGVkU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKHRoaXMuZWxlbWVudCk7XG4gICAgY29uc3QgbWFyZ2luTGVmdCA9IHBhcnNlSW50KHBvcG92ZXJDb21wdXRlZFN0eWxlLm1hcmdpbkxlZnQsIDEwKTtcbiAgICBjb25zdCBtYXJnaW5SaWdodCA9IHBhcnNlSW50KHBvcG92ZXJDb21wdXRlZFN0eWxlLm1hcmdpblJpZ2h0LCAxMCk7XG4gICAgY29uc3QgbWFyZ2luVG9wID0gcGFyc2VJbnQocG9wb3ZlckNvbXB1dGVkU3R5bGUubWFyZ2luVG9wLCAxMCk7XG4gICAgY29uc3QgbWFyZ2luQm90dG9tID0gcGFyc2VJbnQocG9wb3ZlckNvbXB1dGVkU3R5bGUubWFyZ2luQm90dG9tLCAxMCk7XG5cbiAgICBzd2l0Y2ggKGFuY2hvckFsaWduKSB7XG4gICAgICBjYXNlIFBvaW50LkxFRlRfVE9QOlxuICAgICAgY2FzZSBQb2ludC5UT1BfTEVGVDpcbiAgICAgIGNhc2UgUG9pbnQuVE9QX1JJR0hUOlxuICAgICAgY2FzZSBQb2ludC5SSUdIVF9UT1A6XG4gICAgICAgIGlmIChwb3BvdmVyQWxpZ24gPT09IFBvaW50LkJPVFRPTV9SSUdIVCB8fCBwb3BvdmVyQWxpZ24gPT09IFBvaW50LlJJR0hUX0JPVFRPTSkge1xuICAgICAgICAgIHRvcERpZmYgLT0gbWFyZ2luQm90dG9tO1xuICAgICAgICAgIGxlZnREaWZmIC09IG1hcmdpblJpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3BvdmVyQWxpZ24gPT09IFBvaW50LkJPVFRPTV9MRUZUIHx8IHBvcG92ZXJBbGlnbiA9PT0gUG9pbnQuTEVGVF9CT1RUT00pIHtcbiAgICAgICAgICB0b3BEaWZmIC09IG1hcmdpblRvcDtcbiAgICAgICAgICBsZWZ0RGlmZiArPSBtYXJnaW5MZWZ0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3BvdmVyQWxpZ24gPT09IFBvaW50LlRPUF9MRUZUIHx8IHBvcG92ZXJBbGlnbiA9PT0gUG9pbnQuTEVGVF9UT1ApIHtcbiAgICAgICAgICB0b3BEaWZmICs9IG1hcmdpblRvcDtcbiAgICAgICAgICBsZWZ0RGlmZiArPSBtYXJnaW5MZWZ0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3BvdmVyQWxpZ24gPT09IFBvaW50LlRPUF9SSUdIVCB8fCBwb3BvdmVyQWxpZ24gPT09IFBvaW50LlJJR0hUX1RPUCkge1xuICAgICAgICAgIHRvcERpZmYgKz0gbWFyZ2luVG9wO1xuICAgICAgICAgIGxlZnREaWZmIC09IG1hcmdpblJpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5MRUZUX0JPVFRPTTpcbiAgICAgIGNhc2UgUG9pbnQuQk9UVE9NX0xFRlQ6XG4gICAgICBjYXNlIFBvaW50LkJPVFRPTV9SSUdIVDpcbiAgICAgIGNhc2UgUG9pbnQuUklHSFRfQk9UVE9NOlxuICAgICAgICBpZiAocG9wb3ZlckFsaWduID09PSBQb2ludC5CT1RUT01fTEVGVCB8fCBwb3BvdmVyQWxpZ24gPT09IFBvaW50LkxFRlRfQk9UVE9NKSB7XG4gICAgICAgICAgdG9wRGlmZiAtPSBtYXJnaW5Cb3R0b207XG4gICAgICAgICAgbGVmdERpZmYgKz0gbWFyZ2luTGVmdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9wb3ZlckFsaWduID09PSBQb2ludC5CT1RUT01fUklHSFQgfHwgcG9wb3ZlckFsaWduID09PSBQb2ludC5SSUdIVF9CT1RUT00pIHtcbiAgICAgICAgICB0b3BEaWZmIC09IG1hcmdpbkJvdHRvbTtcbiAgICAgICAgICBsZWZ0RGlmZiAtPSBtYXJnaW5SaWdodDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9wb3ZlckFsaWduID09PSBQb2ludC5UT1BfTEVGVCB8fCBwb3BvdmVyQWxpZ24gPT09IFBvaW50LkxFRlRfVE9QKSB7XG4gICAgICAgICAgdG9wRGlmZiArPSBtYXJnaW5Ub3A7XG4gICAgICAgICAgbGVmdERpZmYgKz0gbWFyZ2luTGVmdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9wb3ZlckFsaWduID09PSBQb2ludC5UT1BfUklHSFQgfHwgcG9wb3ZlckFsaWduID09PSBQb2ludC5SSUdIVF9UT1ApIHtcbiAgICAgICAgICB0b3BEaWZmICs9IG1hcmdpblRvcDtcbiAgICAgICAgICBsZWZ0RGlmZiAtPSBtYXJnaW5SaWdodDtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUG9pbnQuVE9QX0NFTlRFUjpcbiAgICAgICAgdG9wRGlmZiAtPSBtYXJnaW5Cb3R0b207XG4gICAgICAgIGxlZnREaWZmICs9IG1hcmdpbkxlZnQ7XG4gICAgICAgIGxlZnREaWZmIC09IG1hcmdpblJpZ2h0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUG9pbnQuQk9UVE9NX0NFTlRFUjpcbiAgICAgICAgdG9wRGlmZiArPSBtYXJnaW5Ub3A7XG4gICAgICAgIGxlZnREaWZmICs9IG1hcmdpbkxlZnQ7XG4gICAgICAgIGxlZnREaWZmIC09IG1hcmdpblJpZ2h0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUG9pbnQuTEVGVF9DRU5URVI6XG4gICAgICAgIHRvcERpZmYgKz0gbWFyZ2luVG9wO1xuICAgICAgICB0b3BEaWZmIC09IG1hcmdpbkJvdHRvbTtcbiAgICAgICAgbGVmdERpZmYgLT0gbWFyZ2luUmlnaHQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQb2ludC5SSUdIVF9DRU5URVI6XG4gICAgICAgIHRvcERpZmYgKz0gbWFyZ2luVG9wO1xuICAgICAgICB0b3BEaWZmIC09IG1hcmdpbkJvdHRvbTtcbiAgICAgICAgbGVmdERpZmYgKz0gbWFyZ2luTGVmdDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgIH1cblxuICAgIHRoaXMuZWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlWCgke01hdGgucm91bmQobGVmdERpZmYpfXB4KSB0cmFuc2xhdGVZKCR7TWF0aC5yb3VuZCh0b3BEaWZmKX1weClgO1xuICAgIHJldHVybiB0aGlzLl9zY3JvbGwuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICByZWxlYXNlKCkge1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSAnJztcbiAgICB0aGlzLnJlbW92ZVNjcm9sbEV2ZW50TGlzdGVuZXJzKCk7XG4gIH1cblxuICBwcml2YXRlIGlzUG9zaXRpb25lZChjb250YWluZXI6IGFueSkge1xuICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0Q29tcHV0ZWRTdHlsZShjb250YWluZXIpLnBvc2l0aW9uO1xuICAgIHJldHVybiBwb3NpdGlvbiA9PT0gUE9TSVRJT05fUkVMQVRJVkUgfHwgcG9zaXRpb24gPT09IFBPU0lUSU9OX0FCU09MVVRFIHx8IHBvc2l0aW9uID09PSBQT1NJVElPTl9GSVhFRDtcbiAgfVxuXG4gIHByaXZhdGUgZW1pdFNjcm9sbEV2ZW50KCkge1xuICAgIHRoaXMuX3Njcm9sbC5uZXh0KCk7XG4gIH1cblxuICBwcml2YXRlIGFkZFNjcm9sbEV2ZW50TGlzdGVuZXJzKGU6IGFueSkge1xuICAgIHRoaXMuX3Njcm9sbCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gICAgY29uc3QgYW5jaG9yOiBhbnkgPSBlO1xuICAgIGxldCBjdXJyZW50OiBhbnkgPSBlO1xuICAgIHdoaWxlIChjdXJyZW50ICYmIGN1cnJlbnQgIT09IGRvY3VtZW50KSB7XG4gICAgICBpZiAodGhpcy5zY3JvbGxzKGN1cnJlbnQpKSB7XG4gICAgICAgIGN1cnJlbnQuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5ib3VuZE9uU2Nyb2xsTGlzdGVuZXIpO1xuICAgICAgICB0aGlzLnNjcm9sbGFibGVFbGVtZW50cy5wdXNoKGN1cnJlbnQpO1xuICAgICAgfVxuICAgICAgaWYgKGN1cnJlbnQgIT09IGFuY2hvciAmJiB0aGlzLmlzUG9zaXRpb25lZChjdXJyZW50KSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudE5vZGU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVTY3JvbGxFdmVudExpc3RlbmVycygpIHtcbiAgICBmb3IgKGNvbnN0IGVsZW0gb2YgdGhpcy5zY3JvbGxhYmxlRWxlbWVudHMpIHtcbiAgICAgIGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5ib3VuZE9uU2Nyb2xsTGlzdGVuZXIpO1xuICAgIH1cbiAgICB0aGlzLnNjcm9sbGFibGVFbGVtZW50cy5sZW5ndGggPSAwO1xuICAgIGlmICh0aGlzLl9zY3JvbGwpIHtcbiAgICAgIHRoaXMuX3Njcm9sbC5jb21wbGV0ZSgpO1xuICAgICAgZGVsZXRlIHRoaXMuX3Njcm9sbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNjcm9sbHMoY29udGFpbmVyOiBhbnkpOiBib29sZWFuIHtcbiAgICBjb25zdCBjb21wdXRlZFN0eWxlcyA9IGdldENvbXB1dGVkU3R5bGUoY29udGFpbmVyKTtcbiAgICByZXR1cm4gKFxuICAgICAgY29tcHV0ZWRTdHlsZXMub3ZlcmZsb3dYID09PSBPVkVSRkxPV19TQ1JPTEwgfHxcbiAgICAgIGNvbXB1dGVkU3R5bGVzLm92ZXJmbG93WCA9PT0gT1ZFUkZMT1dfQVVUTyB8fFxuICAgICAgY29tcHV0ZWRTdHlsZXMub3ZlcmZsb3dZID09PSBPVkVSRkxPV19TQ1JPTEwgfHxcbiAgICAgIGNvbXB1dGVkU3R5bGVzLm92ZXJmbG93WSA9PT0gT1ZFUkZMT1dfQVVUT1xuICAgICk7XG4gIH1cbn1cbiJdfQ==