import * as i0 from '@angular/core';
import { InjectionToken, input, booleanAttribute, output, signal, inject, ElementRef, Renderer2, NgZone, Directive, viewChild, contentChildren, Component } from '@angular/core';

const CAROUSEL = new InjectionToken('CAROUSEL');
const CAROUSEL_CARD = new InjectionToken('CAROUSEL_CARD');

function easeOutQuad(t) {
    return t * (2 - t);
}
class DraggableCarouselDirective {
    cardSelector = input('.ngs-carousel-card', ...(ngDevMode ? [{ debugName: "cardSelector" }] : /* istanbul ignore next */ []));
    snapToCenter = input(true, ...(ngDevMode ? [{ debugName: "snapToCenter" }] : /* istanbul ignore next */ []));
    snapDebounceTime = input(50, ...(ngDevMode ? [{ debugName: "snapDebounceTime" }] : /* istanbul ignore next */ []));
    snapDuration = input(300, ...(ngDevMode ? [{ debugName: "snapDuration" }] : /* istanbul ignore next */ []));
    resistanceFactor = input(0.5, ...(ngDevMode ? [{ debugName: "resistanceFactor" }] : /* istanbul ignore next */ []));
    velocityThreshold = input(0.5, ...(ngDevMode ? [{ debugName: "velocityThreshold" }] : /* istanbul ignore next */ []));
    visibilityDebounceTime = input(100, ...(ngDevMode ? [{ debugName: "visibilityDebounceTime" }] : /* istanbul ignore next */ []));
    stopPropagation = input(true, { ...(ngDevMode ? { debugName: "stopPropagation" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    indexChange = output();
    isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
    startX = signal(0, ...(ngDevMode ? [{ debugName: "startX" }] : /* istanbul ignore next */ []));
    scrollLeftStart = signal(0, ...(ngDevMode ? [{ debugName: "scrollLeftStart" }] : /* istanbul ignore next */ []));
    currentTranslateX = signal(0, ...(ngDevMode ? [{ debugName: "currentTranslateX" }] : /* istanbul ignore next */ []));
    lastMoveX = signal(null, ...(ngDevMode ? [{ debugName: "lastMoveX" }] : /* istanbul ignore next */ []));
    lastMoveTime = signal(null, ...(ngDevMode ? [{ debugName: "lastMoveTime" }] : /* istanbul ignore next */ []));
    currentVelocityX = signal(0, ...(ngDevMode ? [{ debugName: "currentVelocityX" }] : /* istanbul ignore next */ []));
    lastEmittedIndex = signal(null, ...(ngDevMode ? [{ debugName: "lastEmittedIndex" }] : /* istanbul ignore next */ []));
    snapTimeoutId = null;
    scrollAnimationId = null;
    transformAnimationId = null;
    visibilityDebounceTimeoutId = null;
    el = inject((ElementRef));
    renderer = inject(Renderer2);
    zone = inject(NgZone);
    hostElement;
    cards = [];
    ngOnInit() {
        this.hostElement = this.el.nativeElement;
        this.renderer.setStyle(this.hostElement, 'cursor', 'grab');
        this.hostElement.style.scrollBehavior = 'auto';
    }
    ngAfterContentInit() {
        this.cards = Array.from(this.hostElement.querySelectorAll(this.cardSelector()));
        // Initial state calculation after content is initialized and layout is stable
        setTimeout(() => {
            const actualInitialIndex = this.findCurrentCenterIndex();
            this.emitActiveIndex(actualInitialIndex);
            this.updateCardVisibilityClasses();
        }, 0);
    }
    ngOnDestroy() {
        this.clearSnapTimeout();
        this.cancelScrollAnimation();
        this.cancelTransformAnimation();
        clearTimeout(this.visibilityDebounceTimeoutId);
    }
    onScroll(event) {
        if (this.isDragging() || this.scrollAnimationId !== null || this.transformAnimationId !== null) {
            return;
        }
        if (this.visibilityDebounceTimeoutId !== null) {
            clearTimeout(this.visibilityDebounceTimeoutId);
        }
        this.visibilityDebounceTimeoutId = setTimeout(() => {
            this.updateCardVisibilityClasses();
            const currentIndex = this.findCurrentCenterIndex();
            this.emitActiveIndex(currentIndex);
            this.visibilityDebounceTimeoutId = null;
        }, this.visibilityDebounceTime());
    }
    onMouseDown(event) {
        clearTimeout(this.visibilityDebounceTimeoutId);
        this.clearSnapTimeout();
        this.cancelScrollAnimation();
        this.cancelTransformAnimation();
        if (this.currentTranslateX() !== 0) {
            this.currentTranslateX.set(0);
            this.renderer.setStyle(this.hostElement, 'transform', '');
        }
        this.hostElement.style.scrollBehavior = 'auto';
        if (event.button !== 0)
            return;
        this.isDragging.set(true);
        this.startX.set(event.pageX - this.hostElement.offsetLeft);
        this.scrollLeftStart.set(this.hostElement.scrollLeft);
        this.lastMoveX.set(event.pageX);
        this.lastMoveTime.set(event.timeStamp);
        this.currentVelocityX.set(0);
        this.renderer.setStyle(this.hostElement, 'cursor', 'grabbing');
        event.preventDefault();
    }
    onMouseMove(event) {
        if (!this.isDragging())
            return;
        event.preventDefault();
        const currentX = event.pageX;
        const currentTime = event.timeStamp;
        const lastMoveTime = this.lastMoveTime();
        const lastMoveX = this.lastMoveX();
        if (lastMoveTime !== null && lastMoveX !== null && currentTime > lastMoveTime) {
            const deltaX = currentX - lastMoveX;
            const deltaTime = currentTime - lastMoveTime;
            if (deltaTime > 0) {
                this.currentVelocityX.set(-deltaX / deltaTime);
            }
        }
        this.lastMoveX.set(currentX);
        this.lastMoveTime.set(currentTime);
        const dragDeltaX = currentX - (this.startX() + this.hostElement.offsetLeft);
        const intendedScrollLeft = this.scrollLeftStart() - dragDeltaX;
        const maxScrollLeft = this.hostElement.scrollWidth - this.hostElement.clientWidth;
        let targetScrollLeft = intendedScrollLeft;
        let translateX = 0;
        if (intendedScrollLeft < 0) {
            targetScrollLeft = 0;
            const overpull = -intendedScrollLeft;
            translateX = Math.min(overpull * this.resistanceFactor(), this.hostElement.clientWidth * 0.4);
        }
        else if (intendedScrollLeft > maxScrollLeft) {
            targetScrollLeft = maxScrollLeft;
            const overpull = intendedScrollLeft - maxScrollLeft;
            translateX = -Math.min(overpull * this.resistanceFactor(), this.hostElement.clientWidth * 0.4);
        }
        if (this.hostElement.scrollLeft !== targetScrollLeft) {
            this.hostElement.scrollLeft = targetScrollLeft;
        }
        if (this.currentTranslateX() !== translateX) {
            this.currentTranslateX.set(translateX);
            if (Math.abs(translateX) > 0.1) {
                this.renderer.setStyle(this.hostElement, 'transform', `translateX(${translateX}px)`);
            }
            else {
                this.currentTranslateX.set(0);
                this.renderer.setStyle(this.hostElement, 'transform', '');
            }
        }
    }
    onMouseUpOrLeave(event) {
        if (!this.isDragging()) {
            return;
        }
        this.stopDragging();
        if (this.stopPropagation()) {
            event.stopPropagation();
            event.preventDefault();
            event.stopImmediatePropagation();
        }
    }
    onMouseLeaveElement(event) {
        if (!this.isDragging()) {
            this.renderer.setStyle(this.hostElement, 'cursor', 'grab');
        }
    }
    stopDragging() {
        if (!this.isDragging())
            return;
        this.isDragging.set(false);
        this.renderer.setStyle(this.hostElement, 'cursor', 'grab');
        this.clearSnapTimeout();
        const wasPulled = Math.abs(this.currentTranslateX()) > 0.1;
        if (wasPulled) {
            this.snapTimeoutId = setTimeout(() => {
                this.animateTransformReset();
                this.snapTimeoutId = null;
            }, this.snapDebounceTime() / 2);
        }
        else if (this.snapToCenter()) {
            this.snapTimeoutId = setTimeout(() => {
                this.initiateSnap();
                this.snapTimeoutId = null;
            }, this.snapDebounceTime());
        }
        else {
            this.updateCardVisibilityClasses();
            const currentIndex = this.findCurrentCenterIndex();
            this.emitActiveIndex(currentIndex);
        }
    }
    initiateSnap() {
        this.cards = Array.from(this.hostElement.querySelectorAll(this.cardSelector()));
        if (!this.cards.length)
            return;
        let targetCardIndex = -1;
        const currentScroll = this.hostElement.scrollLeft;
        const containerCenter = currentScroll + this.hostElement.clientWidth / 2;
        let currentNearestCardIndex = this.findNearestCardIndex(this.cards, containerCenter);
        if (currentNearestCardIndex < 0)
            return;
        const absVelocity = Math.abs(this.currentVelocityX());
        const threshold = this.velocityThreshold();
        if (absVelocity > threshold) {
            if (this.currentVelocityX() < 0) {
                targetCardIndex = currentNearestCardIndex - 1;
            }
            else {
                targetCardIndex = currentNearestCardIndex + 1;
            }
            targetCardIndex = Math.max(0, Math.min(targetCardIndex, this.cards.length - 1));
        }
        else {
            targetCardIndex = currentNearestCardIndex;
        }
        if (targetCardIndex >= 0 && targetCardIndex < this.cards.length) {
            this.scrollToCard(targetCardIndex, false);
        }
        else {
            this.updateCardVisibilityClasses();
        }
    }
    scrollToCard(index, immediate = false) {
        if (index < 0 || index >= this.cards.length) {
            return;
        }
        const targetCard = this.cards[index];
        if (!targetCard)
            return;
        const container = this.hostElement;
        const containerWidth = container.clientWidth;
        const targetCardLeft = targetCard.offsetLeft;
        const targetCardWidth = targetCard.offsetWidth;
        let targetScrollLeft = targetCardLeft + targetCardWidth / 2 - containerWidth / 2;
        const maxScrollLeft = container.scrollWidth - containerWidth;
        targetScrollLeft = Math.max(0, Math.min(targetScrollLeft, maxScrollLeft));
        this.cancelScrollAnimation();
        if (immediate) {
            container.scrollLeft = targetScrollLeft;
            this.updateCardVisibilityClasses();
            this.emitActiveIndex(index);
        }
        else {
            this.animateScroll(targetScrollLeft);
        }
    }
    findNearestCardIndex(cards, position) {
        let nearestIndex = -1;
        let minDistance = Infinity;
        cards.forEach((card, index) => {
            if (card instanceof HTMLElement) {
                const cardLeft = card.offsetLeft;
                const cardWidth = card.offsetWidth;
                const cardCenter = cardLeft + cardWidth / 2;
                const distance = Math.abs(cardCenter - position);
                if (distance < minDistance) {
                    minDistance = distance;
                    nearestIndex = index;
                }
            }
        });
        return nearestIndex;
    }
    animateTransformReset() {
        this.cancelTransformAnimation();
        const startTranslateX = this.currentTranslateX();
        const distance = 0 - startTranslateX;
        if (Math.abs(distance) < 1) {
            if (startTranslateX !== 0) {
                this.currentTranslateX.set(0);
                this.renderer.setStyle(this.hostElement, 'transform', '');
                const finalIndex = this.findCurrentCenterIndex();
                this.emitActiveIndex(finalIndex);
                this.updateCardVisibilityClasses();
            }
            return;
        }
        const duration = this.snapDuration();
        let startTime = null;
        const step = (timestamp) => {
            if (startTime === null)
                startTime = timestamp;
            const elapsed = timestamp - startTime;
            const progress = Math.min(1, elapsed / duration);
            const easedProgress = easeOutQuad(progress);
            const newTranslateX = startTranslateX + distance * easedProgress;
            this.currentTranslateX.set(newTranslateX);
            this.renderer.setStyle(this.hostElement, 'transform', `translateX(${newTranslateX}px)`);
            if (progress < 1) {
                this.transformAnimationId = requestAnimationFrame(step);
            }
            else {
                this.currentTranslateX.set(0);
                this.renderer.setStyle(this.hostElement, 'transform', '');
                this.transformAnimationId = null;
                const finalIndex = this.findCurrentCenterIndex();
                this.emitActiveIndex(finalIndex);
                this.updateCardVisibilityClasses();
            }
        };
        this.zone.runOutsideAngular(() => {
            this.transformAnimationId = requestAnimationFrame(step);
        });
    }
    animateScroll(targetScrollLeft) {
        this.cancelScrollAnimation();
        const container = this.hostElement;
        const startScrollLeft = container.scrollLeft;
        const distance = targetScrollLeft - startScrollLeft;
        if (Math.abs(distance) < 1) {
            const finalIndex = this.findCurrentCenterIndex();
            this.emitActiveIndex(finalIndex);
            this.updateCardVisibilityClasses();
            return;
        }
        const duration = this.snapDuration();
        let startTime = null;
        const step = (timestamp) => {
            if (startTime === null)
                startTime = timestamp;
            const elapsed = timestamp - startTime;
            const progress = Math.min(1, elapsed / duration);
            const easedProgress = easeOutQuad(progress);
            container.scrollLeft = startScrollLeft + distance * easedProgress;
            if (progress < 1) {
                this.scrollAnimationId = requestAnimationFrame(step);
            }
            else {
                container.scrollLeft = targetScrollLeft;
                this.scrollAnimationId = null;
                const finalIndex = this.findCurrentCenterIndex();
                this.emitActiveIndex(finalIndex);
                this.updateCardVisibilityClasses();
            }
        };
        this.zone.runOutsideAngular(() => {
            this.scrollAnimationId = requestAnimationFrame(step);
        });
    }
    findCurrentCenterIndex() {
        this.cards = Array.from(this.hostElement.querySelectorAll(this.cardSelector()));
        if (!this.cards.length)
            return -1;
        const currentScroll = this.hostElement.scrollLeft;
        const containerCenter = currentScroll + this.hostElement.clientWidth / 2;
        return this.findNearestCardIndex(this.cards, containerCenter);
    }
    emitActiveIndex(index) {
        if (index >= 0 && index !== this.lastEmittedIndex()) {
            this.lastEmittedIndex.set(index);
            this.zone.run(() => {
                this.indexChange.emit(index);
            });
        }
    }
    updateCardVisibilityClasses() {
        this.cards = Array.from(this.hostElement.querySelectorAll(this.cardSelector()));
        if (!this.cards.length || !this.hostElement.clientWidth)
            return;
        const viewportStart = this.hostElement.scrollLeft;
        const viewportWidth = this.hostElement.clientWidth;
        const viewportEnd = viewportStart + viewportWidth;
        const tolerance = 1;
        this.cards.forEach(card => {
            if (card instanceof HTMLElement) {
                const cardStart = card.offsetLeft;
                const cardEnd = cardStart + card.offsetWidth;
                const isSpanned = cardStart >= viewportStart - tolerance && cardEnd <= viewportEnd + tolerance;
                const isInView = cardEnd > viewportStart + tolerance && cardStart < viewportEnd - tolerance;
                if (isSpanned) {
                    this.renderer.addClass(card, 'is-spanned');
                }
                else {
                    this.renderer.removeClass(card, 'is-spanned');
                }
                if (isInView) {
                    this.renderer.addClass(card, 'is-in-view');
                }
                else {
                    this.renderer.removeClass(card, 'is-in-view');
                }
            }
        });
    }
    cancelScrollAnimation() {
        if (this.scrollAnimationId !== null) {
            cancelAnimationFrame(this.scrollAnimationId);
            this.scrollAnimationId = null;
        }
    }
    cancelTransformAnimation() {
        if (this.transformAnimationId !== null) {
            cancelAnimationFrame(this.transformAnimationId);
            this.transformAnimationId = null;
        }
    }
    clearSnapTimeout() {
        if (this.snapTimeoutId !== null) {
            clearTimeout(this.snapTimeoutId);
            this.snapTimeoutId = null;
        }
    }
    onClick(event) {
        if (this.stopPropagation()) {
            event.stopPropagation();
            event.preventDefault();
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DraggableCarouselDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.4", type: DraggableCarouselDirective, isStandalone: true, selector: "[ngsDraggableCarousel]", inputs: { cardSelector: { classPropertyName: "cardSelector", publicName: "cardSelector", isSignal: true, isRequired: false, transformFunction: null }, snapToCenter: { classPropertyName: "snapToCenter", publicName: "snapToCenter", isSignal: true, isRequired: false, transformFunction: null }, snapDebounceTime: { classPropertyName: "snapDebounceTime", publicName: "snapDebounceTime", isSignal: true, isRequired: false, transformFunction: null }, snapDuration: { classPropertyName: "snapDuration", publicName: "snapDuration", isSignal: true, isRequired: false, transformFunction: null }, resistanceFactor: { classPropertyName: "resistanceFactor", publicName: "resistanceFactor", isSignal: true, isRequired: false, transformFunction: null }, velocityThreshold: { classPropertyName: "velocityThreshold", publicName: "velocityThreshold", isSignal: true, isRequired: false, transformFunction: null }, visibilityDebounceTime: { classPropertyName: "visibilityDebounceTime", publicName: "visibilityDebounceTime", isSignal: true, isRequired: false, transformFunction: null }, stopPropagation: { classPropertyName: "stopPropagation", publicName: "stopPropagation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexChange: "indexChange" }, host: { listeners: { "scroll": "onScroll($event)", "click": "onClick($event)", "mousedown": "onMouseDown($event)", "mouseleave": "onMouseLeaveElement($event)", "document:mousemove": "onMouseMove($event)", "document:mouseup": "onMouseUpOrLeave($event)", "document:mouseleave": "onMouseUpOrLeave($event)" }, properties: { "class.dragging-active": "isDragging()" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DraggableCarouselDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[ngsDraggableCarousel]',
                    host: {
                        '(scroll)': 'onScroll($event)',
                        '(click)': 'onClick($event)',
                        '(mousedown)': 'onMouseDown($event)',
                        '(mouseleave)': 'onMouseLeaveElement($event)',
                        '(document:mousemove)': 'onMouseMove($event)',
                        '(document:mouseup)': 'onMouseUpOrLeave($event)',
                        '(document:mouseleave)': 'onMouseUpOrLeave($event)',
                        '[class.dragging-active]': 'isDragging()'
                    }
                }]
        }], propDecorators: { cardSelector: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardSelector", required: false }] }], snapToCenter: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToCenter", required: false }] }], snapDebounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapDebounceTime", required: false }] }], snapDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapDuration", required: false }] }], resistanceFactor: [{ type: i0.Input, args: [{ isSignal: true, alias: "resistanceFactor", required: false }] }], velocityThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "velocityThreshold", required: false }] }], visibilityDebounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibilityDebounceTime", required: false }] }], stopPropagation: [{ type: i0.Input, args: [{ isSignal: true, alias: "stopPropagation", required: false }] }], indexChange: [{ type: i0.Output, args: ["indexChange"] }] } });

