import * as i0 from '@angular/core';
import { InjectionToken, makeEnvironmentProviders, inject, NgZone, ElementRef, ChangeDetectorRef, Renderer2, signal, input, booleanAttribute, output, viewChildren, effect, ChangeDetectionStrategy, Component, Directive } from '@angular/core';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

function getPointFromEvent(event) {
    // TouchEvent
    if (event.changedTouches !== undefined &&
        event.changedTouches.length > 0) {
        return {
            x: event.changedTouches[0].clientX,
            y: event.changedTouches[0].clientY,
        };
    }
    // MouseEvent
    else if (event.clientX !== undefined &&
        event.clientY !== undefined) {
        return {
            x: event.clientX,
            y: event.clientY,
        };
    }
    return null;
}
function getElementPixelSize(elRef, direction) {
    const rect = elRef.nativeElement.getBoundingClientRect();
    return direction === 'horizontal' ? rect.width : rect.height;
}
function getInputPositiveNumber(v, defaultValue) {
    if (v === null || v === undefined) {
        return defaultValue;
    }
    v = Number(v);
    return !isNaN(v) && v >= 0 ? v : defaultValue;
}
function isUserSizesValid(unit, sizes) {
    // All sizes have to be not null and total should be 100
    if (unit === 'percent') {
        const total = sizes.reduce((_total, s) => (s !== null ? _total + s : _total), 0);
        return sizes.every(s => s !== null) && total && total > 99.9 && total < 100.1;
    }
    // A size at null is mandatory but only one.
    if (unit === 'pixel') {
        return sizes.filter(s => s === null).length === 1;
    }
}
function getAreaMinSize(a) {
    if (a.size === null) {
        return 0;
    }
    if (a.component.isLocked() === true) {
        return a.size;
    }
    if (a.component.getMinSize() === null) {
        return 0;
    }
    if (a.component.getMinSize() > a.size) {
        return a.size;
    }
    return a.component.getMinSize();
}
function getAreaMaxSize(a) {
    if (a.size === null) {
        return null;
    }
    if (a.component.isLocked() === true) {
        return a.size;
    }
    if (a.component.getMaxSize() === null) {
        return null;
    }
    if (a.component.getMaxSize() < a.size) {
        return a.size;
    }
    return a.component.getMaxSize();
}
function getGutterSideAbsorptionCapacity(unit, sideAreas, pixels, allAreasSizePixel) {
    return sideAreas.reduce((acc, area) => {
        const res = getAreaAbsorptionCapacity(unit, area, acc.remain, allAreasSizePixel);
        acc.list.push(res);
        acc.remain = res && res.pixelRemain;
        return acc;
    }, { remain: pixels, list: [] });
}
function getAreaAbsorptionCapacity(unit, areaSnapshot, pixels, allAreasSizePixel) {
    // No pain no gain
    if (pixels === 0) {
        return {
            areaSnapshot,
            pixelAbsorb: 0,
            percentAfterAbsorption: areaSnapshot.sizePercentAtStart,
            pixelRemain: 0,
        };
    }
    // Area start at zero and need to be reduced, not possible
    if (areaSnapshot.sizePixelAtStart === 0 && pixels < 0) {
        return {
            areaSnapshot,
            pixelAbsorb: 0,
            percentAfterAbsorption: 0,
            pixelRemain: pixels,
        };
    }
    if (unit === 'percent') {
        return getAreaAbsorptionCapacityPercent(areaSnapshot, pixels, allAreasSizePixel);
    }
    if (unit === 'pixel') {
        return getAreaAbsorptionCapacityPixel(areaSnapshot, pixels, allAreasSizePixel);
    }
}
function getAreaAbsorptionCapacityPercent(areaSnapshot, pixels, allAreasSizePixel) {
    const tempPixelSize = areaSnapshot.sizePixelAtStart + pixels;
    const tempPercentSize = (tempPixelSize / allAreasSizePixel) * 100;
    // ENLARGE AREA
    if (pixels > 0) {
        // If maxSize & newSize bigger than it > absorb to max and return remaining pixels
        if (areaSnapshot.area.maxSize !== null && tempPercentSize > areaSnapshot.area.maxSize) {
            // Use area.area.maxSize as newPercentSize and return calculate pixels remaining
            const maxSizePixel = (areaSnapshot.area.maxSize / 100) * allAreasSizePixel;
            return {
                areaSnapshot,
                pixelAbsorb: maxSizePixel,
                percentAfterAbsorption: areaSnapshot.area.maxSize,
                pixelRemain: areaSnapshot.sizePixelAtStart + pixels - maxSizePixel,
            };
        }
        return {
            areaSnapshot,
            pixelAbsorb: pixels,
            percentAfterAbsorption: tempPercentSize > 100 ? 100 : tempPercentSize,
            pixelRemain: 0,
        };
    }
    // REDUCE AREA
    else if (pixels < 0) {
        // If minSize & newSize smaller than it > absorb to min and return remaining pixels
        if (areaSnapshot.area.minSize !== null && tempPercentSize < areaSnapshot.area.minSize) {
            // Use area.area.minSize as newPercentSize and return calculate pixels remaining
            const minSizePixel = (areaSnapshot.area.minSize / 100) * allAreasSizePixel;
            return {
                areaSnapshot,
                pixelAbsorb: minSizePixel,
                percentAfterAbsorption: areaSnapshot.area.minSize,
                pixelRemain: areaSnapshot.sizePixelAtStart + pixels - minSizePixel,
            };
        }
        // If reduced under zero > return remaining pixels
        else if (tempPercentSize < 0) {
            // Use 0 as newPercentSize and return calculate pixels remaining
            return {
                areaSnapshot,
                pixelAbsorb: -areaSnapshot.sizePixelAtStart,
                percentAfterAbsorption: 0,
                pixelRemain: pixels + areaSnapshot.sizePixelAtStart,
            };
        }
        return {
            areaSnapshot,
            pixelAbsorb: pixels,
            percentAfterAbsorption: tempPercentSize,
            pixelRemain: 0,
        };
    }
}
function getAreaAbsorptionCapacityPixel(areaSnapshot, pixels, containerSizePixel) {
    const tempPixelSize = areaSnapshot.sizePixelAtStart + pixels;
    // ENLARGE AREA
    if (pixels > 0) {
        // If maxSize & newSize bigger than it > absorb to max and return remaining pixels
        if (areaSnapshot.area.maxSize !== null && tempPixelSize > areaSnapshot.area.maxSize) {
            return {
                areaSnapshot,
                pixelAbsorb: areaSnapshot.area.maxSize - areaSnapshot.sizePixelAtStart,
                percentAfterAbsorption: -1,
                pixelRemain: tempPixelSize - areaSnapshot.area.maxSize,
            };
        }
        return {
            areaSnapshot,
            pixelAbsorb: pixels,
            percentAfterAbsorption: -1,
            pixelRemain: 0,
        };
    }
    // REDUCE AREA
    else if (pixels < 0) {
        // If minSize & newSize smaller than it > absorb to min and return remaining pixels
        if (areaSnapshot.area.minSize !== null && tempPixelSize < areaSnapshot.area.minSize) {
            return {
                areaSnapshot,
                pixelAbsorb: areaSnapshot.area.minSize + pixels - tempPixelSize,
                percentAfterAbsorption: -1,
                pixelRemain: tempPixelSize - areaSnapshot.area.minSize,
            };
        }
        // If reduced under zero > return remaining pixels
        else if (tempPixelSize < 0) {
            return {
                areaSnapshot,
                pixelAbsorb: -areaSnapshot.sizePixelAtStart,
                percentAfterAbsorption: -1,
                pixelRemain: pixels + areaSnapshot.sizePixelAtStart,
            };
        }
        return {
            areaSnapshot,
            pixelAbsorb: pixels,
            percentAfterAbsorption: -1,
            pixelRemain: 0,
        };
    }
}
function updateAreaSize(unit, item) {
    if (unit === 'percent') {
        item.areaSnapshot.area.component.setSize(item.percentAfterAbsorption);
    }
    else if (unit === 'pixel') {
        // Update size except for the wildcard size area
        if (item.areaSnapshot.area.size !== null) {
            item.areaSnapshot.area.component.setSize(item.areaSnapshot.sizePixelAtStart + item.pixelAbsorb);
        }
    }
}

