ngx-intersection-observer
Version:
Intersection observer for Angular
200 lines • 27.6 kB
JavaScript
import { Directive, EventEmitter, Input, Optional, Output } from "@angular/core";
import { Subscription } from "rxjs";
import * as i0 from "@angular/core";
import * as i1 from "./intersection-observer.service";
import * as i2 from "./intersection-observer-config.model";
export class IntersectionObserverDirective {
constructor(element, renderer, intersectionObserverService, intersectionObserverConfig) {
this.element = element;
this.renderer = renderer;
this.intersectionObserverService = intersectionObserverService;
this.intersectionObserverConfig = intersectionObserverConfig;
// Private fields
this._viewportChangeSub = new Subscription();
this._visitClass = [];
this._leaveClass = [];
this._removeVisitClass = [];
this._removeLeaveClass = [];
this._elementVisible = false;
this._hasClasses = false;
// Directive outputs
this.intersection = new EventEmitter(); // Event that fires once an element intersects.
}
ngOnInit() {
// Generate arrays of class stings
this._visitClass = this.getClassArray(this.visitClass ?? "");
this._leaveClass = this.getClassArray(this.leaveClass ?? "");
this._removeVisitClass = this.getClassArray(this.removeVisitClass ?? "");
this._removeLeaveClass = this.getClassArray(this.removeLeaveClass ?? "");
this._hasClasses = (this.visitClass || this.leaveClass || this.removeVisitClass || this.removeLeaveClass) ? true : false;
// Identify which intersection mechanism should be used
// (IntersectionObserver or Scroll Listener) default IntersectionObserver
let useScroll = this.intersectionObserverConfig?.useScroll;
useScroll = useScroll == undefined ? false : useScroll;
useScroll = this.useScroll == undefined ? useScroll : this.useScroll;
// Get threshold or default to 30
let threshold = this.intersectionObserverConfig?.threshold;
threshold = threshold == undefined ? 30 : threshold;
threshold = this.threshold == undefined ? threshold : this.threshold;
// Auto remove
let autoRemove = this.intersectionObserverConfig?.autoRemove;
autoRemove = autoRemove == undefined ? true : autoRemove;
autoRemove = this.autoRemove == undefined ? autoRemove : this.autoRemove;
// using intersecting observer by default, else fallback to scroll Listener
if ("IntersectionObserver" in window && !useScroll) {
const options = {
root: null,
threshold: threshold / 100,
rootMargin: "0px"
};
const observer = new IntersectionObserver((entries, _) => {
entries.forEach((entry) => {
this.handleIntersection(entry.isIntersecting);
});
}, options);
observer.observe(this.element.nativeElement);
return;
}
// Fallback to scroll listener
this._viewportChangeSub = this.intersectionObserverService.windowViewportChange$.subscribe(() => this.checkForIntersection());
}
/**
* Gets an array of classes.
* @param classString String with classes separated by whitespace.
* @returns An array with classes.
*/
getClassArray(classString) {
let classes = new Array();
classString.split(" ").forEach(cls => {
if (cls.trim()) {
classes.push(cls.trim());
}
});
return classes;
}
/**
* Checks if the element is visible within the viewport.
* @returns void
* */
checkForIntersection() {
const thresholdPx = (this.elementHeight / 100) * this.threshold;
const scrollTriggerMax = this.offsetTop + thresholdPx - this.winHeight;
const scrollTriggerMin = (this.offsetTop + (this.elementHeight - thresholdPx));
this.handleIntersection(this.intersectionObserverService.pageYOffset >= scrollTriggerMax &&
this.intersectionObserverService.pageYOffset <= scrollTriggerMin);
}
/**
*
* @param intersect Determines if the elements intersects with its viewport or not.
* @returns void
*/
handleIntersection(intersect) {
this._elementVisible = intersect;
this.handleClasses();
this.intersection.emit({ element: this.element, intersect: intersect });
}
/**
* Adds or removes classes on the element when it enters or leaves the viewport.
* @returns void
* */
handleClasses() {
// No classes, skip
if (!this._hasClasses)
return;
if (this._elementVisible) {
this.addClasses(this._visitClass);
if (this.autoRemove) {
this.removeClasses(this._leaveClass);
}
this.removeClasses(this._removeVisitClass);
}
else {
this.addClasses(this._leaveClass);
if (this.autoRemove) {
this.removeClasses(this._visitClass);
}
this.removeClasses(this._removeLeaveClass);
}
}
/**
* Helper to add a list of classes to the element.
* @param classes The list of classes to add.
* @returns void
*/
addClasses(classes) {
classes.forEach(cls => {
if (!this.element.nativeElement.classList.contains(cls)) {
this.renderer.addClass(this.element.nativeElement, cls);
}
});
}
/**
* Helper to remove a list of classes from the element.
* @param classes The list of classes to remove.
* @returns void
*/
removeClasses(classes) {
classes.forEach(cls => {
if (this.element.nativeElement.classList.contains(cls)) {
this.renderer.removeClass(this.element.nativeElement, cls);
}
});
}
/**
* Gets the height of the browser window.
* @returns the height of the browser window.
*/
get winHeight() {
return typeof window !== "undefined" ? window.innerHeight : 0;
}
/**
* Gets the offset of the element.
* @returns The elements offset.
*/
get offsetTop() {
if (typeof this.element.nativeElement.getBoundingClientRect === "function") {
const viewportTop = this.element.nativeElement.getBoundingClientRect().top;
return viewportTop + this.intersectionObserverService.pageYOffset - this.element.nativeElement.clientTop;
}
else {
return 0;
}
}
/**
* Gets the height of the element (Including border)
* @returns the height of the element.
*/
get elementHeight() {
return this.element.nativeElement.offsetHeight;
}
ngOnDestroy() {
this._viewportChangeSub.unsubscribe();
}
}
IntersectionObserverDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: IntersectionObserverDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.IntersectionObserverService }, { token: i2.IntersectionObserverConfig, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
IntersectionObserverDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0", type: IntersectionObserverDirective, selector: "[intersectionObserver]", inputs: { visitClass: "visitClass", leaveClass: "leaveClass", removeVisitClass: "removeVisitClass", removeLeaveClass: "removeLeaveClass", useScroll: "useScroll", threshold: "threshold", autoRemove: "autoRemove" }, outputs: { intersection: "intersection" }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: IntersectionObserverDirective, decorators: [{
type: Directive,
args: [{
selector: "[intersectionObserver]",
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.IntersectionObserverService }, { type: i2.IntersectionObserverConfig, decorators: [{
type: Optional
}] }]; }, propDecorators: { visitClass: [{
type: Input
}], leaveClass: [{
type: Input
}], removeVisitClass: [{
type: Input
}], removeLeaveClass: [{
type: Input
}], useScroll: [{
type: Input
}], threshold: [{
type: Input
}], autoRemove: [{
type: Input
}], intersection: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJzZWN0aW9uLW9ic2VydmVyLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2ludGVyc2VjdGlvbi1vYnNlcnZlci9zcmMvbGliL2ludGVyc2VjdGlvbi1vYnNlcnZlci5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBYyxZQUFZLEVBQUUsS0FBSyxFQUFxQixRQUFRLEVBQUUsTUFBTSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQzNILE9BQU8sRUFBVSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7QUFTNUMsTUFBTSxPQUFPLDZCQUE2QjtJQXlCeEMsWUFDVSxPQUF3QixFQUN4QixRQUFtQixFQUNuQiwyQkFBd0QsRUFDNUMsMEJBQXVEO1FBSG5FLFlBQU8sR0FBUCxPQUFPLENBQWlCO1FBQ3hCLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsZ0NBQTJCLEdBQTNCLDJCQUEyQixDQUE2QjtRQUM1QywrQkFBMEIsR0FBMUIsMEJBQTBCLENBQTZCO1FBM0I3RSxpQkFBaUI7UUFDVCx1QkFBa0IsR0FBaUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN0RCxnQkFBVyxHQUFhLEVBQUUsQ0FBQztRQUMzQixnQkFBVyxHQUFhLEVBQUUsQ0FBQztRQUMzQixzQkFBaUIsR0FBYSxFQUFFLENBQUM7UUFDakMsc0JBQWlCLEdBQWEsRUFBRSxDQUFDO1FBQ2pDLG9CQUFlLEdBQVksS0FBSyxDQUFDO1FBQ2pDLGdCQUFXLEdBQVksS0FBSyxDQUFDO1FBWXJDLG9CQUFvQjtRQUNWLGlCQUFZLEdBQ3BCLElBQUksWUFBWSxFQUE2QixDQUFDLENBQUMsK0NBQStDO0lBT2hHLENBQUM7SUFFRCxRQUFRO1FBRU4sa0NBQWtDO1FBQ2xDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLEVBQUUs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Z0I7c0JBQXhCLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBR0ksWUFBWTtzQkFBckIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIE9wdGlvbmFsLCBPdXRwdXQsIFJlbmRlcmVyMiB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7IGNvbmZpZywgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHsgSW50ZXJzZWN0aW9uT2JzZXJ2ZXJDb25maWcgfSBmcm9tIFwiLi9pbnRlcnNlY3Rpb24tb2JzZXJ2ZXItY29uZmlnLm1vZGVsXCI7XHJcbmltcG9ydCB7IEludGVyc2VjdGlvbk9ic2VydmVyRXZlbnQgfSBmcm9tIFwiLi9pbnRlcnNlY3Rpb24tb2JzZXJ2ZXItZXZlbnQubW9kZWxcIjtcclxuaW1wb3J0IHsgSW50ZXJzZWN0aW9uT2JzZXJ2ZXJTZXJ2aWNlIH0gZnJvbSBcIi4vaW50ZXJzZWN0aW9uLW9ic2VydmVyLnNlcnZpY2VcIjtcclxuXHJcbkBEaXJlY3RpdmUoe1xyXG4gIHNlbGVjdG9yOiBcIltpbnRlcnNlY3Rpb25PYnNlcnZlcl1cIixcclxuXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBJbnRlcnNlY3Rpb25PYnNlcnZlckRpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuXHJcbiAgLy8gUHJpdmF0ZSBmaWVsZHNcclxuICBwcml2YXRlIF92aWV3cG9ydENoYW5nZVN1YjogU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xyXG4gIHByaXZhdGUgX3Zpc2l0Q2xhc3M6IHN0cmluZ1tdID0gW107XHJcbiAgcHJpdmF0ZSBfbGVhdmVDbGFzczogc3RyaW5nW10gPSBbXTtcclxuICBwcml2YXRlIF9yZW1vdmVWaXNpdENsYXNzOiBzdHJpbmdbXSA9IFtdO1xyXG4gIHByaXZhdGUgX3JlbW92ZUxlYXZlQ2xhc3M6IHN0cmluZ1tdID0gW107XHJcbiAgcHJpdmF0ZSBfZWxlbWVudFZpc2libGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBwcml2YXRlIF9oYXNDbGFzc2VzOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8vIERpcmVjdGl2ZSBpbnB1dHNcclxuICBASW5wdXQoKSB2aXNpdENsYXNzOiBzdHJpbmcgfCB1bmRlZmluZWQ7ICAgICAgICAgLy8gQ2xhc3NlcyB0byBhcHBseSB3aGVuIHRoZSBlbGVtZW50IHZpc2l0cyB0aGUgdmlld3BvcnQuXHJcbiAgQElucHV0KCkgbGVhdmVDbGFzczogc3RyaW5nIHwgdW5kZWZpbmVkOyAgICAgICAgIC8vIENsYXNzZXMgdG8gYXBwbHkgd2hlbiB0aGUgZWxlbWVudCB2aXNpdHMgdGhlIHZpZXdwb3J0LlxyXG4gIEBJbnB1dCgpIHJlbW92ZVZpc2l0Q2xhc3M6IHN0cmluZyB8IHVuZGVmaW5lZCAgICAvLyBDbGFzc2VzIHRvIHJlbW92ZSB3aGUgdGhlIGVsZW1lbnQgdmlzaXRzIHRoZSB2aWV3cG9ydFxyXG4gIEBJbnB1dCgpIHJlbW92ZUxlYXZlQ2xhc3M6IHN0cmluZyB8IHVuZGVmaW5lZCAgICAvLyBDbGFzc2VzIHRvIHJlbW92ZSB3aGVuIHRoZSBlbGVtZW50IGxlYXZlcyB0aGUgdmlld3BvcnQuXHJcblxyXG4gIEBJbnB1dCgpIHVzZVNjcm9sbDogYm9vbGVhbiB8IHVuZGVmaW5lZCAgICAgICAgICAvLyB0cnVlID0gU2Nyb2xsIExpc3RlbmVyLCBmYWxzZSA9IEludGVyc2VjdGlvbk9ic2VydmVyXHJcbiAgQElucHV0KCkgdGhyZXNob2xkOiBudW1iZXIgfCB1bmRlZmluZWQ7ICAgICAgICAgIC8vIFRocmVzaG9sZCwgaG93IG1hbnkgcHJlY2VudGFnZSBvZiB0aGUgZWxlbWVudCBtdXN0IGJlIG91dCBvZiB0aGUgdmlld3BvcnQgdG8gdHJlYXQgaXQgYXMgaW52aXNpYmxlLlxyXG4gIEBJbnB1dCgpIGF1dG9SZW1vdmU6IGJvb2xlYW4gfCB1bmRlZmluZWQ7ICAgICAgICAvLyB0cnVlID0gQXV0b21hdGljYWxseSByZW1vdmUgY2xhc3NlcyBmcm9tIHRoZSBlbGVtZW50LCBmYWxzZSAtPiB1c2UgcmVtb3ZlTGVhdmVDbGFzc1xyXG5cclxuICAvLyBEaXJlY3RpdmUgb3V0cHV0c1xyXG4gIEBPdXRwdXQoKSBpbnRlcnNlY3Rpb246IEV2ZW50RW1pdHRlcjxJbnRlcnNlY3Rpb25PYnNlcnZlckV2ZW50PiA9XHJcbiAgICBuZXcgRXZlbnRFbWl0dGVyPEludGVyc2VjdGlvbk9ic2VydmVyRXZlbnQ+KCk7IC8vIEV2ZW50IHRoYXQgZmlyZXMgb25jZSBhbiBlbGVtZW50IGludGVyc2VjdHMuXHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmPGFueT4sXHJcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcbiAgICBwcml2YXRlIGludGVyc2VjdGlvbk9ic2VydmVyU2VydmljZTogSW50ZXJzZWN0aW9uT2JzZXJ2ZXJTZXJ2aWNlLFxyXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBpbnRlcnNlY3Rpb25PYnNlcnZlckNvbmZpZz86IEludGVyc2VjdGlvbk9ic2VydmVyQ29uZmlnKSB7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuXHJcbiAgICAvLyBHZW5lcmF0ZSBhcnJheXMgb2YgY2xhc3Mgc3RpbmdzXHJcbiAgICB0aGlzLl92aXNpdENsYXNzID0gdGhpcy5nZXRDbGFzc0FycmF5KHRoaXMudmlzaXRDbGFzcyA/PyBcIlwiKTtcclxuICAgIHRoaXMuX2xlYXZlQ2xhc3MgPSB0aGlzLmdldENsYXNzQXJyYXkodGhpcy5sZWF2ZUNsYXNzID8/IFwiXCIpO1xyXG4gICAgdGhpcy5fcmVtb3ZlVmlzaXRDbGFzcyA9IHRoaXMuZ2V0Q2xhc3NBcnJheSh0aGlzLnJlbW92ZVZpc2l0Q2xhc3MgPz8gXCJcIik7XHJcbiAgICB0aGlzLl9yZW1vdmVMZWF2ZUNsYXNzID0gdGhpcy5nZXRDbGFzc0FycmF5KHRoaXMucmVtb3ZlTGVhdmVDbGFzcyA/PyBcIlwiKTtcclxuICAgIHRoaXMuX2hhc0NsYXNzZXMgPSAodGhpcy52aXNpdENsYXNzIHx8IHRoaXMubGVhdmVDbGFzcyB8fCB0aGlzLnJlbW92ZVZpc2l0Q2xhc3MgfHwgdGhpcy5yZW1vdmVMZWF2ZUNsYXNzKSA/IHRydWUgOiBmYWxzZTtcclxuXHJcbiAgICAvLyBJZGVudGlmeSB3aGljaCBpbnRlcnNlY3Rpb24gbWVjaGFuaXNtIHNob3VsZCBiZSB1c2VkXHJcbiAgICAvLyAoSW50ZXJzZWN0aW9uT2JzZXJ2ZXIgb3IgU2Nyb2xsIExpc3RlbmVyKSBkZWZhdWx0IEludGVyc2VjdGlvbk9ic2VydmVyXHJcbiAgICBsZXQgdXNlU2Nyb2xsID0gdGhpcy5pbnRlcnNlY3Rpb25PYnNlcnZlckNvbmZpZz8udXNlU2Nyb2xsO1xyXG4gICAgdXNlU2Nyb2xsID0gdXNlU2Nyb2xsID09IHVuZGVmaW5lZCA/IGZhbHNlIDogdXNlU2Nyb2xsO1xyXG4gICAgdXNlU2Nyb2xsID0gdGhpcy51c2VTY3JvbGwgPT0gdW5kZWZpbmVkID8gdXNlU2Nyb2xsIDogdGhpcy51c2VTY3JvbGw7ICAgXHJcblxyXG4gICAgLy8gR2V0IHRocmVzaG9sZCBvciBkZWZhdWx0IHRvIDMwXHJcbiAgICBsZXQgdGhyZXNob2xkID0gdGhpcy5pbnRlcnNlY3Rpb25PYnNlcnZlckNvbmZpZz8udGhyZXNob2xkO1xyXG4gICAgdGhyZXNob2xkID0gdGhyZXNob2xkID09IHVuZGVmaW5lZCA/IDMwIDogdGhyZXNob2xkO1xyXG4gICAgdGhyZXNob2xkID0gdGhpcy50aHJlc2hvbGQgPT0gdW5kZWZpbmVkID8gdGhyZXNob2xkIDogdGhpcy50aHJlc2hvbGQ7ICAgXHJcblxyXG4gICAgLy8gQXV0byByZW1vdmVcclxuICAgIGxldCBhdXRvUmVtb3ZlID0gdGhpcy5pbnRlcnNlY3Rpb25PYnNlcnZlckNvbmZpZz8uYXV0b1JlbW92ZTtcclxuICAgIGF1dG9SZW1vdmUgPSBhdXRvUmVtb3ZlID09IHVuZGVmaW5lZCA/IHRydWUgOiBhdXRvUmVtb3ZlO1xyXG4gICAgYXV0b1JlbW92ZSA9IHRoaXMuYXV0b1JlbW92ZSA9PSB1bmRlZmluZWQgPyBhdXRvUmVtb3ZlIDogdGhpcy5hdXRvUmVtb3ZlO1xyXG5cclxuICAgIC8vIHVzaW5nIGludGVyc2VjdGluZyBvYnNlcnZlciBieSBkZWZhdWx0LCBlbHNlIGZhbGxiYWNrIHRvIHNjcm9sbCBMaXN0ZW5lclxyXG4gICAgaWYgKFwiSW50ZXJzZWN0aW9uT2JzZXJ2ZXJcIiBpbiB3aW5kb3cgJiYgIXVzZVNjcm9sbCkge1xyXG4gICAgICBjb25zdCBvcHRpb25zOiBJbnRlcnNlY3Rpb25PYnNlcnZlckluaXQgPSB7XHJcbiAgICAgICAgcm9vdDogbnVsbCwgLy8gVXNlIHdpbmRvdyBhcyByb290XHJcbiAgICAgICAgdGhyZXNob2xkOiB0aHJlc2hvbGQgLyAxMDAsXHJcbiAgICAgICAgcm9vdE1hcmdpbjogXCIwcHhcIlxyXG4gICAgICB9O1xyXG4gICAgICBjb25zdCBvYnNlcnZlcjogSW50ZXJzZWN0aW9uT2JzZXJ2ZXIgPSBuZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoXHJcbiAgICAgICAgKGVudHJpZXMsIF8pID0+IHtcclxuICAgICAgICAgIGVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5oYW5kbGVJbnRlcnNlY3Rpb24oZW50cnkuaXNJbnRlcnNlY3RpbmcpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBvcHRpb25zXHJcbiAgICAgICk7XHJcbiAgICAgIG9ic2VydmVyLm9ic2VydmUodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRmFsbGJhY2sgdG8gc2Nyb2xsIGxpc3RlbmVyXHJcbiAgICB0aGlzLl92aWV3cG9ydENoYW5nZVN1YiA9IHRoaXMuaW50ZXJzZWN0aW9uT2JzZXJ2ZXJTZXJ2aWNlLndpbmRvd1ZpZXdwb3J0Q2hhbmdlJC5zdWJzY3JpYmUoKCkgPT5cclxuICAgICAgdGhpcy5jaGVja0ZvckludGVyc2VjdGlvbigpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyBhbiBhcnJheSBvZiBjbGFzc2VzLlxyXG4gICAqIEBwYXJhbSBjbGFzc1N0cmluZyBTdHJpbmcgd2l0aCBjbGFzc2VzIHNlcGFyYXRlZCBieSB3aGl0ZXNwYWNlLlxyXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IHdpdGggY2xhc3Nlcy5cclxuICAgKi9cclxuICBwcml2YXRlIGdldENsYXNzQXJyYXkoY2xhc3NTdHJpbmc6IHN0cmluZyk6IHN0cmluZ1tdIHtcclxuICAgIGxldCBjbGFzc2VzID0gbmV3IEFycmF5PHN0cmluZz4oKTtcclxuICAgIGNsYXNzU3RyaW5nLnNwbGl0KFwiIFwiKS5mb3JFYWNoKGNscyA9PiB7XHJcbiAgICAgIGlmIChjbHMudHJpbSgpKSB7XHJcbiAgICAgICAgY2xhc3Nlcy5wdXNoKGNscy50cmltKCkpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gY2xhc3NlcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrcyBpZiB0aGUgZWxlbWVudCBpcyB2aXNpYmxlIHdpdGhpbiB0aGUgdmlld3BvcnQuXHJcbiAgICogQHJldHVybnMgdm9pZFxyXG4gICAqICovXHJcbiAgcHJpdmF0ZSBjaGVja0ZvckludGVyc2VjdGlvbigpOiB2b2lkIHtcclxuICAgIGNvbnN0IHRocmVzaG9sZFB4ID0gKHRoaXMuZWxlbWVudEhlaWdodCAvIDEwMCkgKiB0aGlzLnRocmVzaG9sZCE7XHJcbiAgICBjb25zdCBzY3JvbGxUcmlnZ2VyTWF4ID0gdGhpcy5vZmZzZXRUb3AgKyB0aHJlc2hvbGRQeCAtIHRoaXMud2luSGVpZ2h0O1xyXG4gICAgY29uc3Qgc2Nyb2xsVHJpZ2dlck1pbiA9ICh0aGlzLm9mZnNldFRvcCArICh0aGlzLmVsZW1lbnRIZWlnaHQgLSB0aHJlc2hvbGRQeCkpO1xyXG4gICAgdGhpcy5oYW5kbGVJbnRlcnNlY3Rpb24oXHJcbiAgICAgIHRoaXMuaW50ZXJzZWN0aW9uT2JzZXJ2ZXJTZXJ2aWNlLnBhZ2VZT2Zmc2V0ID49IHNjcm9sbFRyaWdnZXJNYXggJiZcclxuICAgICAgdGhpcy5pbnRlcnNlY3Rpb25PYnNlcnZlclNlcnZpY2UucGFnZVlPZmZzZXQgPD0gc2Nyb2xsVHJpZ2dlck1pbik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBcclxuICAgKiBAcGFyYW0gaW50ZXJzZWN0IERldGVybWluZXMgaWYgdGhlIGVsZW1lbnRzIGludGVyc2VjdHMgd2l0aCBpdHMgdmlld3BvcnQgb3Igbm90LlxyXG4gICAqIEByZXR1cm5zIHZvaWRcclxuICAgKi9cclxuICBwcml2YXRlIGhhbmRsZUludGVyc2VjdGlvbihpbnRlcnNlY3Q6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIHRoaXMuX2VsZW1lbnRWaXNpYmxlID0gaW50ZXJzZWN0O1xyXG4gICAgdGhpcy5oYW5kbGVDbGFzc2VzKCk7XHJcbiAgICB0aGlzLmludGVyc2VjdGlvbi5lbWl0KHsgZWxlbWVudDogdGhpcy5lbGVtZW50LCBpbnRlcnNlY3Q6IGludGVyc2VjdCB9IGFzIEludGVyc2VjdGlvbk9ic2VydmVyRXZlbnQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkcyBvciByZW1vdmVzIGNsYXNzZXMgb24gdGhlIGVsZW1lbnQgd2hlbiBpdCBlbnRlcnMgb3IgbGVhdmVzIHRoZSB2aWV3cG9ydC5cclxuICAgKiBAcmV0dXJucyB2b2lkXHJcbiAgICogKi9cclxuICBwcml2YXRlIGhhbmRsZUNsYXNzZXMoKTogdm9pZCB7XHJcbiAgICAvLyBObyBjbGFzc2VzLCBza2lwXHJcbiAgICBpZiAoIXRoaXMuX2hhc0NsYXNzZXMpXHJcbiAgICAgIHJldHVybjtcclxuXHJcbiAgICBpZiAodGhpcy5fZWxlbWVudFZpc2libGUpIHtcclxuICAgICAgdGhpcy5hZGRDbGFzc2VzKHRoaXMuX3Zpc2l0Q2xhc3MpO1xyXG4gICAgICBpZiAodGhpcy5hdXRvUmVtb3ZlKSB7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVDbGFzc2VzKHRoaXMuX2xlYXZlQ2xhc3MpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMucmVtb3ZlQ2xhc3Nlcyh0aGlzLl9yZW1vdmVWaXNpdENsYXNzKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICB0aGlzLmFkZENsYXNzZXModGhpcy5fbGVhdmVDbGFzcyk7XHJcbiAgICAgIGlmICh0aGlzLmF1dG9SZW1vdmUpIHtcclxuICAgICAgICB0aGlzLnJlbW92ZUNsYXNzZXModGhpcy5fdmlzaXRDbGFzcyk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5yZW1vdmVDbGFzc2VzKHRoaXMuX3JlbW92ZUxlYXZlQ2xhc3MpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIZWxwZXIgdG8gYWRkIGEgbGlzdCBvZiBjbGFzc2VzIHRvIHRoZSBlbGVtZW50LlxyXG4gICAqIEBwYXJhbSBjbGFzc2VzIFRoZSBsaXN0IG9mIGNsYXNzZXMgdG8gYWRkLlxyXG4gICAqIEByZXR1cm5zIHZvaWRcclxuICAgKi9cclxuICBwcml2YXRlIGFkZENsYXNzZXMoY2xhc3Nlczogc3RyaW5nW10pOiB2b2lkIHtcclxuICAgIGNsYXNzZXMuZm9yRWFjaChjbHMgPT4ge1xyXG4gICAgICBpZiAoIXRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhjbHMpKSB7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudCwgY2xzKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAqIEhlbHBlciB0byByZW1vdmUgYSBsaXN0IG9mIGNsYXNzZXMgZnJvbSB0aGUgZWxlbWVudC5cclxuICAqIEBwYXJhbSBjbGFzc2VzIFRoZSBsaXN0IG9mIGNsYXNzZXMgdG8gcmVtb3ZlLlxyXG4gICogQHJldHVybnMgdm9pZFxyXG4gICovXHJcbiAgcHJpdmF0ZSByZW1vdmVDbGFzc2VzKGNsYXNzZXM6IHN0cmluZ1tdKSB7XHJcbiAgICBjbGFzc2VzLmZvckVhY2goY2xzID0+IHtcclxuICAgICAgaWYgKHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhjbHMpKSB7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudCwgY2xzKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAqIEdldHMgdGhlIGhlaWdodCBvZiB0aGUgYnJvd3NlciB3aW5kb3cuIFxyXG4gICogQHJldHVybnMgdGhlIGhlaWdodCBvZiB0aGUgYnJvd3NlciB3aW5kb3cuXHJcbiAgKi9cclxuICBwcml2YXRlIGdldCB3aW5IZWlnaHQoKSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdy5pbm5lckhlaWdodCA6IDA7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAqIEdldHMgdGhlIG9mZnNldCBvZiB0aGUgZWxlbWVudC4gXHJcbiAgKiBAcmV0dXJucyBUaGUgZWxlbWVudHMgb2Zmc2V0LlxyXG4gICovXHJcbiAgcHJpdmF0ZSBnZXQgb2Zmc2V0VG9wKCkge1xyXG4gICAgaWYgKHR5cGVvZiB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QgPT09IFwiZnVuY3Rpb25cIikge1xyXG4gICAgICBjb25zdCB2aWV3cG9ydFRvcCA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcDtcclxuICAgICAgcmV0dXJuIHZpZXdwb3J0VG9wICsgdGhpcy5pbnRlcnNlY3Rpb25PYnNlcnZlclNlcnZpY2UucGFnZVlPZmZzZXQgLSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5jbGllbnRUb3A7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAqIEdldHMgdGhlIGhlaWdodCBvZiB0aGUgZWxlbWVudCAoSW5jbHVkaW5nIGJvcmRlcilcclxuICAqIEByZXR1cm5zIHRoZSBoZWlnaHQgb2YgdGhlIGVsZW1lbnQuXHJcbiAgKi9cclxuICBwcml2YXRlIGdldCBlbGVtZW50SGVpZ2h0KCkge1xyXG4gICAgcmV0dXJuIHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodCBhcyBudW1iZXI7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMuX3ZpZXdwb3J0Q2hhbmdlU3ViLnVuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==