angular-responsive-carousel-ng16
Version:
Carousel for Angular. A simple solution for horizontal scrolling images with lazy loading.
294 lines • 35.6 kB
JavaScript
export class Container {
get visibleWidth() {
return this.utils.visibleWidth;
}
get overflowCellsLimit() {
return this.utils.overflowCellsLimit;
}
get images() {
return this.carouselProperties.images;
}
get element() {
return this.carouselProperties.cellsElement;
}
get freeScroll() {
return this.carouselProperties.freeScroll;
}
get fullCellWidth() {
return this.carouselProperties.cellWidth + this.carouselProperties.margin;
}
get numberOfVisibleCells() {
return this.utils.numberOfVisibleCells;
}
get transitionDuration() {
return this.carouselProperties.transitionDuration;
}
get transitionTimingFunction() {
return this.carouselProperties.transitionTimingFunction;
}
get cellLength() {
if (this.images) {
return this.images.length;
}
else {
return this.cells.cellLength;
}
}
get cellLengthInLightDOMMode() {
if (this.images) {
let cellLength = this.numberOfVisibleCells + this.overflowCellsLimit * 2;
if (cellLength > this.images.length) {
cellLength = this.images.length;
}
return cellLength;
}
else {
return this.cellLength;
}
}
get tooFewCells() {
return this.numberOfVisibleCells > this.cellLength;
}
get disabled() {
return this.tooFewCells;
}
get margin() {
return this.carouselProperties.margin;
}
get isLightDOM() {
return this.carouselProperties.lightDOM || this.carouselProperties.loop;
}
constructor(carouselProperties, utils, cells) {
this.carouselProperties = carouselProperties;
this.utils = utils;
this.cells = cells;
/* The index of the new position relative to
* the active index, for example -1 or +1
*/
this.newPositionIndex = 0;
this.isPositionCorrection = false;
this.initialPositionX = 0;
this.initialElementPositionX = 0;
this.isLocked = true;
this.pullLimit = 100;
this.startTime = 0;
this.startX = 0;
this.moveX = 0;
this.isSwipeInProgress = false;
this.init();
}
updateProperties(carouselProperties) {
this.carouselProperties = carouselProperties;
}
init() {
this.setWidth();
}
handleTouchstart() {
this.startX = this.utils.getStartX(event);
this.startTime = new Date().getTime();
this.initialElementPositionX = this.getInitialElementPositionX();
}
handleHorizontalSwipe() {
if (this.disabled) {
return;
}
if (!this.isSwipeInProgress) {
this.startX = this.utils.getStartX(event);
this.startTime = new Date().getTime();
this.initialElementPositionX = this.getInitialElementPositionX();
}
this.isSwipeInProgress = true;
this.moveX = this.utils.getMoveX(event);
this.move();
}
handleTouchend(simpleProcessing = false) {
if (this.disabled) {
return;
}
/* If touchend was passed to the Slide class */
if (simpleProcessing) {
this.isSwipeInProgress = false;
return;
}
this.isSwipeInProgress = false;
this.finishMoving();
this.clearInitialValues();
}
move() {
let positionX = this.getMovePositionX();
const isPulled = this.detectPulled();
const direction = this.getDirection();
if (isPulled) {
if (isPulled.edge === "left" && direction === "right" ||
isPulled.edge === "right" && direction === "left") {
positionX = this.slowdownOnPull(positionX);
}
}
this.transformPositionX(positionX, 0);
if (this.freeScroll) {
this.initialPositionX = positionX;
}
if (isPulled) {
if (isPulled.edge === 'left' && isPulled.overflowX > this.pullLimit) {
this.initialPositionX = 0;
}
if (isPulled.edge === 'right' && isPulled.overflowX > this.pullLimit) {
this.initialPositionX = positionX;
}
}
}
getMovePositionX() {
const distance = this.getDistance();
return this.initialElementPositionX - distance;
}
getDistance() {
return this.startX - this.moveX;
}
/* If the container is pulled out of the left or right border */
detectPulled() {
const currentPositionX = this.getCurrentPositionX();
if (currentPositionX > 0) {
return {
edge: 'left',
positionX: currentPositionX,
overflowX: Math.abs(currentPositionX)
};
}
if (currentPositionX < this.getEndPosition()) {
return {
edge: 'right',
positionX: currentPositionX,
overflowX: Math.abs(currentPositionX - this.getEndPosition())
};
}
return undefined;
}
slowdownOnPull(_positionX) {
let distance = Math.abs(this.getDistance());
const endPosition = this.getEndPosition();
const isPulled = this.detectPulled();
if (!isPulled) {
return 0;
}
const decelerationRatio = 3 + isPulled.overflowX / 50;
let positionX = 0;
if (isPulled.edge === 'left') {
if (this.initialElementPositionX < 0) {
distance = distance - Math.abs(this.initialElementPositionX);
}
const rubberPositionX = distance / decelerationRatio;
positionX = rubberPositionX;
if (this.initialElementPositionX > 0) {
positionX = this.initialElementPositionX + rubberPositionX;
}
if (positionX > this.pullLimit) {
positionX = this.pullLimit;
}
}
if (isPulled.edge === 'right') {
const rubberPositionX = endPosition + (((this.initialElementPositionX - distance) - endPosition) / decelerationRatio);
const containerWidth = this.getWidth();
positionX = rubberPositionX;
if (this.initialElementPositionX < -(containerWidth - this.visibleWidth)) {
positionX = ((containerWidth - this.visibleWidth) + this.initialElementPositionX) + rubberPositionX;
}
if (positionX < endPosition - this.pullLimit) {
positionX = endPosition - this.pullLimit;
}
}
return positionX;
}
finishMoving() {
const positionX = this.getMovePositionX();
let newPositionX = 0;
if (this.freeScroll) {
newPositionX = this.getInertia();
}
/* Align container while pulling */
newPositionX = this.getAlignedPositionOnPull(newPositionX);
this.transformPositionX(newPositionX);
this.setInitialPosition(positionX);
}
/* Returns the new position of the container with inertia */
getInertia() {
const distance = this.getDistance();
const currentTime = new Date().getTime();
const tapLength = currentTime - this.startTime;
let inertia = (distance / tapLength) * 100;
return this.initialPositionX - inertia;
}
getAlignedPositionOnPull(newPositionX) {
const direction = this.getDirection();
if (direction === 'left') {
let endPosition = this.getEndPosition();
if (newPositionX < endPosition) {
return endPosition;
}
}
if (direction === 'right') {
if (newPositionX > 0) {
return 0;
}
}
return newPositionX;
}
getCurrentPositionX() {
const parentPosition = this.element.parentElement.getBoundingClientRect();
const position = this.element.getBoundingClientRect();
return position.left - parentPosition.left;
}
getEndPosition() {
if (this.isLightDOM) {
let imagesInContainer = this.cells.imageUtils.getImages();
return -(imagesInContainer.length * this.fullCellWidth - this.visibleWidth - this.margin);
}
else {
const width = this.getWidth();
const visibleWidth = this.element.parentElement.clientWidth;
return visibleWidth - width;
}
}
transformPositionX(value, duration = this.transitionDuration) {
if (value === undefined) {
return;
}
this.element.style.transition = 'transform ' + duration + 'ms ' + this.transitionTimingFunction;
this.element.style.transform = 'translateX(' + value + 'px)';
}
getWidth() {
let width = this.cellLengthInLightDOMMode * this.fullCellWidth;
let totalImageWidth = this.cellLength * this.fullCellWidth;
if (totalImageWidth < width) {
width = totalImageWidth;
}
return this.isLightDOM ? width : totalImageWidth;
}
setWidth() {
const width = this.getWidth();
this.element.style.width = width + "px";
}
setInitialPosition(position) {
this.initialPositionX = position;
}
getElementPosition() {
return this.element.getBoundingClientRect();
}
getInitialElementPositionX() {
const carouselElementPosition = this.utils.getCarouselElementPosition()['left'];
return this.getElementPosition()['left'] - carouselElementPosition;
}
clearInitialValues() {
this.startX = this.moveX = 0;
}
getDirection() {
const direction = Math.sign(this.startX - this.moveX);
if (direction === -1) {
return 'right';
}
if (direction === 1) {
return 'left';
}
return undefined;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGFpbmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1yZXNwb25zaXZlLWNhcm91c2VsLW5nMTYvc3JjL2xpYi9jb250YWluZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxPQUFPLFNBQVM7SUFlbEIsSUFBSSxZQUFZO1FBQ1osT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztJQUNuQyxDQUFDO0lBRUQsSUFBSSxrQkFBa0I7UUFDbEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDO0lBQ3pDLENBQUM7SUFFRCxJQUFJLE1BQU07UUFDTixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUM7SUFDMUMsQ0FBQztJQUVELElBQUksT0FBTztRQUNQLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQztJQUNoRCxDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1YsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDO0lBQzlDLENBQUM7SUFFRCxJQUFJLGFBQWE7UUFDYixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQztJQUM5RSxDQUFDO0lBRUQsSUFBSSxvQkFBb0I7UUFDcEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDO0lBQzNDLENBQUM7SUFFRCxJQUFJLGtCQUFrQjtRQUNsQixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxrQkFBa0IsQ0FBQztJQUN0RCxDQUFDO0lBRUQsSUFBSSx3QkFBd0I7UUFDeEIsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsd0JBQXdCLENBQUM7SUFDNUQsQ0FBQztJQUVELElBQUksVUFBVTtRQUNWLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNiLE9BQU8sSUFB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LE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQ2hELENBQUM7SUFFRCwwQkFBMEI7UUFDdEIsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLDBCQUEwQixFQUFFLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEYsT0FBTyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyx1QkFBdUIsQ0FBQztJQUN2RSxDQUFDO0lBRUQsa0JBQWtCO1FBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsWUFBWTtRQUNSLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEQsSUFBSSxTQUFTLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFDbEIsT0FBTyxPQUFPLENBQUM7U0FDbEI7UUFDRCxJQUFJLFNBQVMsS0FBSyxDQUFDLEVBQUU7WUFDakIsT0FBTyxNQUFNLENBQUM7U0FDakI7UUFFRCxPQUFPLFNBQVMsQ0FBQztJQUNyQixDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1Byb3BlcnRpZXMgYXMgQ2Fyb3VzZWxQcm9wZXJ0aWVzfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuXG5leHBvcnQgY2xhc3MgQ29udGFpbmVyIHtcbiAgICAvKiBUaGUgaW5kZXggb2YgdGhlIG5ldyBwb3NpdGlvbiByZWxhdGl2ZSB0byBcbiAgICAgKiB0aGUgYWN0aXZlIGluZGV4LCBmb3IgZXhhbXBsZSAtMSBvciArMSBcbiAgICAgKi9cbiAgICBuZXdQb3NpdGlvbkluZGV4OiBudW1iZXIgPSAwO1xuICAgIGlzUG9zaXRpb25Db3JyZWN0aW9uOiBib29sZWFuID0gZmFsc2U7XG4gICAgaW5pdGlhbFBvc2l0aW9uWDogbnVtYmVyID0gMDtcbiAgICBpbml0aWFsRWxlbWVudFBvc2l0aW9uWDogbnVtYmVyID0gMDtcbiAgICBpc0xvY2tlZDogYm9vbGVhbiA9IHRydWU7XG4gICAgcHVsbExpbWl0OiBudW1iZXIgPSAxMDA7XG4gICAgc3RhcnRUaW1lOiBudW1iZXIgPSAwO1xuICAgIHN0YXJ0WDogbnVtYmVyID0gMDtcbiAgICBtb3ZlWDogbnVtYmVyID0gMDtcbiAgICBpc1N3aXBlSW5Qcm9ncmVzczogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgZ2V0IHZpc2libGVXaWR0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudXRpbHMudmlzaWJsZVdpZHRoO1xuICAgIH1cblxuICAgIGdldCBvdmVyZmxvd0NlbGxzTGltaXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnV0aWxzLm92ZXJmbG93Q2VsbHNMaW1pdDtcbiAgICB9XG5cbiAgICBnZXQgaW1hZ2VzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMuaW1hZ2VzO1xuICAgIH1cblxuICAgIGdldCBlbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMuY2VsbHNFbGVtZW50O1xuICAgIH1cblxuICAgIGdldCBmcmVlU2Nyb2xsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMuZnJlZVNjcm9sbDtcbiAgICB9XG5cbiAgICBnZXQgZnVsbENlbGxXaWR0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2Fyb3VzZWxQcm9wZXJ0aWVzLmNlbGxXaWR0aCArIHRoaXMuY2Fyb3VzZWxQcm9wZXJ0aWVzLm1hcmdpbjtcbiAgICB9XG5cbiAgICBnZXQgbnVtYmVyT2ZWaXNpYmxlQ2VsbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnV0aWxzLm51bWJlck9mVmlzaWJsZUNlbGxzO1xuICAgIH1cblxuICAgIGdldCB0cmFuc2l0aW9uRHVyYXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy50cmFuc2l0aW9uRHVyYXRpb247XG4gICAgfVxuXG4gICAgZ2V0IHRyYW5zaXRpb25UaW1pbmdGdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2Fyb3VzZWxQcm9wZXJ0aWVzLnRyYW5zaXRpb25UaW1pbmdGdW5jdGlvbjtcbiAgICB9XG5cbiAgICBnZXQgY2VsbExlbmd0aCgpIHtcbiAgICAgICAgaWYgKHRoaXMuaW1hZ2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5pbWFnZXMubGVuZ3RoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2VsbHMuY2VsbExlbmd0aDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBjZWxsTGVuZ3RoSW5MaWdodERPTU1vZGUoKSB7XG4gICAgICAgIGlmICh0aGlzLmltYWdlcykge1xuICAgICAgICAgICAgbGV0IGNlbGxMZW5ndGggPSB0aGlzLm51bWJlck9mVmlzaWJsZUNlbGxzICsgdGhpcy5vdmVyZmxvd0NlbGxzTGltaXQgKiAyO1xuICAgICAgICAgICAgaWYgKGNlbGxMZW5ndGggPiB0aGlzLmltYWdlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjZWxsTGVuZ3RoID0gdGhpcy5pbWFnZXMubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGNlbGxMZW5ndGg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jZWxsTGVuZ3RoO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IHRvb0Zld0NlbGxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5udW1iZXJPZlZpc2libGVDZWxscyA+IHRoaXMuY2VsbExlbmd0aDtcbiAgICB9XG5cbiAgICBnZXQgZGlzYWJsZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvb0Zld0NlbGxzO1xuICAgIH1cblxuICAgIGdldCBtYXJnaW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy5tYXJnaW47XG4gICAgfVxuXG4gICAgZ2V0IGlzTGlnaHRET00oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy5saWdodERPTSB8fCB0aGlzLmNhcm91c2VsUHJvcGVydGllcy5sb29wO1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgY2Fyb3VzZWxQcm9wZXJ0aWVzOiBDYXJvdXNlbFByb3BlcnRpZXMsXG4gICAgICAgIHByaXZhdGUgdXRpbHM6YW55LFxuICAgICAgICBwcml2YXRlIGNlbGxzOmFueSkge1xuXG4gICAgICAgIHRoaXMuaW5pdCgpXG4gICAgfVxuXG4gICAgdXBkYXRlUHJvcGVydGllcyhjYXJvdXNlbFByb3BlcnRpZXM6IENhcm91c2VsUHJvcGVydGllcykge1xuICAgICAgICB0aGlzLmNhcm91c2VsUHJvcGVydGllcyA9IGNhcm91c2VsUHJvcGVydGllcztcbiAgICB9XG5cbiAgICBpbml0KCkge1xuICAgICAgICB0aGlzLnNldFdpZHRoKCk7XG4gICAgfVxuXG4gICAgaGFuZGxlVG91Y2hzdGFydCgpIHtcbiAgICAgICAgdGhpcy5zdGFydFggPSB0aGlzLnV0aWxzLmdldFN0YXJ0WChldmVudCk7XG4gICAgICAgIHRoaXMuc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIHRoaXMuaW5pdGlhbEVsZW1lbnRQb3NpdGlvblggPSB0aGlzLmdldEluaXRpYWxFbGVtZW50UG9zaXRpb25YKCk7XG4gICAgfVxuXG4gICAgaGFuZGxlSG9yaXpvbnRhbFN3aXBlKCkge1xuICAgICAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmlzU3dpcGVJblByb2dyZXNzKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0WCA9IHRoaXMudXRpbHMuZ2V0U3RhcnRYKGV2ZW50KTtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxFbGVtZW50UG9zaXRpb25YID0gdGhpcy5nZXRJbml0aWFsRWxlbWVudFBvc2l0aW9uWCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pc1N3aXBlSW5Qcm9ncmVzcyA9IHRydWU7XG4gICAgICAgIHRoaXMubW92ZVggPSB0aGlzLnV0aWxzLmdldE1vdmVYKGV2ZW50KTtcbiAgICAgICAgdGhpcy5tb3ZlKCk7XG4gICAgfVxuXG4gICAgaGFuZGxlVG91Y2hlbmQoc2ltcGxlUHJvY2Vzc2luZzogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvKiBJZiB0b3VjaGVuZCB3YXMgcGFzc2VkIHRvIHRoZSBTbGlkZSBjbGFzcyAqL1xuICAgICAgICBpZiAoc2ltcGxlUHJvY2Vzc2luZykge1xuICAgICAgICAgICAgdGhpcy5pc1N3aXBlSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pc1N3aXBlSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZpbmlzaE1vdmluZygpO1xuICAgICAgICB0aGlzLmNsZWFySW5pdGlhbFZhbHVlcygpO1xuICAgIH1cblxuICAgIG1vdmUoKSB7XG4gICAgICAgIGxldCBwb3NpdGlvblg6IG51bWJlciA9IHRoaXMuZ2V0TW92ZVBvc2l0aW9uWCgpO1xuICAgICAgICBjb25zdCBpc1B1bGxlZCA9IHRoaXMuZGV0ZWN0UHVsbGVkKCk7XG4gICAgICAgIGNvbnN0IGRpcmVjdGlvbiA9IHRoaXMuZ2V0RGlyZWN0aW9uKCk7XG5cbiAgICAgICAgaWYgKGlzUHVsbGVkKSB7XG4gICAgICAgICAgICBpZiAoaXNQdWxsZWQuZWRnZSA9PT0gXCJsZWZ0XCIgJiYgZGlyZWN0aW9uID09PSBcInJpZ2h0XCIgfHxcbiAgICAgICAgICAgICAgICBpc1B1bGxlZC5lZGdlID09PSBcInJpZ2h0XCIgJiYgZGlyZWN0aW9uID09PSBcImxlZnRcIikge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uWCA9IHRoaXMuc2xvd2Rvd25PblB1bGwocG9zaXRpb25YKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudHJhbnNmb3JtUG9zaXRpb25YKHBvc2l0aW9uWCwgMCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZnJlZVNjcm9sbCkge1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsUG9zaXRpb25YID0gcG9zaXRpb25YO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzUHVsbGVkKSB7XG4gICAgICAgICAgICBpZiAoaXNQdWxsZWQuZWRnZSA9PT0gJ2xlZnQnICYmIGlzUHVsbGVkLm92ZXJmbG93WCA+IHRoaXMucHVsbExpbWl0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0aWFsUG9zaXRpb25YID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1B1bGxlZC5lZGdlID09PSAncmlnaHQnICYmIGlzUHVsbGVkLm92ZXJmbG93WCA+IHRoaXMucHVsbExpbWl0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0aWFsUG9zaXRpb25YID0gcG9zaXRpb25YO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0TW92ZVBvc2l0aW9uWCgpIHtcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSB0aGlzLmdldERpc3RhbmNlKCk7XG4gICAgICAgIHJldHVybiB0aGlzLmluaXRpYWxFbGVtZW50UG9zaXRpb25YIC0gZGlzdGFuY2U7XG4gICAgfVxuXG4gICAgZ2V0RGlzdGFuY2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXJ0WCAtIHRoaXMubW92ZVg7XG4gICAgfVxuXG4gICAgLyogSWYgdGhlIGNvbnRhaW5lciBpcyBwdWxsZWQgb3V0IG9mIHRoZSBsZWZ0IG9yIHJpZ2h0IGJvcmRlciAqL1xuICAgIGRldGVjdFB1bGxlZCgpIHtcbiAgICAgICAgY29uc3QgY3VycmVudFBvc2l0aW9uWCA9IHRoaXMuZ2V0Q3VycmVudFBvc2l0aW9uWCgpO1xuXG4gICAgICAgIGlmIChjdXJyZW50UG9zaXRpb25YID4gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBlZGdlOiAnbGVmdCcsXG4gICAgICAgICAgICAgICAgcG9zaXRpb25YOiBjdXJyZW50UG9zaXRpb25YLFxuICAgICAgICAgICAgICAgIG92ZXJmbG93WDogTWF0aC5hYnMoY3VycmVudFBvc2l0aW9uWClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjdXJyZW50UG9zaXRpb25YIDwgdGhpcy5nZXRFbmRQb3NpdGlvbigpKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGVkZ2U6ICdyaWdodCcsXG4gICAgICAgICAgICAgICAgcG9zaXRpb25YOiBjdXJyZW50UG9zaXRpb25YLFxuICAgICAgICAgICAgICAgIG92ZXJmbG93WDogTWF0aC5hYnMoY3VycmVudFBvc2l0aW9uWCAtIHRoaXMuZ2V0RW5kUG9zaXRpb24oKSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgc2xvd2Rvd25PblB1bGwoX3Bvc2l0aW9uWDogbnVtYmVyKSB7XG4gICAgICAgIGxldCBkaXN0YW5jZSA9IE1hdGguYWJzKHRoaXMuZ2V0RGlzdGFuY2UoKSk7XG4gICAgICAgIGNvbnN0IGVuZFBvc2l0aW9uID0gdGhpcy5nZXRFbmRQb3NpdGlvbigpO1xuICAgICAgICBjb25zdCBpc1B1bGxlZCA9IHRoaXMuZGV0ZWN0UHVsbGVkKCk7XG5cbiAgICAgICAgaWYgKCFpc1B1bGxlZCkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZWNlbGVyYXRpb25SYXRpbyA9IDMgKyBpc1B1bGxlZC5vdmVyZmxvd1ggLyA1MDtcbiAgICAgICAgbGV0IHBvc2l0aW9uWDpudW1iZXIgPSAwO1xuXG4gICAgICAgIGlmIChpc1B1bGxlZC5lZGdlID09PSAnbGVmdCcpIHtcblxuICAgICAgICAgICAgaWYgKHRoaXMuaW5pdGlhbEVsZW1lbnRQb3NpdGlvblggPCAwKSB7XG4gICAgICAgICAgICAgICAgZGlzdGFuY2UgPSBkaXN0YW5jZSAtIE1hdGguYWJzKHRoaXMuaW5pdGlhbEVsZW1lbnRQb3NpdGlvblgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBydWJiZXJQb3NpdGlvblggPSBkaXN0YW5jZSAvIGRlY2VsZXJhdGlvblJhdGlvO1xuICAgICAgICAgICAgcG9zaXRpb25YID0gcnViYmVyUG9zaXRpb25YO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCA+IDApIHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvblggPSB0aGlzLmluaXRpYWxFbGVtZW50UG9zaXRpb25YICsgcnViYmVyUG9zaXRpb25YO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocG9zaXRpb25YID4gdGhpcy5wdWxsTGltaXQpIHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvblggPSB0aGlzLnB1bGxMaW1pdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc1B1bGxlZC5lZGdlID09PSAncmlnaHQnKSB7XG4gICAgICAgICAgICBjb25zdCBydWJiZXJQb3NpdGlvblggPSBlbmRQb3NpdGlvbiArICgoKHRoaXMuaW5pdGlhbEVsZW1lbnRQb3NpdGlvblggLSBkaXN0YW5jZSkgLSBlbmRQb3NpdGlvbikgLyBkZWNlbGVyYXRpb25SYXRpbyk7XG4gICAgICAgICAgICBjb25zdCBjb250YWluZXJXaWR0aCA9IHRoaXMuZ2V0V2lkdGgoKTtcblxuICAgICAgICAgICAgcG9zaXRpb25YID0gcnViYmVyUG9zaXRpb25YO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCA8IC0oY29udGFpbmVyV2lkdGggLSB0aGlzLnZpc2libGVXaWR0aCkpIHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvblggPSAoKGNvbnRhaW5lcldpZHRoIC0gdGhpcy52aXNpYmxlV2lkdGgpICsgdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCkgKyBydWJiZXJQb3NpdGlvblg7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwb3NpdGlvblggPCBlbmRQb3NpdGlvbiAtIHRoaXMucHVsbExpbWl0KSB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb25YID0gZW5kUG9zaXRpb24gLSB0aGlzLnB1bGxMaW1pdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwb3NpdGlvblg7XG4gICAgfVxuXG4gICAgZmluaXNoTW92aW5nKCkge1xuICAgICAgICBjb25zdCBwb3NpdGlvblggPSB0aGlzLmdldE1vdmVQb3NpdGlvblgoKTtcbiAgICAgICAgbGV0IG5ld1Bvc2l0aW9uWDpudW1iZXIgPSAwO1xuXG4gICAgICAgIGlmICh0aGlzLmZyZWVTY3JvbGwpIHtcbiAgICAgICAgICAgIG5ld1Bvc2l0aW9uWCA9IHRoaXMuZ2V0SW5lcnRpYSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyogQWxpZ24gY29udGFpbmVyIHdoaWxlIHB1bGxpbmcgKi9cbiAgICAgICAgbmV3UG9zaXRpb25YID0gdGhpcy5nZXRBbGlnbmVkUG9zaXRpb25PblB1bGwobmV3UG9zaXRpb25YKTtcblxuICAgICAgICB0aGlzLnRyYW5zZm9ybVBvc2l0aW9uWChuZXdQb3NpdGlvblgpO1xuICAgICAgICB0aGlzLnNldEluaXRpYWxQb3NpdGlvbihwb3NpdGlvblgpO1xuICAgIH1cblxuICAgIC8qIFJldHVybnMgdGhlIG5ldyBwb3NpdGlvbiBvZiB0aGUgY29udGFpbmVyIHdpdGggaW5lcnRpYSAqL1xuICAgIGdldEluZXJ0aWEoKSB7XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gdGhpcy5nZXREaXN0YW5jZSgpO1xuICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCB0YXBMZW5ndGggPSBjdXJyZW50VGltZSAtIHRoaXMuc3RhcnRUaW1lO1xuICAgICAgICBsZXQgaW5lcnRpYSA9IChkaXN0YW5jZSAvIHRhcExlbmd0aCkgKiAxMDA7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaW5pdGlhbFBvc2l0aW9uWCAtIGluZXJ0aWE7XG4gICAgfVxuXG4gICAgZ2V0QWxpZ25lZFBvc2l0aW9uT25QdWxsKG5ld1Bvc2l0aW9uWDpudW1iZXIpIHtcbiAgICAgICAgY29uc3QgZGlyZWN0aW9uID0gdGhpcy5nZXREaXJlY3Rpb24oKTtcblxuICAgICAgICBpZiAoZGlyZWN0aW9uID09PSAnbGVmdCcpIHtcbiAgICAgICAgICAgIGxldCBlbmRQb3NpdGlvbiA9IHRoaXMuZ2V0RW5kUG9zaXRpb24oKTtcbiAgICAgICAgICAgIGlmIChuZXdQb3NpdGlvblggPCBlbmRQb3NpdGlvbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbmRQb3NpdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZGlyZWN0aW9uID09PSAncmlnaHQnKSB7XG4gICAgICAgICAgICBpZiAobmV3UG9zaXRpb25YID4gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ld1Bvc2l0aW9uWDtcbiAgICB9XG5cbiAgICBnZXRDdXJyZW50UG9zaXRpb25YKCkge1xuICAgICAgICBjb25zdCBwYXJlbnRQb3NpdGlvbiA9IHRoaXMuZWxlbWVudCEucGFyZW50RWxlbWVudCEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICByZXR1cm4gcG9zaXRpb24ubGVmdCAtIHBhcmVudFBvc2l0aW9uLmxlZnQ7XG4gICAgfVxuXG4gICAgZ2V0RW5kUG9zaXRpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLmlzTGlnaHRET00pIHtcbiAgICAgICAgICAgIGxldCBpbWFnZXNJbkNvbnRhaW5lciA9IHRoaXMuY2VsbHMuaW1hZ2VVdGlscy5nZXRJbWFnZXMoKTtcbiAgICAgICAgICAgIHJldHVybiAtKGltYWdlc0luQ29udGFpbmVyLmxlbmd0aCAqIHRoaXMuZnVsbENlbGxXaWR0aCAtIHRoaXMudmlzaWJsZVdpZHRoIC0gdGhpcy5tYXJnaW4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgd2lkdGggPSB0aGlzLmdldFdpZHRoKCk7XG4gICAgICAgICAgICBjb25zdCB2aXNpYmxlV2lkdGggPSB0aGlzLmVsZW1lbnQhLnBhcmVudEVsZW1lbnQhLmNsaWVudFdpZHRoO1xuICAgICAgICAgICAgcmV0dXJuIHZpc2libGVXaWR0aCAtIHdpZHRoO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdHJhbnNmb3JtUG9zaXRpb25YKHZhbHVlOm51bWJlciwgZHVyYXRpb24gPSB0aGlzLnRyYW5zaXRpb25EdXJhdGlvbikge1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLnRyYW5zaXRpb24gPSAndHJhbnNmb3JtICcgKyBkdXJhdGlvbiArICdtcyAnICsgdGhpcy50cmFuc2l0aW9uVGltaW5nRnVuY3Rpb247XG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlWCgnICsgdmFsdWUgKyAncHgpJztcbiAgICB9XG5cbiAgICBnZXRXaWR0aCgpIHtcbiAgICAgICAgbGV0IHdpZHRoID0gdGhpcy5jZWxsTGVuZ3RoSW5MaWdodERPTU1vZGUgKiB0aGlzLmZ1bGxDZWxsV2lkdGg7XG4gICAgICAgIGxldCB0b3RhbEltYWdlV2lkdGggPSB0aGlzLmNlbGxMZW5ndGggKiB0aGlzLmZ1bGxDZWxsV2lkdGg7XG5cbiAgICAgICAgaWYgKHRvdGFsSW1hZ2VXaWR0aCA8IHdpZHRoKSB7XG4gICAgICAgICAgICB3aWR0aCA9IHRvdGFsSW1hZ2VXaWR0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLmlzTGlnaHRET00gPyB3aWR0aCA6IHRvdGFsSW1hZ2VXaWR0aDtcbiAgICB9XG5cbiAgICBzZXRXaWR0aCgpIHtcbiAgICAgICAgY29uc3Qgd2lkdGggPSB0aGlzLmdldFdpZHRoKCk7XG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9IHdpZHRoICsgXCJweFwiO1xuICAgIH1cblxuICAgIHNldEluaXRpYWxQb3NpdGlvbihwb3NpdGlvbjpudW1iZXIpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsUG9zaXRpb25YID0gcG9zaXRpb247XG4gICAgfVxuXG4gICAgZ2V0RWxlbWVudFBvc2l0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIH1cblxuICAgIGdldEluaXRpYWxFbGVtZW50UG9zaXRpb25YKCkge1xuICAgICAgICBjb25zdCBjYXJvdXNlbEVsZW1lbnRQb3NpdGlvbiA9IHRoaXMudXRpbHMuZ2V0Q2Fyb3VzZWxFbGVtZW50UG9zaXRpb24oKVsnbGVmdCddO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50UG9zaXRpb24oKVsnbGVmdCddIC0gY2Fyb3VzZWxFbGVtZW50UG9zaXRpb247XG4gICAgfVxuXG4gICAgY2xlYXJJbml0aWFsVmFsdWVzKCkge1xuICAgICAgICB0aGlzLnN0YXJ0WCA9IHRoaXMubW92ZVggPSAwO1xuICAgIH1cblxuICAgIGdldERpcmVjdGlvbigpIHtcbiAgICAgICAgY29uc3QgZGlyZWN0aW9uID0gTWF0aC5zaWduKHRoaXMuc3RhcnRYIC0gdGhpcy5tb3ZlWCk7XG5cbiAgICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiAncmlnaHQnO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXJlY3Rpb24gPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiAnbGVmdCc7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbn0iXX0=