/** Injection token that can be used to specify default split options. */
const SPLIT_DEFAULT_OPTIONS = new InjectionToken('SPLIT_DEFAULT_OPTIONS');
/**
 * Configures the default options for the split component.
 * @param options The default options to use.
 * @returns The environment providers.
 */
function provideSplit(options) {
    return makeEnvironmentProviders([
        { provide: SPLIT_DEFAULT_OPTIONS, useValue: options },
    ]);
}
class Split {
    shouldShowHandle(gutterIndex) {
        // show if either adjacent pane has withHandle=true
        const left = this.displayedAreas[gutterIndex]?.component;
        const right = this.displayedAreas[gutterIndex + 1]?.component;
        return !!(left?.hasHandle() || right?.hasHandle());
    }
    ngZone = inject(NgZone);
    elRef = inject(ElementRef);
    cdRef = inject(ChangeDetectorRef);
    renderer = inject(Renderer2);
    isInit = signal(false, ...(ngDevMode ? [{ debugName: "isInit" }] : /* istanbul ignore next */ []));
    _defaultOptions = inject(SPLIT_DEFAULT_OPTIONS, {
        optional: true,
    });
    /** The split direction. */
    direction = input(this._defaultOptions?.direction ?? 'horizontal', ...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
    /** The unit you want to specify area sizes. */
    unit = input(this._defaultOptions?.unit ?? 'percent', ...(ngDevMode ? [{ debugName: "unit" }] : /* istanbul ignore next */ []));
    /** Gutters's size (dragging elements) in pixels. */
    gutterSize = input(this._defaultOptions?.gutterSize ?? 5, { ...(ngDevMode ? { debugName: "gutterSize" } : /* istanbul ignore next */ {}), transform: (v) => getInputPositiveNumber(v, 4) });
    /** Gutter step while moving in pixels. */
    gutterStep = input(this._defaultOptions?.gutterStep ?? 1, { ...(ngDevMode ? { debugName: "gutterStep" } : /* istanbul ignore next */ {}), transform: (v) => getInputPositiveNumber(v, 1) });
    /** Set to true if you want to limit gutter move to adjacent areas only. */
    restrictMove = input(this._defaultOptions?.restrictMove ?? false, { ...(ngDevMode ? { debugName: "restrictMove" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    /** Add transition when toggling visibility using `visible` or `size` changes. */
    useTransition = input(this._defaultOptions?.useTransition ?? false, { ...(ngDevMode ? { debugName: "useTransition" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    /**
     * Disable the dragging feature (remove cursor/image on gutters).
     * `gutterClick`/`gutterDblClick` still emits.
     */
    disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    /** Indicates the directionality of the areas. */
    dir = input(this._defaultOptions?.dir ?? 'ltr', ...(ngDevMode ? [{ debugName: "dir" }] : /* istanbul ignore next */ []));
    /**
     * Milliseconds to detect a double click on a gutter. Set it around 300-500ms if
     * you want to use `gutterDblClick` event.
     */
    gutterDblClickDuration = input(this._defaultOptions?.gutterDblClickDuration ?? 0, { ...(ngDevMode ? { debugName: "gutterDblClickDuration" } : /* istanbul ignore next */ {}), transform: (v) => getInputPositiveNumber(v, 0) });
    /** Event emitted when drag starts. */
    dragStart = output();
    /** Event emitted when drag ends. */
    dragEnd = output();
    /** Event emitted when user clicks on a gutter. */
    gutterClick = output();
    /** Event emitted when user double clicks on a gutter. */
    gutterDblClick = output();
    /** Event emitted when transition ends (debounced). */
    transitionEnd = output();
    transitionEndSubject = new Subject();
    dragProgressSubject = new Subject();
    dragProgress$ = this.dragProgressSubject.asObservable();
    isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
    dragListeners = [];
    snapshot = null;
    startPoint = null;
    endPoint = null;
    displayedAreas = [];
    hidedAreas = [];
    gutterEls = viewChildren('gutterEls', ...(ngDevMode ? [{ debugName: "gutterEls" }] : /* istanbul ignore next */ []));
    isDraggingSignal = this.isDragging.asReadonly();
    isDraggingPublic = this.isDragging.asReadonly();
    isInitSignal = this.isInit.asReadonly();
    constructor() {
        // Debounce transitionEnd output
        this.transitionEndSubject.pipe(debounceTime(20)).subscribe(sizes => {
            this.transitionEnd.emit(sizes);
        });
        effect(() => {
            this.direction();
            this.cdRef.markForCheck();
            this.build(false, false);
        });
        effect(() => {
            this.unit();
            this.cdRef.markForCheck();
            this.build(false, true);
        });
        effect(() => {
            this.gutterSize();
            this.build(false, false);
        });
        effect(() => {
            this.useTransition();
            this.cdRef.markForCheck();
        });
        effect(() => {
            this.disabled();
            this.cdRef.markForCheck();
        });
        effect(() => {
            this.renderer.setAttribute(this.elRef.nativeElement, 'dir', this.dir());
        });
    }
    ngAfterViewInit() {
        this.ngZone.runOutsideAngular(() => {
            // To avoid transition at first rendering
            setTimeout(() => {
                this.isInit.set(true);
                this.cdRef.markForCheck();
            });
        });
    }
    getNbGutters() {
        return this.displayedAreas.length === 0 ? 0 : this.displayedAreas.length - 1;
    }
    addArea(component) {
        const newArea = {
            component,
            order: 0,
            size: 0,
            minSize: null,
            maxSize: null,
        };
        if (component.isVisible() === true) {
            this.displayedAreas.push(newArea);
            this.build(true, true);
        }
        else {
            this.hidedAreas.push(newArea);
        }
    }
    removeArea(component) {
        if (this.displayedAreas.some(a => a.component === component)) {
            const area = this.displayedAreas.find(a => a.component === component);
            this.displayedAreas.splice(this.displayedAreas.indexOf(area), 1);
            this.build(true, true);
        }
        else if (this.hidedAreas.some(a => a.component === component)) {
            const area = this.hidedAreas.find(a => a.component === component);
            this.hidedAreas.splice(this.hidedAreas.indexOf(area), 1);
        }
    }
    updateArea(component, resetOrders, resetSizes) {
        if (component.isVisible() === true) {
            this.build(resetOrders, resetSizes);
        }
    }
    updateAreaInternal(component) {
        const area = this.displayedAreas.find(a => a.component === component);
        if (area) {
            area.size = component.getSize();
        }
    }
    showArea(component) {
        const area = this.hidedAreas.find(a => a.component === component);
        if (area === undefined) {
            return;
        }
        const areas = this.hidedAreas.splice(this.hidedAreas.indexOf(area), 1);
        this.displayedAreas.push(...areas);
        this.build(true, true);
    }
    hideArea(comp) {
        const area = this.displayedAreas.find(a => a.component === comp);
        if (area === undefined) {
            return;
        }
        const areas = this.displayedAreas.splice(this.displayedAreas.indexOf(area), 1);
        areas.forEach(_area => {
            _area.order = 0;
            _area.size = 0;
        });
        this.hidedAreas.push(...areas);
        this.build(true, true);
    }
    getVisibleAreaSizes() {
        return this.displayedAreas.map(a => (a.size === null ? '*' : a.size));
    }
    setVisibleAreaSizes(sizes) {
        if (sizes.length !== this.displayedAreas.length) {
            return false;
        }
        const formatedSizes = sizes.map(s => getInputPositiveNumber(s, null));
        const isValid = isUserSizesValid(this.unit(), formatedSizes);
        if (isValid === false) {
            return false;
        }
        this.displayedAreas.forEach((area, i) => area.component.setSize(formatedSizes[i]));
        this.build(false, true);
        return true;
    }
    build(resetOrders, resetSizes) {
        // ¤ AREAS ORDER
        if (resetOrders === true) {
            // If user provided 'order' for each area, use it to sort them.
            if (this.displayedAreas.every(a => a.component.getOrder() !== null)) {
                this.displayedAreas.sort((a, b) => a.component.getOrder() - b.component.getOrder());
            }
            // Then set real order with multiples of 2, numbers between will be used by gutters.
            this.displayedAreas.forEach((area, i) => {
                area.order = i * 2;
                area.component.setStyleOrder(area.order);
            });
        }
        // ¤ AREAS SIZE
        if (resetSizes === true) {
            const useUserSizes = isUserSizesValid(this.unit(), this.displayedAreas.map(a => a.component.getSize()));
            switch (this.unit()) {
                case 'percent': {
                    const defaultSize = 100 / this.displayedAreas.length;
                    this.displayedAreas.forEach(area => {
                        area.size = useUserSizes ? area.component.getSize() : defaultSize;
                        area.minSize = getAreaMinSize(area);
                        area.maxSize = getAreaMaxSize(area);
                    });
                    break;
                }
                case 'pixel': {
                    if (useUserSizes) {
                        this.displayedAreas.forEach(area => {
                            area.size = area.component.getSize();
                            area.minSize = getAreaMinSize(area);
                            area.maxSize = getAreaMaxSize(area);
                        });
                    }
                    else {
                        const wildcardSizeAreas = this.displayedAreas.filter(a => a.component.getSize() === null);
                        // No wildcard area > Need to select one arbitrarily > first
                        if (wildcardSizeAreas.length === 0 && this.displayedAreas.length > 0) {
                            this.displayedAreas.forEach((area, i) => {
                                area.size = i === 0 ? null : area.component.getSize();
                                area.minSize = i === 0 ? null : getAreaMinSize(area);
                                area.maxSize = i === 0 ? null : getAreaMaxSize(area);
                            });
                        }
                        // More than one wildcard area > Need to keep only one arbitrarly > first
                        else if (wildcardSizeAreas.length > 1) {
                            let alreadyGotOne = false;
                            this.displayedAreas.forEach(area => {
                                if (area.component.getSize() === null) {
                                    if (alreadyGotOne === false) {
                                        area.size = null;
                                        area.minSize = null;
                                        area.maxSize = null;
                                        alreadyGotOne = true;
                                    }
                                    else {
                                        area.size = 100;
                                        area.minSize = null;
                                        area.maxSize = null;
                                    }
                                }
                                else {
                                    area.size = area.component.getSize();
                                    area.minSize = getAreaMinSize(area);
                                    area.maxSize = getAreaMaxSize(area);
                                }
                            });
                        }
                    }
                    break;
                }
            }
        }
        this.refreshStyleSizes();
        this.cdRef.markForCheck();
    }
    refreshStyleSizes() {
        ///////////////////////////////////////////
        // PERCENT MODE
        if (this.unit() === 'percent') {
            // Only one area > flex-basis 100%
            if (this.displayedAreas.length === 1) {
                this.displayedAreas[0].component.setStyleFlex(0, 0, `100%`, false, false);
            }
            // Multiple areas > use each percent basis
            else {
                const sumGutterSize = this.getNbGutters() * this.gutterSize();
                this.displayedAreas.forEach(area => {
                    area.component.setStyleFlex(0, 0, `calc( ${area.size}% - ${(area.size / 100) * sumGutterSize}px )`, area.minSize !== null && area.minSize === area.size ? true : false, area.maxSize !== null && area.maxSize === area.size ? true : false);
                });
            }
        }
        ///////////////////////////////////////////
        // PIXEL MODE
        else if (this.unit() === 'pixel') {
            this.displayedAreas.forEach(area => {
                // Area with wildcard size
                if (area.size === null) {
                    if (this.displayedAreas.length === 1) {
                        area.component.setStyleFlex(1, 1, `100%`, false, false);
                    }
                    else {
                        area.component.setStyleFlex(1, 1, `auto`, false, false);
                    }
                }
                // Area with pixel size
                else {
                    // Only one area > flex-basis 100%
                    if (this.displayedAreas.length === 1) {
                        area.component.setStyleFlex(0, 0, `100%`, false, false);
                    }
                    // Multiple areas > use each pixel basis
                    else {
                        area.component.setStyleFlex(0, 0, `${area.size}px`, area.minSize !== null && area.minSize === area.size ? true : false, area.maxSize !== null && area.maxSize === area.size ? true : false);
                    }
                }
            });
        }
    }
    _clickTimeout = null;
    clickGutter(event, gutterNum) {
        const tempPoint = getPointFromEvent(event);
        // Be sure mouseup/touchend happened at same point as mousedown/touchstart to trigger click/dblclick
        if (this.startPoint && this.startPoint.x === tempPoint.x && this.startPoint.y === tempPoint.y) {
            // If timeout in progress and new click > clearTimeout & dblClickEvent
            if (this._clickTimeout !== null) {
                window.clearTimeout(this._clickTimeout);
                this._clickTimeout = null;
                this.notify('dblclick', gutterNum);
                this.stopDragging();
            }
            // Else start timeout to call clickEvent at end
            else {
                this._clickTimeout = window.setTimeout(() => {
                    this._clickTimeout = null;
                    this.notify('click', gutterNum);
                    this.stopDragging();
                }, this.gutterDblClickDuration());
            }
        }
    }
    startDragging(event, gutterOrder, gutterNum) {
        if (event.cancelable) {
            event.preventDefault();
        }
        event.stopPropagation();
        this.startPoint = getPointFromEvent(event);
        if (this.startPoint === null || this.disabled() === true) {
            return;
        }
        this.isDragging.set(true);
        this.cdRef.markForCheck();
        this.snapshot = {
            gutterNum,
            lastSteppedOffset: 0,
            allAreasSizePixel: getElementPixelSize(this.elRef, this.direction()) - this.getNbGutters() * this.gutterSize(),
            allInvolvedAreasSizePercent: 100,
            areasBeforeGutter: [],
            areasAfterGutter: [],
        };
        this.displayedAreas.forEach(area => {
            const areaSnapshot = {
                area,
                sizePixelAtStart: getElementPixelSize(area.component.elRef, this.direction()),
                sizePercentAtStart: (this.unit() === 'percent' ? area.size : -1), // If pixel mode, anyway, will not be used.
            };
            if (area.order < gutterOrder) {
                if (this.restrictMove() === true) {
                    this.snapshot.areasBeforeGutter = [areaSnapshot];
                }
                else {
                    this.snapshot.areasBeforeGutter.unshift(areaSnapshot);
                }
            }
            else if (area.order > gutterOrder) {
                if (this.restrictMove() === true) {
                    if (this.snapshot.areasAfterGutter.length === 0) {
                        this.snapshot.areasAfterGutter = [areaSnapshot];
                    }
                }
                else {
                    this.snapshot.areasAfterGutter.push(areaSnapshot);
                }
            }
        });
        this.snapshot.allInvolvedAreasSizePercent = [
            ...this.snapshot.areasBeforeGutter,
            ...this.snapshot.areasAfterGutter,
        ].reduce((t, a) => t + (a.sizePercentAtStart > 0 ? a.sizePercentAtStart : 0), 0);
        if (this.snapshot.areasBeforeGutter.length === 0 ||
            this.snapshot.areasAfterGutter.length === 0) {
            return;
        }
        this.dragListeners.push(this.renderer.listen('document', 'mouseup', this.stopDragging.bind(this)));
        this.dragListeners.push(this.renderer.listen('document', 'touchend', this.stopDragging.bind(this)));
        this.dragListeners.push(this.renderer.listen('document', 'touchcancel', this.stopDragging.bind(this)));
        this.ngZone.runOutsideAngular(() => {
            this.dragListeners.push(this.renderer.listen('document', 'mousemove', this.dragEvent.bind(this)));
            this.dragListeners.push(this.renderer.listen('document', 'touchmove', this.dragEvent.bind(this)));
        });
        this.displayedAreas.forEach(area => area.component.lockEvents());
        this.isDragging.set(true);
        this.renderer.addClass(this.elRef.nativeElement, 'ngs-dragging');
        this.renderer.addClass(this.gutterEls()[this.snapshot.gutterNum - 1].nativeElement, 'ngs-dragged');
        this.notify('start', this.snapshot.gutterNum);
    }
    dragEvent(event) {
        if (event.cancelable) {
            event.preventDefault();
        }
        event.stopPropagation();
        if (this._clickTimeout !== null) {
            window.clearTimeout(this._clickTimeout);
            this._clickTimeout = null;
        }
        if (this.isDragging() === false) {
            return;
        }
        this.endPoint = getPointFromEvent(event);
        if (this.endPoint === null) {
            return;
        }
        // Calculate steppedOffset
        let offset = this.direction() === 'horizontal'
            ? this.startPoint.x - this.endPoint.x
            : this.startPoint.y - this.endPoint.y;
        if (this.dir() === 'rtl' && this.direction() === 'horizontal') {
            offset = -offset;
        }
        const steppedOffset = Math.round(offset / this.gutterStep()) * this.gutterStep();
        if (steppedOffset === this.snapshot.lastSteppedOffset) {
            return;
        }
        this.snapshot.lastSteppedOffset = steppedOffset;
        // Need to know if each gutter side areas could reacts to steppedOffset
        let areasBefore = getGutterSideAbsorptionCapacity(this.unit(), this.snapshot.areasBeforeGutter, -steppedOffset, this.snapshot.allAreasSizePixel);
        let areasAfter = getGutterSideAbsorptionCapacity(this.unit(), this.snapshot.areasAfterGutter, steppedOffset, this.snapshot.allAreasSizePixel);
        // Each gutter side areas can't absorb all offset
        if (areasBefore.remain !== 0 && areasAfter.remain !== 0) {
            if (Math.abs(areasBefore.remain) === Math.abs(areasAfter.remain)) {
                /** */
            }
            else if (Math.abs(areasBefore.remain) > Math.abs(areasAfter.remain)) {
                areasAfter = getGutterSideAbsorptionCapacity(this.unit(), this.snapshot.areasAfterGutter, steppedOffset + areasBefore.remain, this.snapshot.allAreasSizePixel);
            }
            else {
                areasBefore = getGutterSideAbsorptionCapacity(this.unit(), this.snapshot.areasBeforeGutter, -(steppedOffset - areasAfter.remain), this.snapshot.allAreasSizePixel);
            }
        }
        // Areas before gutter can't absorbs all offset > need to recalculate sizes for areas after gutter.
        else if (areasBefore.remain !== 0) {
            areasAfter = getGutterSideAbsorptionCapacity(this.unit(), this.snapshot.areasAfterGutter, steppedOffset + areasBefore.remain, this.snapshot.allAreasSizePixel);
        }
        // Areas after gutter can't absorbs all offset > need to recalculate sizes for areas before gutter.
        else if (areasAfter.remain !== 0) {
            areasBefore = getGutterSideAbsorptionCapacity(this.unit(), this.snapshot.areasBeforeGutter, -(steppedOffset - areasAfter.remain), this.snapshot.allAreasSizePixel);
        }
        if (this.unit() === 'percent') {
            // Hack because of browser messing up with sizes using calc(X% - Ypx) -> el.getBoundingClientRect()
            // If not there, playing with gutters makes total going down to 99.99875% then 99.99286%, 99.98986%,..
            const all = [...areasBefore.list, ...areasAfter.list];
            const areaToReset = all.find(a => a.percentAfterAbsorption !== 0 &&
                a.percentAfterAbsorption !== a.areaSnapshot.area.minSize &&
                a.percentAfterAbsorption !== a.areaSnapshot.area.maxSize);
            if (areaToReset) {
                areaToReset.percentAfterAbsorption =
                    this.snapshot.allInvolvedAreasSizePercent -
                        all
                            .filter(a => a !== areaToReset)
                            .reduce((total, a) => total + a.percentAfterAbsorption, 0);
            }
        }
        // Now we know areas could absorb steppedOffset, time to really update sizes
        areasBefore.list.forEach(item => updateAreaSize(this.unit(), item));
        areasAfter.list.forEach(item => updateAreaSize(this.unit(), item));
        this.refreshStyleSizes();
        this.notify('progress', this.snapshot.gutterNum);
    }
    stopDragging(event) {
        if (event && event.cancelable) {
            event.preventDefault();
            event.stopPropagation();
        }
        if (this.isDragging() === false) {
            return;
        }
        this.displayedAreas.forEach(area => area.component.unlockEvents());
        while (this.dragListeners.length > 0) {
            const fct = this.dragListeners.pop();
            if (fct) {
                fct();
            }
        }
        // Warning: Have to be before "notify('end')"
        // because "notify('end')"" can be linked to "[size]='x'" > "build()" > "stopDragging()"
        this.isDragging.set(false);
        this.cdRef.markForCheck();
        // If moved from starting point, notify end
        if (this.endPoint &&
            (this.startPoint.x !== this.endPoint.x ||
                this.startPoint.y !== this.endPoint.y)) {
            this.notify('end', this.snapshot.gutterNum);
        }
        this.renderer.removeClass(this.elRef.nativeElement, 'ngs-dragging');
        this.renderer.removeClass(this.gutterEls()[this.snapshot.gutterNum - 1].nativeElement, 'ngs-dragged');
        this.snapshot = null;
        // Needed to let (click)="clickGutter(...)" event run and verify if mouse moved or not
        this.ngZone.runOutsideAngular(() => {
            setTimeout(() => {
                this.startPoint = null;
                this.endPoint = null;
            });
        });
    }
    notify(type, gutterNum) {
        const sizes = this.getVisibleAreaSizes();
        if (type === 'start') {
            this.dragStart.emit({ gutterNum, sizes });
        }
        else if (type === 'end') {
            this.dragEnd.emit({ gutterNum, sizes });
        }
        else if (type === 'click') {
            this.gutterClick.emit({ gutterNum, sizes });
        }
        else if (type === 'dblclick') {
            this.gutterDblClick.emit({ gutterNum, sizes });
        }
        else if (type === 'transitionEnd') {
            this.ngZone.run(() => this.transitionEndSubject.next(sizes));
        }
        else if (type === 'progress') {
            // Stay outside zone to allow users do what they want about change detection mechanism.
            this.dragProgressSubject.next({ gutterNum, sizes });
        }
    }
    ngOnDestroy() {
        this.stopDragging();
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Split, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: Split, isStandalone: true, selector: "ngs-split", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, gutterSize: { classPropertyName: "gutterSize", publicName: "gutterSize", isSignal: true, isRequired: false, transformFunction: null }, gutterStep: { classPropertyName: "gutterStep", publicName: "gutterStep", isSignal: true, isRequired: false, transformFunction: null }, restrictMove: { classPropertyName: "restrictMove", publicName: "restrictMove", isSignal: true, isRequired: false, transformFunction: null }, useTransition: { classPropertyName: "useTransition", publicName: "useTransition", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, dir: { classPropertyName: "dir", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, gutterDblClickDuration: { classPropertyName: "gutterDblClickDuration", publicName: "gutterDblClickDuration", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragStart: "dragStart", dragEnd: "dragEnd", gutterClick: "gutterClick", gutterDblClick: "gutterDblClick", transitionEnd: "transitionEnd" }, host: { properties: { "class.ngs-split-horizontal": "direction() === \"horizontal\"", "class.ngs-split-vertical": "direction() === \"vertical\"", "class.ngs-split-percent": "unit() === \"percent\"", "class.ngs-split-pixel": "unit() === \"pixel\"", "class.ngs-split-disabled": "disabled()", "class.ngs-split-transition": "useTransition()", "class.ngs-dragging": "isDraggingSignal()", "class.ngs-split-init": "isInitSignal()" }, classAttribute: "ngs-split" }, viewQueries: [{ propertyName: "gutterEls", predicate: ["gutterEls"], descendants: true, isSignal: true }], exportAs: ["ngsSplit"], ngImport: i0, template: "<ng-content/>\n@for (area of displayedAreas; track area; let index = $index; let last = $last) {\n  @if (!last) {\n    <div\n      #gutterEls\n      class=\"ngs-split-gutter\"\n      [style.flex-basis.px]=\"gutterSize()\"\n      [style.order]=\"index * 2 + 1\"\n      (mousedown)=\"startDragging($event, index * 2 + 1, index + 1)\"\n      (touchstart)=\"startDragging($event, index * 2 + 1, index + 1)\"\n      (mouseup)=\"clickGutter($event, index + 1)\"\n      (touchend)=\"clickGutter($event, index + 1)\"\n    >\n      <div class=\"ngs-split-gutter-handle\" [class.has-dots]=\"shouldShowHandle(index)\">\n        @if (shouldShowHandle(index)) {\n          <div class=\"ngs-split-gutter-dot\"></div>\n          <div class=\"ngs-split-gutter-dot\"></div>\n          <div class=\"ngs-split-gutter-dot\"></div>\n        }\n      </div>\n    </div>\n  }\n}\n", styles: [":host{--ngs-split-gutter-size: 5px;--ngs-split-handle-size: 10px;--ngs-split-handle-offset: calc((var(--ngs-split-handle-size) - var(--ngs-split-gutter-size)) * .5);--ngs-split-gutter-bg: var(--ngs-color-surface-container-high);--ngs-split-gutter-hover-bg: var(--ngs-color-primary);display:flex;flex-wrap:nowrap;justify-content:flex-start;align-items:stretch;overflow:hidden;width:100%;height:100%}:host ::ng-deep>.ngs-split-gutter{position:relative;display:flex;flex-grow:0;flex-shrink:0;align-items:center;justify-content:center;background-color:transparent;z-index:10}:host ::ng-deep>.ngs-split-gutter:before{content:\"\";position:absolute;background-color:var(--ngs-split-gutter-bg);transition:background-color .2s}:host ::ng-deep>.ngs-split-gutter:hover:before{background-color:var(--ngs-split-gutter-hover-bg)}:host ::ng-deep>.ngs-split-gutter>.ngs-split-gutter-handle{position:absolute;opacity:0;display:flex;align-items:center;justify-content:center}:host ::ng-deep>.ngs-split-gutter>.ngs-split-gutter-handle.has-dots{opacity:1}:host ::ng-deep>.ngs-split-gutter>.ngs-split-gutter-handle .ngs-split-gutter-dot{width:2px;height:2px;border-radius:50%;background-color:var(--ngs-color-on-surface)}:host ::ng-deep>.ngs-split-pane{display:flex;flex-direction:column;flex-grow:0;flex-shrink:0;min-width:0;min-height:0;overflow:hidden auto}:host ::ng-deep>.ngs-split-pane.ngs-dragging{-webkit-user-select:none;user-select:none}:host ::ng-deep>.ngs-split-pane>*{flex-shrink:0}:host ::ng-deep>.ngs-split-pane.ngs-split-pane-hidden{flex:0 1 0!important;overflow:hidden}:host.ngs-split-horizontal{flex-direction:row}:host.ngs-split-horizontal.ngs-dragging{cursor:col-resize}:host.ngs-split-horizontal ::ng-deep>.ngs-split-gutter{flex-direction:row;height:100%;width:var(--ngs-split-gutter-size);cursor:col-resize}:host.ngs-split-horizontal ::ng-deep>.ngs-split-gutter:before{width:100%;height:100%;top:0;left:0}:host.ngs-split-horizontal ::ng-deep>.ngs-split-gutter>.ngs-split-gutter-handle{width:var(--ngs-split-handle-size);height:100%;left:calc(-1 * var(--ngs-split-handle-offset));flex-direction:column;gap:2px}:host.ngs-split-horizontal ::ng-deep>.ngs-split-pane{height:100%;min-height:0}:host.ngs-split-vertical{flex-direction:column}:host.ngs-split-vertical.ngs-dragging{cursor:row-resize}:host.ngs-split-vertical ::ng-deep>.ngs-split-gutter{flex-direction:column;width:100%;height:var(--ngs-split-gutter-size);cursor:row-resize}:host.ngs-split-vertical ::ng-deep>.ngs-split-gutter:before{width:100%;height:100%;top:0;left:0}:host.ngs-split-vertical ::ng-deep>.ngs-split-gutter>.ngs-split-gutter-handle{width:100%;height:var(--ngs-split-handle-size);top:calc(-1 * var(--ngs-split-handle-offset));flex-direction:row;gap:3px}:host.ngs-split-vertical ::ng-deep>.ngs-split-pane{width:100%;min-width:0}:host.ngs-split-vertical ::ng-deep>.ngs-split-pane.ngs-split-pane-hidden{max-width:0}:host.ngs-split-disabled ::ng-deep>.ngs-split-gutter{cursor:default}:host.ngs-split-disabled ::ng-deep>.ngs-split-gutter .ngs-split-gutter-handle{background-image:none}:host.ngs-split-transition.ngs-split-init:not(.ngs-dragging) ::ng-deep>.ngs-split-gutter,:host.ngs-split-transition.ngs-split-init:not(.ngs-dragging) ::ng-deep>.ngs-split-pane{transition:flex-basis .3s}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Split, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-split', exportAs: 'ngsSplit', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
                        class: 'ngs-split',
                        '[class.ngs-split-horizontal]': 'direction() === "horizontal"',
                        '[class.ngs-split-vertical]': 'direction() === "vertical"',
                        '[class.ngs-split-percent]': 'unit() === "percent"',
                        '[class.ngs-split-pixel]': 'unit() === "pixel"',
                        '[class.ngs-split-disabled]': 'disabled()',
                        '[class.ngs-split-transition]': 'useTransition()',
                        '[class.ngs-dragging]': 'isDraggingSignal()',
                        '[class.ngs-split-init]': 'isInitSignal()',
                    }, template: "<ng-content/>\n@for (area of displayedAreas; track area; let index = $index; let last = $last) {\n  @if (!last) {\n    <div\n      #gutterEls\n      class=\"ngs-split-gutter\"\n      [style.flex-basis.px]=\"gutterSize()\"\n      [style.order]=\"index * 2 + 1\"\n      (mousedown)=\"startDragging($event, index * 2 + 1, index + 1)\"\n      (touchstart)=\"startDragging($event, index * 2 + 1, index + 1)\"\n      (mouseup)=\"clickGutter($event, index + 1)\"\n      (touchend)=\"clickGutter($event, index + 1)\"\n    >\n      <div class=\"ngs-split-gutter-handle\" [class.has-dots]=\"shouldShowHandle(index)\">\n        @if (shouldShowHandle(index)) {\n          <div class=\"ngs-split-gutter-dot\"></div>\n          <div class=\"ngs-split-gutter-dot\"></div>\n          <div class=\"ngs-split-gutter-dot\"></div>\n        }\n      </div>\n    </div>\n  }\n}\n", styles: [":host{--ngs-split-gutter-size: 5px;--ngs-split-handle-size: 10px;--ngs-split-handle-offset: calc((var(--ngs-split-handle-size) - var(--ngs-split-gutter-size)) * .5);--ngs-split-gutter-bg: var(--ngs-color-surface-container-high);--ngs-split-gutter-hover-bg: var(--ngs-color-primary);display:flex;flex-wrap:nowrap;justify-content:flex-start;align-items:stretch;overflow:hidden;width:100%;height:100%}:host ::ng-deep>.ngs-split-gutter{position:relative;display:flex;flex-grow:0;flex-shrink:0;align-items:center;justify-content:center;background-color:transparent;z-index:10}:host ::ng-deep>.ngs-split-gutter:before{content:\"\";position:absolute;background-color:var(--ngs-split-gutter-bg);transition:background-color .2s}:host ::ng-deep>.ngs-split-gutter:hover:before{background-color:var(--ngs-split-gutter-hover-bg)}:host ::ng-deep>.ngs-split-gutter>.ngs-split-gutter-handle{position:absolute;opacity:0;display:flex;align-items:center;justify-content:center}:host ::ng-deep>.ngs-split-gutter>.ngs-split-gutter-handle.has-dots{opacity:1}:host ::ng-deep>.ngs-split-gutter>.ngs-split-gutter-handle .ngs-split-gutter-dot{width:2px;height:2px;border-radius:50%;background-color:var(--ngs-color-on-surface)}:host ::ng-deep>.ngs-split-pane{display:flex;flex-direction:column;flex-grow:0;flex-shrink:0;min-width:0;min-height:0;overflow:hidden auto}:host ::ng-deep>.ngs-split-pane.ngs-dragging{-webkit-user-select:none;user-select:none}:host ::ng-deep>.ngs-split-pane>*{flex-shrink:0}:host ::ng-deep>.ngs-split-pane.ngs-split-pane-hidden{flex:0 1 0!important;overflow:hidden}:host.ngs-split-horizontal{flex-direction:row}:host.ngs-split-horizontal.ngs-dragging{cursor:col-resize}:host.ngs-split-horizontal ::ng-deep>.ngs-split-gutter{flex-direction:row;height:100%;width:var(--ngs-split-gutter-size);cursor:col-resize}:host.ngs-split-horizontal ::ng-deep>.ngs-split-gutter:before{width:100%;height:100%;top:0;left:0}:host.ngs-split-horizontal ::ng-deep>.ngs-split-gutter>.ngs-split-gutter-handle{width:var(--ngs-split-handle-size);height:100%;left:calc(-1 * var(--ngs-split-handle-offset));flex-direction:column;gap:2px}:host.ngs-split-horizontal ::ng-deep>.ngs-split-pane{height:100%;min-height:0}:host.ngs-split-vertical{flex-direction:column}:host.ngs-split-vertical.ngs-dragging{cursor:row-resize}:host.ngs-split-vertical ::ng-deep>.ngs-split-gutter{flex-direction:column;width:100%;height:var(--ngs-split-gutter-size);cursor:row-resize}:host.ngs-split-vertical ::ng-deep>.ngs-split-gutter:before{width:100%;height:100%;top:0;left:0}:host.ngs-split-vertical ::ng-deep>.ngs-split-gutter>.ngs-split-gutter-handle{width:100%;height:var(--ngs-split-handle-size);top:calc(-1 * var(--ngs-split-handle-offset));flex-direction:row;gap:3px}:host.ngs-split-vertical ::ng-deep>.ngs-split-pane{width:100%;min-width:0}:host.ngs-split-vertical ::ng-deep>.ngs-split-pane.ngs-split-pane-hidden{max-width:0}:host.ngs-split-disabled ::ng-deep>.ngs-split-gutter{cursor:default}:host.ngs-split-disabled ::ng-deep>.ngs-split-gutter .ngs-split-gutter-handle{background-image:none}:host.ngs-split-transition.ngs-split-init:not(.ngs-dragging) ::ng-deep>.ngs-split-gutter,:host.ngs-split-transition.ngs-split-init:not(.ngs-dragging) ::ng-deep>.ngs-split-pane{transition:flex-basis .3s}\n"] }]
        }], ctorParameters: () => [], propDecorators: { direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], unit: [{ type: i0.Input, args: [{ isSignal: true, alias: "unit", required: false }] }], gutterSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutterSize", required: false }] }], gutterStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutterStep", required: false }] }], restrictMove: [{ type: i0.Input, args: [{ isSignal: true, alias: "restrictMove", required: false }] }], useTransition: [{ type: i0.Input, args: [{ isSignal: true, alias: "useTransition", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], dir: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], gutterDblClickDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutterDblClickDuration", required: false }] }], dragStart: [{ type: i0.Output, args: ["dragStart"] }], dragEnd: [{ type: i0.Output, args: ["dragEnd"] }], gutterClick: [{ type: i0.Output, args: ["gutterClick"] }], gutterDblClick: [{ type: i0.Output, args: ["gutterDblClick"] }], transitionEnd: [{ type: i0.Output, args: ["transitionEnd"] }], gutterEls: [{ type: i0.ViewChildren, args: ['gutterEls', { isSignal: true }] }] } });

class SplitPane {
    ngZone = inject(NgZone);
    renderer = inject(Renderer2);
    split = inject(Split);
    elRef = inject(ElementRef);
    /**
     * Order of the area. Used to maintain the order of areas when toggling their visibility.
     * Toggling area visibility without specifying an `order` leads to weird behavior.
     */
    orderIn = input(null, { ...(ngDevMode ? { debugName: "orderIn" } : /* istanbul ignore next */ {}), alias: 'order',
        transform: v => getInputPositiveNumber(v, null) });
    /**
     * Size of the area in selected unit (percent/pixel).
     * - Percent: All areas sizes should equal to `100`, If not, all areas will have the same size.
     * - Pixel: An area with wildcard size (`size="*"`) is mandatory (only one) and
     *   can't have `visible="false"` or `minSize`/`maxSize`/`lockSize` properties.
     */
    sizeIn = input(null, { ...(ngDevMode ? { debugName: "sizeIn" } : /* istanbul ignore next */ {}), alias: 'size',
        transform: v => getInputPositiveNumber(v, null) });
    /** Minimum pixel or percent size, should be equal to or smaller than provided `size`. */
    minSizeIn = input(null, { ...(ngDevMode ? { debugName: "minSizeIn" } : /* istanbul ignore next */ {}), alias: 'minSize',
        transform: v => getInputPositiveNumber(v, null) });
    /** Maximum pixel or percent size, should be equal to or larger than provided `size`. */
    maxSizeIn = input(null, { ...(ngDevMode ? { debugName: "maxSizeIn" } : /* istanbul ignore next */ {}), alias: 'maxSize',
        transform: v => getInputPositiveNumber(v, null) });
    /** Lock area size, same as `minSize`=`maxSize`=`size`. */
    lockSizeIn = input(false, { ...(ngDevMode ? { debugName: "lockSizeIn" } : /* istanbul ignore next */ {}), alias: 'lockSize', transform: booleanAttribute });
    /** Hide area visually but still present in the DOM, use `ngIf` to completely remove it. */
    visibleIn = input(true, { ...(ngDevMode ? { debugName: "visibleIn" } : /* istanbul ignore next */ {}), alias: 'visible', transform: booleanAttribute });
    /** Show handle (three dots) on the gutter adjacent to this pane. */
    withHandleIn = input(false, { ...(ngDevMode ? { debugName: "withHandleIn" } : /* istanbul ignore next */ {}), alias: 'withHandle', transform: booleanAttribute });
    // Writable state reflecting current effective values (can be changed programmatically by Split)
    orderSig = signal(null, { ...(ngDevMode ? { debugName: "orderSig" } : /* istanbul ignore next */ {}), equal: Object.is });
    sizeSig = signal(null, { ...(ngDevMode ? { debugName: "sizeSig" } : /* istanbul ignore next */ {}), equal: Object.is });
    minSizeSig = signal(null, { ...(ngDevMode ? { debugName: "minSizeSig" } : /* istanbul ignore next */ {}), equal: Object.is });
    maxSizeSig = signal(null, { ...(ngDevMode ? { debugName: "maxSizeSig" } : /* istanbul ignore next */ {}), equal: Object.is });
    lockSizeSig = signal(false, { ...(ngDevMode ? { debugName: "lockSizeSig" } : /* istanbul ignore next */ {}), equal: Object.is });
    visibleSig = signal(true, { ...(ngDevMode ? { debugName: "visibleSig" } : /* istanbul ignore next */ {}), equal: Object.is });
    withHandleSig = signal(false, { ...(ngDevMode ? { debugName: "withHandleSig" } : /* istanbul ignore next */ {}), equal: Object.is });
    transitionListener;
    lockListeners = [];
    constructor() {
        this.renderer.addClass(this.elRef.nativeElement, 'ngs-split-pane');
        this.split.addArea(this);
        this.ngZone.runOutsideAngular(() => {
            this.transitionListener = this.renderer.listen(this.elRef.nativeElement, 'transitionend', (event) => {
                // Limit only flex-basis transition to trigger the event
                if (event.propertyName === 'flex-basis') {
                    this.split.notify('transitionEnd', -1);
                }
            });
        });
        // Sync inputs to writable state
        effect(() => this.orderSig.set(this.orderIn()));
        effect(() => this.sizeSig.set(this.sizeIn()));
        effect(() => this.minSizeSig.set(this.minSizeIn()));
        effect(() => this.maxSizeSig.set(this.maxSizeIn()));
        effect(() => this.lockSizeSig.set(this.lockSizeIn()));
        effect(() => this.withHandleSig.set(this.withHandleIn()));
        // React to visibility changes
        effect(() => {
            const isVisible = this.visibleIn();
            this.visibleSig.set(isVisible);
            if (isVisible) {
                this.split.showArea(this);
                this.renderer.removeClass(this.elRef.nativeElement, 'ngs-split-pane-hidden');
            }
            else {
                this.split.hideArea(this);
                this.renderer.addClass(this.elRef.nativeElement, 'ngs-split-pane-hidden');
            }
        });
        // React to state changes that require rebuild
        effect(() => {
            this.orderSig();
            if (!this.split.isDraggingPublic()) {
                this.split.updateArea(this, true, false);
            }
        });
        effect(() => {
            this.sizeSig();
            this.minSizeSig();
            this.maxSizeSig();
            this.lockSizeSig();
            if (!this.split.isDraggingPublic()) {
                this.split.updateArea(this, false, true);
            }
        });
        effect(() => {
            this.withHandleSig();
            if (!this.split.isDraggingPublic()) {
                this.split.updateArea(this, false, false);
            }
        });
    }
    // Imperative API used by Split
    getOrder() { return this.orderSig(); }
    getSize() { return this.sizeSig(); }
    setSize(v) {
        this.sizeSig.set(v);
        this.split.updateAreaInternal(this);
    }
    getMinSize() { return this.minSizeSig(); }
    getMaxSize() { return this.maxSizeSig(); }
    isLocked() { return this.lockSizeSig(); }
    isVisible() { return this.visibleSig(); }
    hasHandle() { return this.withHandleSig(); }
    setStyleOrder(value) {
        this.renderer.setStyle(this.elRef.nativeElement, 'order', value);
    }
    setStyleFlex(grow, shrink, basis, isMin, isMax) {
        // Need 3 separated properties to work on IE11 (https://github.com/angular/flex-layout/issues/323)
        this.renderer.setStyle(this.elRef.nativeElement, 'flex-grow', grow);
        this.renderer.setStyle(this.elRef.nativeElement, 'flex-shrink', shrink);
        this.renderer.setStyle(this.elRef.nativeElement, 'flex-basis', basis);
        if (basis === '0px' || basis === '0%') {
            this.renderer.setStyle(this.elRef.nativeElement, 'overflow', 'hidden');
        }
        else {
            this.renderer.removeStyle(this.elRef.nativeElement, 'overflow');
        }
        if (isMin === true) {
            this.renderer.addClass(this.elRef.nativeElement, 'ngs-min');
        }
        else {
            this.renderer.removeClass(this.elRef.nativeElement, 'ngs-min');
        }
        if (isMax === true) {
            this.renderer.addClass(this.elRef.nativeElement, 'ngs-max');
        }
        else {
            this.renderer.removeClass(this.elRef.nativeElement, 'ngs-max');
        }
    }
    lockEvents() {
        this.ngZone.runOutsideAngular(() => {
            this.lockListeners.push(this.renderer.listen(this.elRef.nativeElement, 'selectstart', (e) => false));
            this.lockListeners.push(this.renderer.listen(this.elRef.nativeElement, 'dragstart', (e) => false));
        });
    }
    unlockEvents() {
        while (this.lockListeners.length > 0) {
            const fct = this.lockListeners.pop();
            if (fct) {
                fct();
            }
        }
    }
    ngOnDestroy() {
        this.unlockEvents();
        if (this.transitionListener) {
            this.transitionListener();
        }
        this.split.removeArea(this);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SplitPane, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.4", type: SplitPane, isStandalone: true, selector: "ngs-split-pane, [ngs-split-pane]", inputs: { orderIn: { classPropertyName: "orderIn", publicName: "order", isSignal: true, isRequired: false, transformFunction: null }, sizeIn: { classPropertyName: "sizeIn", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, minSizeIn: { classPropertyName: "minSizeIn", publicName: "minSize", isSignal: true, isRequired: false, transformFunction: null }, maxSizeIn: { classPropertyName: "maxSizeIn", publicName: "maxSize", isSignal: true, isRequired: false, transformFunction: null }, lockSizeIn: { classPropertyName: "lockSizeIn", publicName: "lockSize", isSignal: true, isRequired: false, transformFunction: null }, visibleIn: { classPropertyName: "visibleIn", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, withHandleIn: { classPropertyName: "withHandleIn", publicName: "withHandle", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["ngsSplitPane"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SplitPane, decorators: [{
            type: Directive,
            args: [{
                    selector: 'ngs-split-pane, [ngs-split-pane]',
                    exportAs: 'ngsSplitPane',
                    standalone: true,
                }]
        }], ctorParameters: () => [], propDecorators: { orderIn: [{ type: i0.Input, args: [{ isSignal: true, alias: "order", required: false }] }], sizeIn: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], minSizeIn: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSize", required: false }] }], maxSizeIn: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSize", required: false }] }], lockSizeIn: [{ type: i0.Input, args: [{ isSignal: true, alias: "lockSize", required: false }] }], visibleIn: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }], withHandleIn: [{ type: i0.Input, args: [{ isSignal: true, alias: "withHandle", required: false }] }] } });

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

export { SPLIT_DEFAULT_OPTIONS, Split, SplitPane, getAreaAbsorptionCapacity, getAreaAbsorptionCapacityPercent, getAreaAbsorptionCapacityPixel, getAreaMaxSize, getAreaMinSize, getElementPixelSize, getGutterSideAbsorptionCapacity, getInputPositiveNumber, getPointFromEvent, isUserSizesValid, provideSplit, updateAreaSize };
//# sourceMappingURL=ngstarter-ui-components-split.mjs.map