class Carousel {
    _content = viewChild.required('content');
    _cards = contentChildren(CAROUSEL_CARD, ...(ngDevMode ? [{ debugName: "_cards" }] : /* istanbul ignore next */ []));
    fade = input(false, { ...(ngDevMode ? { debugName: "fade" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    snapToCenter = input(true, ...(ngDevMode ? [{ debugName: "snapToCenter" }] : /* istanbul ignore next */ []));
    snapDebounceTime = input(50, ...(ngDevMode ? [{ debugName: "snapDebounceTime" }] : /* istanbul ignore next */ []));
    snapDuration = input(300, ...(ngDevMode ? [{ debugName: "snapDuration" }] : /* istanbul ignore next */ []));
    resistanceFactor = input(0.5, ...(ngDevMode ? [{ debugName: "resistanceFactor" }] : /* istanbul ignore next */ []));
    velocityThreshold = input(0.5, ...(ngDevMode ? [{ debugName: "velocityThreshold" }] : /* istanbul ignore next */ []));
    visibilityDebounceTime = input(100, ...(ngDevMode ? [{ debugName: "visibilityDebounceTime" }] : /* istanbul ignore next */ []));
    stopPropagation = input(true, { ...(ngDevMode ? { debugName: "stopPropagation" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    indexChange = output();
    _index = signal(0, ...(ngDevMode ? [{ debugName: "_index" }] : /* istanbul ignore next */ []));
    get api() {
        return {
            isNextDisabled: () => this._isNextDisabled,
            isPreviousDisabled: () => this._isPreviousDisabled,
            previous: () => this._previous(),
            next: () => this._next(),
            selectedIndex: () => this._index()
        };
    }
    onIndexChanged(index) {
        if (this._index() === index) {
            return;
        }
        this._index.set(index);
        this.indexChange.emit(index);
    }
    _previous() {
        const contentElement = this._content()?.nativeElement;
        for (let index = this._cards().length - 1; index >= 0; index--) {
            if (index >= this._index()) {
                continue;
            }
            const card = this._cards().at(index);
            if (!this._visibleInParentViewport(contentElement, card.element)) {
                this._scrollToCard(card);
                break;
            }
        }
    }
    _next() {
        const contentElement = this._content().nativeElement;
        const notVisibleCard = this._cards().find((card, index) => !this._visibleInParentViewport(contentElement, card.element) && index > this._index());
        if (notVisibleCard) {
            this._scrollToCard(notVisibleCard);
        }
    }
    _scrollToCard(notVisibleCard) {
        this._index.set(this._cards().findIndex(card => card === notVisibleCard));
        this.indexChange.emit(this._index());
        notVisibleCard.element.scrollIntoView({
            block: 'nearest',
            behavior: 'smooth',
            inline: 'center'
        });
    }
    _visibleInParentViewport = (parent, el) => {
        const parentRect = parent.getBoundingClientRect();
        const elementRect = el.getBoundingClientRect();
        return (elementRect.right <= parentRect.right &&
            elementRect.left >= parentRect.left);
    };
    get _isPreviousDisabled() {
        return this._index() === 0;
    }
    get _isNextDisabled() {
        return this._index() === this._cards().length - 1;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Carousel, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.4", type: Carousel, isStandalone: true, selector: "ngs-carousel", inputs: { fade: { classPropertyName: "fade", publicName: "fade", isSignal: true, isRequired: false, transformFunction: null }, snapToCenter: { classPropertyName: "snapToCenter", publicName: "snapToCenter", isSignal: true, isRequired: false, transformFunction: null }, snapDebounceTime: { classPropertyName: "snapDebounceTime", publicName: "snapDebounceTime", isSignal: true, isRequired: false, transformFunction: null }, snapDuration: { classPropertyName: "snapDuration", publicName: "snapDuration", isSignal: true, isRequired: false, transformFunction: null }, resistanceFactor: { classPropertyName: "resistanceFactor", publicName: "resistanceFactor", isSignal: true, isRequired: false, transformFunction: null }, velocityThreshold: { classPropertyName: "velocityThreshold", publicName: "velocityThreshold", isSignal: true, isRequired: false, transformFunction: null }, visibilityDebounceTime: { classPropertyName: "visibilityDebounceTime", publicName: "visibilityDebounceTime", isSignal: true, isRequired: false, transformFunction: null }, stopPropagation: { classPropertyName: "stopPropagation", publicName: "stopPropagation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexChange: "indexChange" }, host: { properties: { "class.fade": "fade()" }, classAttribute: "ngs-carousel" }, providers: [
            {
                provide: CAROUSEL,
                useExisting: Carousel
            }
        ], queries: [{ propertyName: "_cards", predicate: CAROUSEL_CARD, isSignal: true }], viewQueries: [{ propertyName: "_content", first: true, predicate: ["content"], descendants: true, isSignal: true }], exportAs: ["ngsCarousel"], ngImport: i0, template: "<div #content class=\"content\"\n     ngsDraggableCarousel\n     [stopPropagation]=\"stopPropagation()\"\n     [snapToCenter]=\"snapToCenter()\"\n     [snapDebounceTime]=\"snapDebounceTime()\"\n     [snapDuration]=\"snapDuration()\"\n     [resistanceFactor]=\"resistanceFactor()\"\n     [velocityThreshold]=\"velocityThreshold()\"\n     [visibilityDebounceTime]=\"visibilityDebounceTime()\"\n     (indexChange)=\"onIndexChanged($event)\">\n  <ng-content select=\"ngs-carousel-card,[ngs-carousel-card]\" />\n</div>\n<div class=\"controls\">\n  <ng-content select=\"[ngsCarouselControls]\" />\n</div>\n", styles: [":host{--ngs-carousel-gap: calc(var(--spacing, .25rem) * 8);display:block;position:relative}:host .content{display:flex;overflow:hidden;gap:var(--ngs-carousel-gap)}:host .controls{margin-top:calc(var(--spacing, .25rem) * 4);gap:calc(var(--spacing, .25rem) * 3)}:host .controls:empty{display:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: DraggableCarouselDirective, selector: "[ngsDraggableCarousel]", inputs: ["cardSelector", "snapToCenter", "snapDebounceTime", "snapDuration", "resistanceFactor", "velocityThreshold", "visibilityDebounceTime", "stopPropagation"], outputs: ["indexChange"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Carousel, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-carousel', exportAs: 'ngsCarousel', providers: [
                        {
                            provide: CAROUSEL,
                            useExisting: Carousel
                        }
                    ], hostDirectives: [], imports: [
                        DraggableCarouselDirective
                    ], host: {
                        'class': 'ngs-carousel',
                        '[class.fade]': 'fade()',
                    }, template: "<div #content class=\"content\"\n     ngsDraggableCarousel\n     [stopPropagation]=\"stopPropagation()\"\n     [snapToCenter]=\"snapToCenter()\"\n     [snapDebounceTime]=\"snapDebounceTime()\"\n     [snapDuration]=\"snapDuration()\"\n     [resistanceFactor]=\"resistanceFactor()\"\n     [velocityThreshold]=\"velocityThreshold()\"\n     [visibilityDebounceTime]=\"visibilityDebounceTime()\"\n     (indexChange)=\"onIndexChanged($event)\">\n  <ng-content select=\"ngs-carousel-card,[ngs-carousel-card]\" />\n</div>\n<div class=\"controls\">\n  <ng-content select=\"[ngsCarouselControls]\" />\n</div>\n", styles: [":host{--ngs-carousel-gap: calc(var(--spacing, .25rem) * 8);display:block;position:relative}:host .content{display:flex;overflow:hidden;gap:var(--ngs-carousel-gap)}:host .controls{margin-top:calc(var(--spacing, .25rem) * 4);gap:calc(var(--spacing, .25rem) * 3)}:host .controls:empty{display:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
        }], propDecorators: { _content: [{ type: i0.ViewChild, args: ['content', { isSignal: true }] }], _cards: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => CAROUSEL_CARD), { isSignal: true }] }], fade: [{ type: i0.Input, args: [{ isSignal: true, alias: "fade", required: false }] }], snapToCenter: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToCenter", required: false }] }], snapDebounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapDebounceTime", required: false }] }], snapDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapDuration", required: false }] }], resistanceFactor: [{ type: i0.Input, args: [{ isSignal: true, alias: "resistanceFactor", required: false }] }], velocityThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "velocityThreshold", required: false }] }], visibilityDebounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibilityDebounceTime", required: false }] }], stopPropagation: [{ type: i0.Input, args: [{ isSignal: true, alias: "stopPropagation", required: false }] }], indexChange: [{ type: i0.Output, args: ["indexChange"] }] } });

class CarouselCard {
    _elementRef = inject(ElementRef);
    get element() {
        return this._elementRef.nativeElement;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CarouselCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: CarouselCard, isStandalone: true, selector: "ngs-carousel-card,[ngs-carousel-card]", host: { classAttribute: "ngs-carousel-card" }, providers: [
            {
                provide: CAROUSEL_CARD,
                useExisting: CarouselCard
            }
        ], exportAs: ["ngsCarouselCard"], ngImport: i0, template: "<ng-content />\n", styles: [":host{display:block;scroll-padding-inline:100px;flex:none}:host-context(.ngs-carousel.fade){animation:ngs-carousel-fade;animation-fill-mode:both;animation-timing-function:linear;animation-timeline:view(inline)}@keyframes ngs-carousel-fade{0%,to{opacity:.3}50%{opacity:1}}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CarouselCard, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-carousel-card,[ngs-carousel-card]', exportAs: 'ngsCarouselCard', imports: [], providers: [
                        {
                            provide: CAROUSEL_CARD,
                            useExisting: CarouselCard
                        }
                    ], host: {
                        'class': 'ngs-carousel-card',
                    }, template: "<ng-content />\n", styles: [":host{display:block;scroll-padding-inline:100px;flex:none}:host-context(.ngs-carousel.fade){animation:ngs-carousel-fade;animation-fill-mode:both;animation-timing-function:linear;animation-timeline:view(inline)}@keyframes ngs-carousel-fade{0%,to{opacity:.3}50%{opacity:1}}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
        }] });

class CarouselControlsDirective {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CarouselControlsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: CarouselControlsDirective, isStandalone: true, selector: "[ngsCarouselControls]", host: { classAttribute: "ngs-carousel-controls" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CarouselControlsDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[ngsCarouselControls]',
                    standalone: true,
                    host: {
                        'class': 'ngs-carousel-controls',
                    }
                }]
        }] });

class CarouselPreviousDirective {
    _carousel = inject(CAROUSEL, {
        optional: true
    });
    carousel = input(null, ...(ngDevMode ? [{ debugName: "carousel" }] : /* istanbul ignore next */ []));
    ngOnInit() {
        if (this.carousel() && !this._carousel) {
            this._carousel = this.carousel();
        }
    }
    _handleClick() {
        this._carousel?.api.previous();
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CarouselPreviousDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.4", type: CarouselPreviousDirective, isStandalone: true, selector: "[ngsCarouselPrevious]", inputs: { carousel: { classPropertyName: "carousel", publicName: "carousel", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "_handleClick()" }, properties: { "attr.disabled": "_carousel?.api?.isPreviousDisabled() ? true : null" }, classAttribute: "ngs-carousel-previous" }, exportAs: ["ngsCarouselPrevious"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CarouselPreviousDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[ngsCarouselPrevious]',
                    exportAs: 'ngsCarouselPrevious',
                    standalone: true,
                    host: {
                        'class': 'ngs-carousel-previous',
                        '[attr.disabled]': '_carousel?.api?.isPreviousDisabled() ? true : null',
                        '(click)': '_handleClick()'
                    }
                }]
        }], propDecorators: { carousel: [{ type: i0.Input, args: [{ isSignal: true, alias: "carousel", required: false }] }] } });

class CarouselNextDirective {
    _carousel = inject(CAROUSEL, {
        optional: true
    });
    carousel = input(null, ...(ngDevMode ? [{ debugName: "carousel" }] : /* istanbul ignore next */ []));
    ngOnInit() {
        if (this.carousel() && !this._carousel) {
            this._carousel = this.carousel();
        }
    }
    _handleClick() {
        this._carousel?.api.next();
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CarouselNextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.4", type: CarouselNextDirective, isStandalone: true, selector: "[ngsCarouselNext]", inputs: { carousel: { classPropertyName: "carousel", publicName: "carousel", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "_handleClick()" }, properties: { "attr.disabled": "_carousel?.api?.isNextDisabled() ? true : null" }, classAttribute: "ngs-carousel-next" }, exportAs: ["ngsCarouselNext"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CarouselNextDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[ngsCarouselNext]',
                    exportAs: 'ngsCarouselNext',
                    standalone: true,
                    host: {
                        'class': 'ngs-carousel-next',
                        '[attr.disabled]': '_carousel?.api?.isNextDisabled() ? true : null',
                        '(click)': '_handleClick()'
                    }
                }]
        }], propDecorators: { carousel: [{ type: i0.Input, args: [{ isSignal: true, alias: "carousel", required: false }] }] } });

/**
 * Generated bundle index. Do not edit.
 */

export { CAROUSEL, CAROUSEL_CARD, Carousel, CarouselCard, CarouselControlsDirective, CarouselNextDirective, CarouselPreviousDirective };
//# sourceMappingURL=ngstarter-ui-components-carousel.mjs.map
