import { __assign } from 'tslib';
import { InjectionToken, Inject, Injectable, isDevMode, NgModule, defineInjectable, inject } from '@angular/core';

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Represents a scrolling action
 */
var  /**
 * Represents a scrolling action
 */
PageScrollInstance = /** @class */ (function () {
    /**
     * Private constructor, requires the properties assumed to be the bare minimum.
     * Use the factory methods to create instances:
     *      {@link PageScrollService#create}
     */
    function PageScrollInstance(pageScrollOptions) {
        /**
         * These properties will be set/manipulated if the scroll animation starts
         */
        /* The initial value of the scrollTop or scrollLeft position when the animation starts */
        this.startScrollPosition = 0;
        /* Whether an interrupt listener is attached to the body or not */
        this.interruptListenersAttached = false;
        /* References to the timer instance that is used to perform the scroll animation to be
           able to clear it on animation end*/
        this.timer = null;
        if (!pageScrollOptions.scrollViews || pageScrollOptions.scrollViews.length === 0) {
            pageScrollOptions.scrollViews = [
                pageScrollOptions.document.documentElement,
                pageScrollOptions.document.body,
                pageScrollOptions.document.body.parentNode,
            ];
            this.isInlineScrolling = false;
        }
        else {
            this.isInlineScrolling = true;
        }
        this.pageScrollOptions = pageScrollOptions;
    }
    /**
     * @private
     * @param {?} pageScrollOptions
     * @param {?} scrollTargetElement
     * @return {?}
     */
    PageScrollInstance.getScrollingTargetPosition = /**
     * @private
     * @param {?} pageScrollOptions
     * @param {?} scrollTargetElement
     * @return {?}
     */
    function (pageScrollOptions, scrollTargetElement) {
        /** @type {?} */
        var body = pageScrollOptions.document.body;
        /** @type {?} */
        var docEl = pageScrollOptions.document.documentElement;
        /** @type {?} */
        var windowPageYOffset = pageScrollOptions.document.defaultView &&
            pageScrollOptions.document.defaultView.pageYOffset || undefined;
        /** @type {?} */
        var windowPageXOffset = pageScrollOptions.document.defaultView &&
            pageScrollOptions.document.defaultView.pageXOffset || undefined;
        /** @type {?} */
        var scrollTop = windowPageYOffset || docEl.scrollTop || body.scrollTop;
        /** @type {?} */
        var scrollLeft = windowPageXOffset || docEl.scrollLeft || body.scrollLeft;
        /** @type {?} */
        var clientTop = docEl.clientTop || body.clientTop || 0;
        /** @type {?} */
        var clientLeft = docEl.clientLeft || body.clientLeft || 0;
        if (scrollTargetElement === undefined || scrollTargetElement === null) {
            // No element found, so return the current position to not cause any change in scroll position
            return { top: scrollTop, left: scrollLeft };
        }
        /** @type {?} */
        var box = scrollTargetElement.getBoundingClientRect();
        /** @type {?} */
        var top = box.top + scrollTop - clientTop;
        /** @type {?} */
        var left = box.left + scrollLeft - clientLeft;
        return { top: Math.round(top), left: Math.round(left) };
    };
    /**
     * @private
     * @param {?} pageScrollOptions
     * @param {?} scrollTargetElement
     * @return {?}
     */
    PageScrollInstance.getInlineScrollingTargetPosition = /**
     * @private
     * @param {?} pageScrollOptions
     * @param {?} scrollTargetElement
     * @return {?}
     */
    function (pageScrollOptions, scrollTargetElement) {
        /** @type {?} */
        var position = { top: scrollTargetElement.offsetTop, left: scrollTargetElement.offsetLeft };
        if (pageScrollOptions.advancedInlineOffsetCalculation && pageScrollOptions.scrollViews.length === 1) {
            /** @type {?} */
            var accumulatedParentsPos = { top: 0, left: 0 };
            // not named window to make sure we're not getting the global window variable by accident
            /** @type {?} */
            var theWindow = scrollTargetElement.ownerDocument.defaultView;
            /** @type {?} */
            var parentFound = false;
            // Start parent is the immediate parent
            /** @type {?} */
            var parent_1 = scrollTargetElement.parentElement;
            // Iterate upwards all parents
            while (!parentFound && parent_1 !== undefined && parent_1 !== null) {
                if (theWindow.getComputedStyle(parent_1).getPropertyValue('position') === 'relative') {
                    accumulatedParentsPos.top += parent_1.offsetTop;
                    accumulatedParentsPos.left += parent_1.offsetLeft;
                }
                // Next iteration
                parent_1 = parent_1.parentElement;
                parentFound = parent_1 === pageScrollOptions.scrollViews[0];
            }
            if (parentFound) {
                // Only use the results if we found the parent, otherwise we accumulated too much anyway
                position.top += accumulatedParentsPos.top;
                position.left += accumulatedParentsPos.left;
            }
        }
        return position;
    };
    /**
     * @param {?} scrollingView
     * @return {?}
     */
    PageScrollInstance.prototype.getScrollPropertyValue = /**
     * @param {?} scrollingView
     * @return {?}
     */
    function (scrollingView) {
        if (!this.pageScrollOptions.verticalScrolling) {
            return scrollingView.scrollLeft;
        }
        return scrollingView.scrollTop;
    };
    /**
     * Extract the exact location of the scrollTarget element.
     *
     * Extract the scrollTarget HTMLElement from the given PageScrollTarget object. The latter one may be
     * a string like "#heading2", then this method returns the corresponding DOM element for that id.
     *
     */
    /**
     * Extract the exact location of the scrollTarget element.
     *
     * Extract the scrollTarget HTMLElement from the given PageScrollTarget object. The latter one may be
     * a string like "#heading2", then this method returns the corresponding DOM element for that id.
     *
     * @return {?}
     */
    PageScrollInstance.prototype.extractScrollTargetPosition = /**
     * Extract the exact location of the scrollTarget element.
     *
     * Extract the scrollTarget HTMLElement from the given PageScrollTarget object. The latter one may be
     * a string like "#heading2", then this method returns the corresponding DOM element for that id.
     *
     * @return {?}
     */
    function () {
        /** @type {?} */
        var scrollTargetElement = this.getScrollTargetElement();
        if (scrollTargetElement === null || scrollTargetElement === undefined) {
            // Scroll target not found
            return { top: NaN, left: NaN };
        }
        if (this.isInlineScrolling) {
            return PageScrollInstance.getInlineScrollingTargetPosition(this.pageScrollOptions, scrollTargetElement);
        }
        return PageScrollInstance.getScrollingTargetPosition(this.pageScrollOptions, scrollTargetElement);
    };
    /**
     * Get the top offset of the scroll animation.
     * This automatically takes the offset location of the scrolling container/scrolling view
     * into account (for nested/inline scrolling).
     */
    /**
     * Get the top offset of the scroll animation.
     * This automatically takes the offset location of the scrolling container/scrolling view
     * into account (for nested/inline scrolling).
     * @return {?}
     */
    PageScrollInstance.prototype.getCurrentOffset = /**
     * Get the top offset of the scroll animation.
     * This automatically takes the offset location of the scrolling container/scrolling view
     * into account (for nested/inline scrolling).
     * @return {?}
     */
    function () {
        return this.pageScrollOptions.scrollOffset;
    };
    /**
     * Sets the "scrollTop" or "scrollLeft" property for all scrollViews to the provided value
     * @return true if at least for one ScrollTopSource the scrollTop/scrollLeft value could be set and it kept the new value.
     *          false if it failed for all ScrollViews, meaning that we should stop the animation
     *          (probably because we're at the end of the scrolling region)
     */
    /**
     * Sets the "scrollTop" or "scrollLeft" property for all scrollViews to the provided value
     * @param {?} position
     * @return {?} true if at least for one ScrollTopSource the scrollTop/scrollLeft value could be set and it kept the new value.
     *          false if it failed for all ScrollViews, meaning that we should stop the animation
     *          (probably because we're at the end of the scrolling region)
     */
    PageScrollInstance.prototype.setScrollPosition = /**
     * Sets the "scrollTop" or "scrollLeft" property for all scrollViews to the provided value
     * @param {?} position
     * @return {?} true if at least for one ScrollTopSource the scrollTop/scrollLeft value could be set and it kept the new value.
     *          false if it failed for all ScrollViews, meaning that we should stop the animation
     *          (probably because we're at the end of the scrolling region)
     */
    function (position) {
        var _this = this;
        // Set the new scrollTop/scrollLeft to all scrollViews elements
        return this.pageScrollOptions.scrollViews.reduce((/**
         * @param {?} oneAlreadyWorked
         * @param {?} scrollingView
         * @return {?}
         */
        function (oneAlreadyWorked, scrollingView) {
            /** @type {?} */
            var startScrollPropertyValue = _this.getScrollPropertyValue(scrollingView);
            if (scrollingView && startScrollPropertyValue !== undefined && startScrollPropertyValue !== null) {
                /** @type {?} */
                var scrollDistance = Math.abs(startScrollPropertyValue - position);
                // The movement we need to perform is less than 2px
                // This we consider a small movement which some browser may not perform when
                // changing the scrollTop/scrollLeft property
                // Thus in this cases we do not stop the scroll animation, although setting the
                // scrollTop/scrollLeft value "fails"
                /** @type {?} */
                var isSmallMovement = scrollDistance < _this.pageScrollOptions._minScrollDistance;
                if (!_this.pageScrollOptions.verticalScrolling) {
                    scrollingView.scrollLeft = position;
                }
                else {
                    scrollingView.scrollTop = position;
                }
                // Return true if setting the new scrollTop/scrollLeft value worked
                // We consider that it worked if the new scrollTop/scrollLeft value is closer to the
                // desired scrollTop/scrollLeft than before (it might not be exactly the value we
                // set due to dpi or rounding irregularities)
                if (isSmallMovement || scrollDistance > Math.abs(_this.getScrollPropertyValue(scrollingView) - position)) {
                    return true;
                }
            }
            return oneAlreadyWorked;
        }), false);
    };
    /**
     * Trigger firing a animation finish event
     * @param value Whether the animation finished at the target (true) or got interrupted (false)
     */
    /**
     * Trigger firing a animation finish event
     * @param {?} value Whether the animation finished at the target (true) or got interrupted (false)
     * @return {?}
     */
    PageScrollInstance.prototype.fireEvent = /**
     * Trigger firing a animation finish event
     * @param {?} value Whether the animation finished at the target (true) or got interrupted (false)
     * @return {?}
     */
    function (value) {
        if (this.pageScrollOptions.scrollFinishListener) {
            this.pageScrollOptions.scrollFinishListener.emit(value);
        }
    };
    /**
     * Attach the interrupt listeners to the PageScrollInstance body. The given interruptReporter
     * will be called if any of the attached events is fired.
     *
     * Possibly attached interruptListeners are automatically removed from the body before the new one will be attached.
     */
    /**
     * Attach the interrupt listeners to the PageScrollInstance body. The given interruptReporter
     * will be called if any of the attached events is fired.
     *
     * Possibly attached interruptListeners are automatically removed from the body before the new one will be attached.
     * @param {?} interruptReporter
     * @return {?}
     */
    PageScrollInstance.prototype.attachInterruptListeners = /**
     * Attach the interrupt listeners to the PageScrollInstance body. The given interruptReporter
     * will be called if any of the attached events is fired.
     *
     * Possibly attached interruptListeners are automatically removed from the body before the new one will be attached.
     * @param {?} interruptReporter
     * @return {?}
     */
    function (interruptReporter) {
        var _this = this;
        if (this.interruptListenersAttached) {
            // Detach possibly existing listeners first
            this.detachInterruptListeners();
        }
        this.interruptListener = (/**
         * @param {?} event
         * @return {?}
         */
        function (event) {
            interruptReporter.report(event, _this);
        });
        this.pageScrollOptions.interruptEvents.forEach((/**
         * @param {?} event
         * @return {?}
         */
        function (event) { return _this.pageScrollOptions.document.body.addEventListener(event, _this.interruptListener); }));
        this.interruptListenersAttached = true;
    };
    /**
     * Remove event listeners from the body and stop listening for events that might be treated as "animation
     * interrupt" events.
     */
    /**
     * Remove event listeners from the body and stop listening for events that might be treated as "animation
     * interrupt" events.
     * @return {?}
     */
    PageScrollInstance.prototype.detachInterruptListeners = /**
     * Remove event listeners from the body and stop listening for events that might be treated as "animation
     * interrupt" events.
     * @return {?}
     */
    function () {
        var _this = this;
        this.pageScrollOptions.interruptEvents.forEach((/**
         * @param {?} event
         * @return {?}
         */
        function (event) { return _this.pageScrollOptions.document.body.removeEventListener(event, _this.interruptListener); }));
        this.interruptListenersAttached = false;
    };
    /**
     * @private
     * @return {?}
     */
    PageScrollInstance.prototype.getScrollTargetElement = /**
     * @private
     * @return {?}
     */
    function () {
        if (typeof this.pageScrollOptions.scrollTarget === 'string') {
            /** @type {?} */
            var targetSelector = (/** @type {?} */ (this.pageScrollOptions.scrollTarget));
            if (targetSelector.match(/^#[^\s]+$/g) !== null) {
                // It's an id selector and a valid id, as it does not contain any white space characters
                return this.pageScrollOptions.document.getElementById(targetSelector.substr(1));
            }
            return (/** @type {?} */ (this.pageScrollOptions.document.querySelector(targetSelector)));
        }
        return (/** @type {?} */ (this.pageScrollOptions.scrollTarget));
    };
    return PageScrollInstance;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/** @type {?} */
var NGXPS_CONFIG = new InjectionToken('ngxps_config');
/** @type {?} */
var defaultPageScrollConfig = {
    _interval: 10,
    _minScrollDistance: 2,
    _logLevel: 1,
    namespace: 'default',
    verticalScrolling: true,
    duration: 1250,
    scrollOffset: 0,
    advancedInlineOffsetCalculation: false,
    interruptEvents: ['mousedown', 'wheel', 'DOMMouseScroll', 'mousewheel', 'keyup', 'touchmove'],
    interruptKeys: [' ', 'Escape', 'Tab', 'Enter', 'PageUp', 'PageDown', 'Home', 'End', 'ArrowUp', 'ArrowRight', 'ArrowLeft', 'ArrowDown'],
    interruptible: true,
    easingLogic: (/**
     * @param {?} t
     * @param {?} b
     * @param {?} c
     * @param {?} d
     * @return {?}
     */
    function (t, b, c, d) {
        // Linear easing
        return c * t / d + b;
    }),
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var PageScrollService = /** @class */ (function () {
    function PageScrollService(customConfig) {
        var _this = this;
        this.runningInstances = [];
        this.onInterrupted = {
            report: (/**
             * @param {?} event
             * @param {?} pageScrollInstance
             * @return {?}
             */
            function (event, pageScrollInstance) {
                if (!pageScrollInstance.pageScrollOptions.interruptible) {
                    // Non-interruptible anyway, so do not stop anything
                    return;
                }
                /** @type {?} */
                var shouldStop = true;
                if (event.type === 'keyup') {
                    // Only stop if specific keys have been pressed, for all others don't stop anything
                    if (_this.config.interruptKeys.indexOf(((/** @type {?} */ (event))).key) === -1) {
                        // The pressed key is not in the list of interrupting keys
                        shouldStop = false;
                    }
                }
                else if (event.type === 'mousedown') {
                    // For mousedown events we only stop the scroll animation of the mouse has
                    // been clicked inside the scrolling container
                    if (!pageScrollInstance.pageScrollOptions.scrollViews.some((/**
                     * @param {?} scrollingView
                     * @return {?}
                     */
                    function (scrollingView) { return scrollingView.contains((/** @type {?} */ (event.target))); }))) {
                        // Mouse clicked an element which is not inside any of the the scrolling containers
                        shouldStop = false;
                    }
                }
                if (shouldStop) {
                    _this.stopAll(pageScrollInstance.pageScrollOptions.namespace);
                }
            }),
        };
        this.config = __assign({}, defaultPageScrollConfig, customConfig);
        if (PageScrollService.instanceCounter > 0 &&
            (this.config._logLevel >= 2 || (this.config._logLevel >= 1 && isDevMode()))) {
            console.warn('An instance of PageScrollService already exists, usually ' +
                'including one provider should be enough, so double check.');
        }
        PageScrollService.instanceCounter++;
    }
    /**
     * @private
     * @param {?} interrupted
     * @param {?} pageScrollInstance
     * @return {?}
     */
    PageScrollService.prototype.stopInternal = /**
     * @private
     * @param {?} interrupted
     * @param {?} pageScrollInstance
     * @return {?}
     */
    function (interrupted, pageScrollInstance) {
        /** @type {?} */
        var index = this.runningInstances.indexOf(pageScrollInstance);
        if (index >= 0) {
            this.runningInstances.splice(index, 1);
        }
        if (pageScrollInstance.interruptListenersAttached) {
            pageScrollInstance.detachInterruptListeners();
        }
        if (pageScrollInstance.timer) {
            // Clear/Stop the timer
            clearInterval(pageScrollInstance.timer);
            // Clear the reference to this timer
            pageScrollInstance.timer = undefined;
            pageScrollInstance.fireEvent(!interrupted);
            return true;
        }
        return false;
    };
    /**
     * @param {?} options
     * @return {?}
     */
    PageScrollService.prototype.create = /**
     * @param {?} options
     * @return {?}
     */
    function (options) {
        return new PageScrollInstance((/** @type {?} */ (__assign({}, this.config, options))));
    };
    /**
     * Start a scroll animation. All properties of the animation are stored in the given {@link PageScrollInstance} object.
     *
     * This is the core functionality of the whole library.
     */
    // tslint:disable-next-line:cyclomatic-complexity
    /**
     * Start a scroll animation. All properties of the animation are stored in the given {\@link PageScrollInstance} object.
     *
     * This is the core functionality of the whole library.
     * @param {?} pageScrollInstance
     * @return {?}
     */
    // tslint:disable-next-line:cyclomatic-complexity
    PageScrollService.prototype.start = /**
     * Start a scroll animation. All properties of the animation are stored in the given {\@link PageScrollInstance} object.
     *
     * This is the core functionality of the whole library.
     * @param {?} pageScrollInstance
     * @return {?}
     */
    // tslint:disable-next-line:cyclomatic-complexity
    function (pageScrollInstance) {
        var _this = this;
        // Merge the default options in the pageScrollInstance options
        pageScrollInstance.pageScrollOptions = (/** @type {?} */ (__assign({}, this.config, pageScrollInstance.pageScrollOptions)));
        // Stop all possibly running scroll animations in the same namespace
        this.stopAll(pageScrollInstance.pageScrollOptions.namespace);
        if (pageScrollInstance.pageScrollOptions.scrollViews === null || pageScrollInstance.pageScrollOptions.scrollViews.length === 0) {
            // No scrollViews specified, thus we can't animate anything
            if (this.config._logLevel >= 2 || (this.config._logLevel >= 1 && isDevMode())) {
                console.warn('No scrollViews specified, thus ngx-page-scroll does not know which DOM elements to scroll');
            }
            return;
        }
        /** @type {?} */
        var startScrollPositionFound = false;
        // Reset start scroll position to 0. If any of the scrollViews has a different one, it will be extracted next
        pageScrollInstance.startScrollPosition = 0;
        // Get the start scroll position from the scrollViews (e.g. if the user already scrolled down the content)
        pageScrollInstance.pageScrollOptions.scrollViews.forEach((/**
         * @param {?} scrollingView
         * @return {?}
         */
        function (scrollingView) {
            if (scrollingView === undefined || scrollingView === null) {
                return;
            }
            // Get the scrollTop or scrollLeft value of the first scrollingView that returns a value for its "scrollTop"
            // or "scrollLeft" property that is not undefined and unequal to 0
            /** @type {?} */
            var scrollPosition = pageScrollInstance.getScrollPropertyValue(scrollingView);
            if (!startScrollPositionFound && scrollPosition) {
                // We found a scrollingView that does not have scrollTop or scrollLeft 0
                // Return the scroll position value, as this will be our startScrollPosition
                pageScrollInstance.startScrollPosition = scrollPosition;
                startScrollPositionFound = true;
            }
        }));
        /** @type {?} */
        var pageScrollOffset = pageScrollInstance.getCurrentOffset();
        // Calculate the target position that the scroll animation should go to
        /** @type {?} */
        var scrollTargetPosition = pageScrollInstance.extractScrollTargetPosition();
        pageScrollInstance.targetScrollPosition = Math.round((pageScrollInstance.pageScrollOptions.verticalScrolling ? scrollTargetPosition.top : scrollTargetPosition.left) - pageScrollOffset);
        // Calculate the distance we need to go in total
        pageScrollInstance.distanceToScroll = pageScrollInstance.targetScrollPosition - pageScrollInstance.startScrollPosition;
        if (isNaN(pageScrollInstance.distanceToScroll)) {
            // We weren't able to find the target position, maybe the element does not exist?
            if (this.config._logLevel >= 2 || (this.config._logLevel >= 1 && isDevMode())) {
                console.log('Scrolling not possible, as we can\'t find the specified target');
            }
            pageScrollInstance.fireEvent(false);
            return;
        }
        // We're at the final destination already
        // OR we need to scroll down but are already at the end
        // OR we need to scroll up but are at the top already
        /** @type {?} */
        var allReadyAtDestination = Math.abs(pageScrollInstance.distanceToScroll) < pageScrollInstance.pageScrollOptions._minScrollDistance;
        // Check how long we need to scroll if a speed option is given
        // Default executionDuration is the specified duration
        pageScrollInstance.executionDuration = pageScrollInstance.pageScrollOptions.duration;
        // Maybe we need to pay attention to the speed option?
        if ((pageScrollInstance.pageScrollOptions.speed !== undefined && pageScrollInstance.pageScrollOptions.speed !== null) &&
            (pageScrollInstance.pageScrollOptions.duration === undefined || pageScrollInstance.pageScrollOptions.duration === null)) {
            // Speed option is set and no duration => calculate duration based on speed and scroll distance
            pageScrollInstance.executionDuration =
                Math.abs(pageScrollInstance.distanceToScroll) / pageScrollInstance.pageScrollOptions.speed * 1000;
        }
        // We should go there directly, as our "animation" would have one big step
        // only anyway and this way we save the interval stuff
        /** @type {?} */
        var tooShortInterval = pageScrollInstance.executionDuration <= pageScrollInstance.pageScrollOptions._interval;
        if (allReadyAtDestination || tooShortInterval) {
            if (this.config._logLevel >= 2 || (this.config._logLevel >= 1 && isDevMode())) {
                if (allReadyAtDestination) {
                    console.log('Scrolling not possible, as we can\'t get any closer to the destination');
                }
                else {
                    console.log('Scroll duration shorter that interval length, jumping to target');
                }
            }
            pageScrollInstance.setScrollPosition(pageScrollInstance.targetScrollPosition);
            pageScrollInstance.fireEvent(true);
            return;
        }
        // Register the interrupt listeners if we want an interruptible scroll animation
        if (pageScrollInstance.pageScrollOptions.interruptible) {
            pageScrollInstance.attachInterruptListeners(this.onInterrupted);
        }
        // Let's get started, get the start time...
        pageScrollInstance.startTime = new Date().getTime();
        // .. and calculate the end time (when we need to finish at last)
        pageScrollInstance.endTime = pageScrollInstance.startTime + pageScrollInstance.executionDuration;
        pageScrollInstance.timer = setInterval((/**
         * @param {?} _pageScrollInstance
         * @return {?}
         */
        function (_pageScrollInstance) {
            // Take the current time
            /** @type {?} */
            var currentTime = new Date().getTime();
            // Determine the new scroll position
            /** @type {?} */
            var newScrollPosition;
            /** @type {?} */
            var stopNow = false;
            if (_pageScrollInstance.endTime <= currentTime) {
                // We're over the time already, so go the targetScrollPosition (aka destination)
                newScrollPosition = _pageScrollInstance.targetScrollPosition;
                stopNow = true;
            }
            else {
                // Calculate the scroll position based on the current time using the easing function
                newScrollPosition = Math.round(_pageScrollInstance.pageScrollOptions.easingLogic(currentTime - _pageScrollInstance.startTime, _pageScrollInstance.startScrollPosition, _pageScrollInstance.distanceToScroll, _pageScrollInstance.executionDuration));
            }
            if (_this.config._logLevel >= 5 && isDevMode()) {
                console.warn('Scroll Position: ' + newScrollPosition);
            }
            // Set the new scrollPosition to all scrollViews elements
            if (!_pageScrollInstance.setScrollPosition(newScrollPosition)) {
                // Setting the new scrollTop/scrollLeft value failed for all ScrollViews
                // early stop the scroll animation to save resources
                stopNow = true;
            }
            // At the end do the internal stop maintenance and fire the pageScrollFinish event
            // (otherwise the event might arrive at "too early")
            if (stopNow) {
                _this.stopInternal(false, _pageScrollInstance);
            }
        }), this.config._interval, pageScrollInstance);
        // Register the instance as running one
        this.runningInstances.push(pageScrollInstance);
    };
    /**
     * @param {?} options
     * @return {?}
     */
    PageScrollService.prototype.scroll = /**
     * @param {?} options
     * @return {?}
     */
    function (options) {
        this.start(this.create(options));
    };
    /**
     * Stop all running scroll animations. Optionally limit to stop only the ones of specific namespace.
     */
    /**
     * Stop all running scroll animations. Optionally limit to stop only the ones of specific namespace.
     * @param {?=} namespace
     * @return {?}
     */
    PageScrollService.prototype.stopAll = /**
     * Stop all running scroll animations. Optionally limit to stop only the ones of specific namespace.
     * @param {?=} namespace
     * @return {?}
     */
    function (namespace) {
        if (this.runningInstances.length > 0) {
            /** @type {?} */
            var stoppedSome = false;
            for (var i = 0; i < this.runningInstances.length; ++i) {
                /** @type {?} */
                var pageScrollInstance = this.runningInstances[i];
                if (!namespace || pageScrollInstance.pageScrollOptions.namespace === namespace) {
                    stoppedSome = true;
                    this.stopInternal(true, pageScrollInstance);
                    // Decrease the counter, as we removed an item from the array we iterate over
                    i--;
                }
            }
            return stoppedSome;
        }
        return false;
    };
    /**
     * @param {?} pageScrollInstance
     * @return {?}
     */
    PageScrollService.prototype.stop = /**
     * @param {?} pageScrollInstance
     * @return {?}
     */
    function (pageScrollInstance) {
        return this.stopInternal(true, pageScrollInstance);
    };
    PageScrollService.instanceCounter = 0;
    PageScrollService.decorators = [
        { type: Injectable, args: [{
                    providedIn: 'root',
                },] }
    ];
    /** @nocollapse */
    PageScrollService.ctorParameters = function () { return [
        { type: undefined, decorators: [{ type: Inject, args: [NGXPS_CONFIG,] }] }
    ]; };
    /** @nocollapse */ PageScrollService.ngInjectableDef = defineInjectable({ factory: function PageScrollService_Factory() { return new PageScrollService(inject(NGXPS_CONFIG)); }, token: PageScrollService, providedIn: "root" });
    return PageScrollService;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var ɵ0 = {};
var NgxPageScrollCoreModule = /** @class */ (function () {
    function NgxPageScrollCoreModule() {
    }
    /**
     * @param {?=} config
     * @return {?}
     */
    NgxPageScrollCoreModule.forRoot = /**
     * @param {?=} config
     * @return {?}
     */
    function (config) {
        return {
            ngModule: NgxPageScrollCoreModule,
            providers: [PageScrollService, { provide: NGXPS_CONFIG, useValue: config }],
        };
    };
    NgxPageScrollCoreModule.decorators = [
        { type: NgModule, args: [{
                    providers: [
                        PageScrollService,
                        { provide: NGXPS_CONFIG, useValue: ɵ0 },
                    ],
                },] }
    ];
    return NgxPageScrollCoreModule;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

export { NgxPageScrollCoreModule, NGXPS_CONFIG, defaultPageScrollConfig, PageScrollService, PageScrollInstance };

//# sourceMappingURL=ngx-page-scroll-core.js.map