UNPKG

carousel-angular

Version:

A simple carousel component for Angular 14+ based on 'angular-responsive-carousel' by Ivy Laboratory http://ivylab.space

258 lines 29.9 kB
export class Container { 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.initialPositionX = 0; this.initialElementPositionX = 0; this.pullLimit = 100; this.startTime = 0; this.startX = 0; this.moveX = 0; this.isSwipeInProgress = false; this.init(); } get visibleWidth() { return this.utils.visibleWidth; } get overflowCellsLimit() { return this.utils.overflowCellsLimit; } 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() { return this.cells.cellLength; } get tooFewCells() { return this.numberOfVisibleCells > this.cellLength; } get disabled() { return this.tooFewCells; } get margin() { return this.carouselProperties.margin; } 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 -= 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; const inertia = (distance / tapLength) * 100; return this.initialPositionX - inertia; } getAlignedPositionOnPull(newPositionX) { const direction = this.getDirection(); if (direction === 'left') { const endPosition = this.getEndPosition(); if (newPositionX < endPosition) { return endPosition; } } return newPositionX; } getCurrentPositionX() { const parentPosition = this.element.parentElement.getBoundingClientRect(); const position = this.element.getBoundingClientRect(); return position.left - parentPosition.left; } getEndPosition() { 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() { return this.cellLength * this.fullCellWidth; } 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGFpbmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvamVjdHMvY2Fyb3VzZWwtYW5ndWxhci9zcmMvbGliL2NvbnRhaW5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLE9BQU8sU0FBUztJQWtFcEIsWUFDVSxrQkFBc0MsRUFDdEMsS0FBVSxFQUNWLEtBQVU7UUFGVix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3RDLFVBQUssR0FBTCxLQUFLLENBQUs7UUFDVixVQUFLLEdBQUwsS0FBSyxDQUFLO1FBcEVwQjs7V0FFRztRQUNILHFCQUFnQixHQUFHLENBQUMsQ0FBQztRQUVyQiw0QkFBdUIsR0FBRyxDQUFDLENBQUM7UUFFNUIsY0FBUyxHQUFHLEdBQUcsQ0FBQztRQUVoQixjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBRWQsV0FBTSxHQUFHLENBQUMsQ0FBQztRQUVYLFVBQUssR0FBRyxDQUFDLENBQUM7UUFFVixzQkFBaUIsR0FBRyxLQUFLLENBQUM7UUF1RHhCLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNkLENBQUM7SUF0REQsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztJQUNqQyxDQUFDO0lBRUQsSUFBSSxrQkFBa0I7UUFDcEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDO0lBQ3ZDLENBQUM7SUFFRCxJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLENBQUM7SUFDOUMsQ0FBQztJQUVELElBQUksVUFBVTtRQUNaLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQztJQUM1QyxDQUFDO0lBRUQsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUM7SUFDNUUsQ0FBQztJ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SUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRELElBQUksU0FBUyxLQUFLLENBQUMsQ0FBQyxFQUFFO1lBQ3BCLE9BQU8sT0FBTyxDQUFDO1NBQ2hCO1FBQ0QsSUFBSSxTQUFTLEtBQUssQ0FBQyxFQUFFO1lBQ25CLE9BQU8sTUFBTSxDQUFDO1NBQ2Y7UUFFRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQcm9wZXJ0aWVzIGFzIENhcm91c2VsUHJvcGVydGllcyB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBjbGFzcyBDb250YWluZXIge1xuICAvKiBUaGUgaW5kZXggb2YgdGhlIG5ldyBwb3NpdGlvbiByZWxhdGl2ZSB0b1xuICAgKiB0aGUgYWN0aXZlIGluZGV4LCBmb3IgZXhhbXBsZSAtMSBvciArMVxuICAgKi9cbiAgaW5pdGlhbFBvc2l0aW9uWCA9IDA7XG5cbiAgaW5pdGlhbEVsZW1lbnRQb3NpdGlvblggPSAwO1xuXG4gIHB1bGxMaW1pdCA9IDEwMDtcblxuICBzdGFydFRpbWUgPSAwO1xuXG4gIHN0YXJ0WCA9IDA7XG5cbiAgbW92ZVggPSAwO1xuXG4gIGlzU3dpcGVJblByb2dyZXNzID0gZmFsc2U7XG5cbiAgZ2V0IHZpc2libGVXaWR0aCgpIHtcbiAgICByZXR1cm4gdGhpcy51dGlscy52aXNpYmxlV2lkdGg7XG4gIH1cblxuICBnZXQgb3ZlcmZsb3dDZWxsc0xpbWl0KCkge1xuICAgIHJldHVybiB0aGlzLnV0aWxzLm92ZXJmbG93Q2VsbHNMaW1pdDtcbiAgfVxuXG4gIGdldCBlbGVtZW50KCkge1xuICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy5jZWxsc0VsZW1lbnQ7XG4gIH1cblxuICBnZXQgZnJlZVNjcm9sbCgpIHtcbiAgICByZXR1cm4gdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMuZnJlZVNjcm9sbDtcbiAgfVxuXG4gIGdldCBmdWxsQ2VsbFdpZHRoKCkge1xuICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy5jZWxsV2lkdGggKyB0aGlzLmNhcm91c2VsUHJvcGVydGllcy5tYXJnaW47XG4gIH1cblxuICBnZXQgbnVtYmVyT2ZWaXNpYmxlQ2VsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudXRpbHMubnVtYmVyT2ZWaXNpYmxlQ2VsbHM7XG4gIH1cblxuICBnZXQgdHJhbnNpdGlvbkR1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy50cmFuc2l0aW9uRHVyYXRpb247XG4gIH1cblxuICBnZXQgdHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy50cmFuc2l0aW9uVGltaW5nRnVuY3Rpb247XG4gIH1cblxuICBnZXQgY2VsbExlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5jZWxscy5jZWxsTGVuZ3RoO1xuICB9XG5cbiAgZ2V0IHRvb0Zld0NlbGxzKCkge1xuICAgIHJldHVybiB0aGlzLm51bWJlck9mVmlzaWJsZUNlbGxzID4gdGhpcy5jZWxsTGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLnRvb0Zld0NlbGxzO1xuICB9XG5cbiAgZ2V0IG1hcmdpbigpIHtcbiAgICByZXR1cm4gdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMubWFyZ2luO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjYXJvdXNlbFByb3BlcnRpZXM6IENhcm91c2VsUHJvcGVydGllcyxcbiAgICBwcml2YXRlIHV0aWxzOiBhbnksXG4gICAgcHJpdmF0ZSBjZWxsczogYW55XG4gICkge1xuICAgIHRoaXMuaW5pdCgpO1xuICB9XG5cbiAgdXBkYXRlUHJvcGVydGllcyhjYXJvdXNlbFByb3BlcnRpZXM6IENhcm91c2VsUHJvcGVydGllcykge1xuICAgIHRoaXMuY2Fyb3VzZWxQcm9wZXJ0aWVzID0gY2Fyb3VzZWxQcm9wZXJ0aWVzO1xuICB9XG5cbiAgaW5pdCgpIHtcbiAgICB0aGlzLnNldFdpZHRoKCk7XG4gIH1cblxuICBoYW5kbGVUb3VjaHN0YXJ0KCkge1xuICAgIHRoaXMuc3RhcnRYID0gdGhpcy51dGlscy5nZXRTdGFydFgoZXZlbnQpO1xuICAgIHRoaXMuc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCA9IHRoaXMuZ2V0SW5pdGlhbEVsZW1lbnRQb3NpdGlvblgoKTtcbiAgfVxuXG4gIGhhbmRsZUhvcml6b250YWxTd2lwZSgpIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5pc1N3aXBlSW5Qcm9ncmVzcykge1xuICAgICAgdGhpcy5zdGFydFggPSB0aGlzLnV0aWxzLmdldFN0YXJ0WChldmVudCk7XG4gICAgICB0aGlzLnN0YXJ0VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCA9IHRoaXMuZ2V0SW5pdGlhbEVsZW1lbnRQb3NpdGlvblgoKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzU3dpcGVJblByb2dyZXNzID0gdHJ1ZTtcbiAgICB0aGlzLm1vdmVYID0gdGhpcy51dGlscy5nZXRNb3ZlWChldmVudCk7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBoYW5kbGVUb3VjaGVuZChzaW1wbGVQcm9jZXNzaW5nID0gZmFsc2UpIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8qIElmIHRvdWNoZW5kIHdhcyBwYXNzZWQgdG8gdGhlIFNsaWRlIGNsYXNzICovXG4gICAgaWYgKHNpbXBsZVByb2Nlc3NpbmcpIHtcbiAgICAgIHRoaXMuaXNTd2lwZUluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmlzU3dpcGVJblByb2dyZXNzID0gZmFsc2U7XG4gICAgdGhpcy5maW5pc2hNb3ZpbmcoKTtcbiAgICB0aGlzLmNsZWFySW5pdGlhbFZhbHVlcygpO1xuICB9XG5cbiAgbW92ZSgpIHtcbiAgICBsZXQgcG9zaXRpb25YOiBudW1iZXIgPSB0aGlzLmdldE1vdmVQb3NpdGlvblgoKTtcbiAgICBjb25zdCBpc1B1bGxlZCA9IHRoaXMuZGV0ZWN0UHVsbGVkKCk7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gdGhpcy5nZXREaXJlY3Rpb24oKTtcblxuICAgIGlmIChpc1B1bGxlZCkge1xuICAgICAgaWYgKFxuICAgICAgICAoaXNQdWxsZWQuZWRnZSA9PT0gJ2xlZnQnICYmIGRpcmVjdGlvbiA9PT0gJ3JpZ2h0JykgfHxcbiAgICAgICAgKGlzUHVsbGVkLmVkZ2UgPT09ICdyaWdodCcgJiYgZGlyZWN0aW9uID09PSAnbGVmdCcpXG4gICAgICApIHtcbiAgICAgICAgcG9zaXRpb25YID0gdGhpcy5zbG93ZG93bk9uUHVsbChwb3NpdGlvblgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudHJhbnNmb3JtUG9zaXRpb25YKHBvc2l0aW9uWCwgMCk7XG5cbiAgICBpZiAodGhpcy5mcmVlU2Nyb2xsKSB7XG4gICAgICB0aGlzLmluaXRpYWxQb3NpdGlvblggPSBwb3NpdGlvblg7XG4gICAgfVxuXG4gICAgaWYgKGlzUHVsbGVkKSB7XG4gICAgICBpZiAoaXNQdWxsZWQuZWRnZSA9PT0gJ2xlZnQnICYmIGlzUHVsbGVkLm92ZXJmbG93WCA+IHRoaXMucHVsbExpbWl0KSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbFBvc2l0aW9uWCA9IDA7XG4gICAgICB9XG4gICAgICBpZiAoaXNQdWxsZWQuZWRnZSA9PT0gJ3JpZ2h0JyAmJiBpc1B1bGxlZC5vdmVyZmxvd1ggPiB0aGlzLnB1bGxMaW1pdCkge1xuICAgICAgICB0aGlzLmluaXRpYWxQb3NpdGlvblggPSBwb3NpdGlvblg7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0TW92ZVBvc2l0aW9uWCgpIHtcbiAgICBjb25zdCBkaXN0YW5jZSA9IHRoaXMuZ2V0RGlzdGFuY2UoKTtcbiAgICByZXR1cm4gdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCAtIGRpc3RhbmNlO1xuICB9XG5cbiAgZ2V0RGlzdGFuY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhcnRYIC0gdGhpcy5tb3ZlWDtcbiAgfVxuXG4gIC8qIElmIHRoZSBjb250YWluZXIgaXMgcHVsbGVkIG91dCBvZiB0aGUgbGVmdCBvciByaWdodCBib3JkZXIgKi9cbiAgZGV0ZWN0UHVsbGVkKCkge1xuICAgIGNvbnN0IGN1cnJlbnRQb3NpdGlvblggPSB0aGlzLmdldEN1cnJlbnRQb3NpdGlvblgoKTtcblxuICAgIGlmIChjdXJyZW50UG9zaXRpb25YID4gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZWRnZTogJ2xlZnQnLFxuICAgICAgICBwb3NpdGlvblg6IGN1cnJlbnRQb3NpdGlvblgsXG4gICAgICAgIG92ZXJmbG93WDogTWF0aC5hYnMoY3VycmVudFBvc2l0aW9uWClcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnRQb3NpdGlvblggPCB0aGlzLmdldEVuZFBvc2l0aW9uKCkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVkZ2U6ICdyaWdodCcsXG4gICAgICAgIHBvc2l0aW9uWDogY3VycmVudFBvc2l0aW9uWCxcbiAgICAgICAgb3ZlcmZsb3dYOiBNYXRoLmFicyhjdXJyZW50UG9zaXRpb25YIC0gdGhpcy5nZXRFbmRQb3NpdGlvbigpKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgc2xvd2Rvd25PblB1bGwoX3Bvc2l0aW9uWDogbnVtYmVyKSB7XG4gICAgbGV0IGRpc3RhbmNlID0gTWF0aC5hYnModGhpcy5nZXREaXN0YW5jZSgpKTtcbiAgICBjb25zdCBlbmRQb3NpdGlvbiA9IHRoaXMuZ2V0RW5kUG9zaXRpb24oKTtcbiAgICBjb25zdCBpc1B1bGxlZCA9IHRoaXMuZGV0ZWN0UHVsbGVkKCk7XG5cbiAgICBpZiAoIWlzUHVsbGVkKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBjb25zdCBkZWNlbGVyYXRpb25SYXRpbyA9IDMgKyBpc1B1bGxlZC5vdmVyZmxvd1ggLyA1MDtcbiAgICBsZXQgcG9zaXRpb25YID0gMDtcblxuICAgIGlmIChpc1B1bGxlZC5lZGdlID09PSAnbGVmdCcpIHtcbiAgICAgIGlmICh0aGlzLmluaXRpYWxFbGVtZW50UG9zaXRpb25YIDwgMCkge1xuICAgICAgICBkaXN0YW5jZSAtPSBNYXRoLmFicyh0aGlzLmluaXRpYWxFbGVtZW50UG9zaXRpb25YKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcnViYmVyUG9zaXRpb25YID0gZGlzdGFuY2UgLyBkZWNlbGVyYXRpb25SYXRpbztcbiAgICAgIHBvc2l0aW9uWCA9IHJ1YmJlclBvc2l0aW9uWDtcblxuICAgICAgaWYgKHRoaXMuaW5pdGlhbEVsZW1lbnRQb3NpdGlvblggPiAwKSB7XG4gICAgICAgIHBvc2l0aW9uWCA9IHRoaXMuaW5pdGlhbEVsZW1lbnRQb3NpdGlvblggKyBydWJiZXJQb3NpdGlvblg7XG4gICAgICB9XG5cbiAgICAgIGlmIChwb3NpdGlvblggPiB0aGlzLnB1bGxMaW1pdCkge1xuICAgICAgICBwb3NpdGlvblggPSB0aGlzLnB1bGxMaW1pdDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNQdWxsZWQuZWRnZSA9PT0gJ3JpZ2h0Jykge1xuICAgICAgY29uc3QgcnViYmVyUG9zaXRpb25YID1cbiAgICAgICAgZW5kUG9zaXRpb24gK1xuICAgICAgICAodGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCAtIGRpc3RhbmNlIC0gZW5kUG9zaXRpb24pIC9cbiAgICAgICAgICBkZWNlbGVyYXRpb25SYXRpbztcbiAgICAgIGNvbnN0IGNvbnRhaW5lcldpZHRoID0gdGhpcy5nZXRXaWR0aCgpO1xuXG4gICAgICBwb3NpdGlvblggPSBydWJiZXJQb3NpdGlvblg7XG5cbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCA8IC0oY29udGFpbmVyV2lkdGggLSB0aGlzLnZpc2libGVXaWR0aClcbiAgICAgICkge1xuICAgICAgICBwb3NpdGlvblggPVxuICAgICAgICAgIGNvbnRhaW5lcldpZHRoIC1cbiAgICAgICAgICB0aGlzLnZpc2libGVXaWR0aCArXG4gICAgICAgICAgdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCArXG4gICAgICAgICAgcnViYmVyUG9zaXRpb25YO1xuICAgICAgfVxuXG4gICAgICBpZiAocG9zaXRpb25YIDwgZW5kUG9zaXRpb24gLSB0aGlzLnB1bGxMaW1pdCkge1xuICAgICAgICBwb3NpdGlvblggPSBlbmRQb3NpdGlvbiAtIHRoaXMucHVsbExpbWl0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwb3NpdGlvblg7XG4gIH1cblxuICBmaW5pc2hNb3ZpbmcoKSB7XG4gICAgY29uc3QgcG9zaXRpb25YID0gdGhpcy5nZXRNb3ZlUG9zaXRpb25YKCk7XG4gICAgbGV0IG5ld1Bvc2l0aW9uWCA9IDA7XG5cbiAgICBpZiAodGhpcy5mcmVlU2Nyb2xsKSB7XG4gICAgICBuZXdQb3NpdGlvblggPSB0aGlzLmdldEluZXJ0aWEoKTtcbiAgICB9XG5cbiAgICAvKiBBbGlnbiBjb250YWluZXIgd2hpbGUgcHVsbGluZyAqL1xuICAgIG5ld1Bvc2l0aW9uWCA9IHRoaXMuZ2V0QWxpZ25lZFBvc2l0aW9uT25QdWxsKG5ld1Bvc2l0aW9uWCk7XG5cbiAgICB0aGlzLnRyYW5zZm9ybVBvc2l0aW9uWChuZXdQb3NpdGlvblgpO1xuICAgIHRoaXMuc2V0SW5pdGlhbFBvc2l0aW9uKHBvc2l0aW9uWCk7XG4gIH1cblxuICAvKiBSZXR1cm5zIHRoZSBuZXcgcG9zaXRpb24gb2YgdGhlIGNvbnRhaW5lciB3aXRoIGluZXJ0aWEgKi9cbiAgZ2V0SW5lcnRpYSgpIHtcbiAgICBjb25zdCBkaXN0YW5jZSA9IHRoaXMuZ2V0RGlzdGFuY2UoKTtcbiAgICBjb25zdCBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIGNvbnN0IHRhcExlbmd0aCA9IGN1cnJlbnRUaW1lIC0gdGhpcy5zdGFydFRpbWU7XG4gICAgY29uc3QgaW5lcnRpYSA9IChkaXN0YW5jZSAvIHRhcExlbmd0aCkgKiAxMDA7XG5cbiAgICByZXR1cm4gdGhpcy5pbml0aWFsUG9zaXRpb25YIC0gaW5lcnRpYTtcbiAgfVxuXG4gIGdldEFsaWduZWRQb3NpdGlvbk9uUHVsbChuZXdQb3NpdGlvblg6IG51bWJlcikge1xuICAgIGNvbnN0IGRpcmVjdGlvbiA9IHRoaXMuZ2V0RGlyZWN0aW9uKCk7XG5cbiAgICBpZiAoZGlyZWN0aW9uID09PSAnbGVmdCcpIHtcbiAgICAgIGNvbnN0IGVuZFBvc2l0aW9uID0gdGhpcy5nZXRFbmRQb3NpdGlvbigpO1xuICAgICAgaWYgKG5ld1Bvc2l0aW9uWCA8IGVuZFBvc2l0aW9uKSB7XG4gICAgICAgIHJldHVybiBlbmRQb3NpdGlvbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3UG9zaXRpb25YO1xuICB9XG5cbiAgZ2V0Q3VycmVudFBvc2l0aW9uWCgpIHtcbiAgICBjb25zdCBwYXJlbnRQb3NpdGlvbiA9IHRoaXMuZWxlbWVudCEucGFyZW50RWxlbWVudCEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgcmV0dXJuIHBvc2l0aW9uLmxlZnQgLSBwYXJlbnRQb3NpdGlvbi5sZWZ0O1xuICB9XG5cbiAgZ2V0RW5kUG9zaXRpb24oKSB7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLmdldFdpZHRoKCk7XG4gICAgY29uc3QgdmlzaWJsZVdpZHRoID0gdGhpcy5lbGVtZW50IS5wYXJlbnRFbGVtZW50IS5jbGllbnRXaWR0aDtcbiAgICByZXR1cm4gdmlzaWJsZVdpZHRoIC0gd2lkdGg7XG4gIH1cblxuICB0cmFuc2Zvcm1Qb3NpdGlvblgodmFsdWU6IG51bWJlciwgZHVyYXRpb24gPSB0aGlzLnRyYW5zaXRpb25EdXJhdGlvbikge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnRyYW5zaXRpb24gPSBgdHJhbnNmb3JtICR7ZHVyYXRpb259bXMgJHt0aGlzLnRyYW5zaXRpb25UaW1pbmdGdW5jdGlvbn1gO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlWCgke3ZhbHVlfXB4KWA7XG4gIH1cblxuICBnZXRXaWR0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5jZWxsTGVuZ3RoICogdGhpcy5mdWxsQ2VsbFdpZHRoO1xuICB9XG5cbiAgc2V0V2lkdGgoKSB7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLmdldFdpZHRoKCk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLndpZHRoID0gYCR7d2lkdGh9cHhgO1xuICB9XG5cbiAgc2V0SW5pdGlhbFBvc2l0aW9uKHBvc2l0aW9uOiBudW1iZXIpIHtcbiAgICB0aGlzLmluaXRpYWxQb3NpdGlvblggPSBwb3NpdGlvbjtcbiAgfVxuXG4gIGdldEVsZW1lbnRQb3NpdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICB9XG5cbiAgZ2V0SW5pdGlhbEVsZW1lbnRQb3NpdGlvblgoKSB7XG4gICAgY29uc3QgY2Fyb3VzZWxFbGVtZW50UG9zaXRpb24gPVxuICAgICAgdGhpcy51dGlscy5nZXRDYXJvdXNlbEVsZW1lbnRQb3NpdGlvbigpLmxlZnQ7XG4gICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudFBvc2l0aW9uKCkubGVmdCAtIGNhcm91c2VsRWxlbWVudFBvc2l0aW9uO1xuICB9XG5cbiAgY2xlYXJJbml0aWFsVmFsdWVzKCkge1xuICAgIHRoaXMuc3RhcnRYID0gdGhpcy5tb3ZlWCA9IDA7XG4gIH1cblxuICBnZXREaXJlY3Rpb24oKSB7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gTWF0aC5zaWduKHRoaXMuc3RhcnRYIC0gdGhpcy5tb3ZlWCk7XG5cbiAgICBpZiAoZGlyZWN0aW9uID09PSAtMSkge1xuICAgICAgcmV0dXJuICdyaWdodCc7XG4gICAgfVxuICAgIGlmIChkaXJlY3Rpb24gPT09IDEpIHtcbiAgICAgIHJldHVybiAnbGVmdCc7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIl19