UNPKG

ng-terminal

Version:

NgTerminal is a terminal component on Angular 16 or higher.

1,134 lines 64.6 kB
import * as i0 from '@angular/core';
import { Injectable, Optional, Component, ViewEncapsulation, EventEmitter, ChangeDetectionStrategy, Output, Input, ViewChild, NgModule } from '@angular/core';
import { Terminal } from '@xterm/xterm';
import { FitAddon } from '@xterm/addon-fit';
import { Subject } from 'rxjs';
import * as i2 from 'angular-resizable-element';
import { ResizableModule } from 'angular-resizable-element';
import * as i3 from '@angular/common';
import { CommonModule } from '@angular/common';

/**
 *
 * In the past, indivisual property changes caused very unexpected behavior on NgTerminal.
 * To solve issues related to property changes, Queue is applied.
 */
class LinearRenderService {
    constructor(hostRef) {
        this.hostRef = hostRef;
        this.handlerToCheckElementConnection = undefined;
        /**
         * This queue has items to have a influence on the view and items are handled in order.
         */
        this.propertyChangeQueue = [];
        this.itemsToBeHandled = new Subject();
        /**
         * Handle a next set of changes if it exists.
         */
        this.handleImmediate = () => {
            if (!this.handlerToCheckElementConnection) {
                let list = this.propertyChangeQueue.splice(0, 1);
                if (list.length == 1) {
                    this.itemsToBeHandled.next(list[0]);
                }
            }
        };
    }
    get renderObservable() {
        return this.itemsToBeHandled;
    }
    /**
     * {@link handleNextOne()} calls {@link handleImmediate()} if an element is connected.
     * Otherwise, {@link pollAndHandle()} is called.
     */
    handleNextOne(lazy = false) {
        if (!this.hostRef.nativeElement.isConnected || lazy) {
            this.pollAndHandle(!this.hostRef.nativeElement.isConnected
                ? 'NOT_CONNECTED_ELEMENT'
                : 'LAZY');
        }
        else {
            this.handleImmediate();
        }
    }
    /**
     * This method pushes item into {@link propertyChangeQueue}.
     * @param item
     */
    pushAndHandle(item, lazy = false) {
        let changeWithDefault = Object.assign({}, item);
        this.propertyChangeQueue.push(changeWithDefault);
        this.handleNextOne(lazy);
    }
    /**
     * {@link pollAndHandle()} continues checking whether new item is put on a queue to call {@link handleImmediate()}.
     */
    pollAndHandle(mode) {
        const pollFunction = () => {
            if (this.handlerToCheckElementConnection)
                return;
            const interval = setInterval(() => {
                if (this.hostRef.nativeElement.isConnected) {
                    clearInterval(interval);
                    this.handlerToCheckElementConnection = undefined;
                    this.handleImmediate();
                }
            }, mode === 'NOT_CONNECTED_ELEMENT' ? 500 : 30);
            this.handlerToCheckElementConnection = interval;
        };
        // Start polling
        pollFunction();
    }
    ngOnDestroy() {
        if (this.handlerToCheckElementConnection)
            clearInterval(this.handlerToCheckElementConnection);
    }
}
LinearRenderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LinearRenderService, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Injectable });
LinearRenderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LinearRenderService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LinearRenderService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root',
                }]
        }], ctorParameters: function () { return [{ type: i0.ElementRef }]; } });

class ModuleOptions {
    constructor() {
        this.enableLog = true;
    }
}

class LoggingService {
    constructor(_options) {
        this.enableLog = false;
        if (_options)
            this.enableLog = _options.enableLog;
    }
    log(loggingFunc) {
        if (this.enableLog)
            loggingFunc();
    }
}
LoggingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LoggingService, deps: [{ token: ModuleOptions, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
LoggingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LoggingService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LoggingService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root',
                }]
        }], ctorParameters: function () {
        return [{ type: ModuleOptions, decorators: [{
                        type: Optional
                    }] }];
    } });

class GlobalStyleComponent {
    constructor() { }
    ngOnInit() {
    }
}
GlobalStyleComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: GlobalStyleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
GlobalStyleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: GlobalStyleComponent, selector: "global-style", ngImport: i0, template: "", styles: ["/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * https://github.com/chjj/term.js\n * @license MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n * Originally forked from (with the author's permission):\n *   Fabrice Bellard's javascript vt100 for jslinux:\n *   http://bellard.org/jslinux/\n *   Copyright (c) 2011 Fabrice Bellard\n *   The original design remains. The terminal itself\n *   has been extended to include xterm CSI codes, among\n *   other features.\n */.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;inset:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility,.xterm .xterm-message{position:absolute;inset:0;z-index:10;color:transparent;pointer-events:none}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{-webkit-text-decoration:double underline;text-decoration:double underline}.xterm-underline-3{-webkit-text-decoration:wavy underline;text-decoration:wavy underline}.xterm-underline-4{-webkit-text-decoration:dotted underline;text-decoration:dotted underline}.xterm-underline-5{-webkit-text-decoration:dashed underline;text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{-webkit-text-decoration:overline double underline;text-decoration:overline double underline}.xterm-overline.xterm-underline-3{-webkit-text-decoration:overline wavy underline;text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{-webkit-text-decoration:overline dotted underline;text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{-webkit-text-decoration:overline dashed underline;text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}\n"], encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: GlobalStyleComponent, decorators: [{
            type: Component,
            args: [{ selector: 'global-style', encapsulation: ViewEncapsulation.None, template: "", styles: ["/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * https://github.com/chjj/term.js\n * @license MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n * Originally forked from (with the author's permission):\n *   Fabrice Bellard's javascript vt100 for jslinux:\n *   http://bellard.org/jslinux/\n *   Copyright (c) 2011 Fabrice Bellard\n *   The original design remains. The terminal itself\n *   has been extended to include xterm CSI codes, among\n *   other features.\n */.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;inset:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility,.xterm .xterm-message{position:absolute;inset:0;z-index:10;color:transparent;pointer-events:none}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{-webkit-text-decoration:double underline;text-decoration:double underline}.xterm-underline-3{-webkit-text-decoration:wavy underline;text-decoration:wavy underline}.xterm-underline-4{-webkit-text-decoration:dotted underline;text-decoration:dotted underline}.xterm-underline-5{-webkit-text-decoration:dashed underline;text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{-webkit-text-decoration:overline double underline;text-decoration:overline double underline}.xterm-overline.xterm-underline-3{-webkit-text-decoration:overline wavy underline;text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{-webkit-text-decoration:overline dotted underline;text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{-webkit-text-decoration:overline dashed underline;text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}\n"] }]
        }], ctorParameters: function () { return []; } });

class NgTerminalComponent {
    /**
     * A datsource is an observable where NgTerminal reads charactors.
     */
    set _dataSource(dataSource) {
        if (!dataSource)
            return;
        if (this.dataSourceSubscription != undefined)
            this.dataSourceSubscription.unsubscribe();
        this.dataSource = dataSource;
        this.dataSourceSubscription = this.dataSource.subscribe((data) => this.write(data));
    }
    /**
     * Toggle draggable.
     */
    set draggable(draggable) {
        this._draggable = draggable;
    }
    get draggable() {
        return this._draggable;
    }
    setMinWidth(width) {
        this._minWidthInput = width;
    }
    setMinHeight(height) {
        this._minHeightInput = height;
    }
    setDraggable(draggable) {
        this._draggable = draggable;
        this.lastDraggedPosition = undefined; // Reset position values
    }
    setXtermOptions(options) {
        this._xtermOptions = options;
        this.linearRender.pushAndHandle({ time: new Date(), type: 'none' });
    }
    setRows(rows) {
        if (this._rowsInput != rows) {
            this._rowsInput = rows;
            this.linearRender.pushAndHandle({
                time: new Date(),
                type: 'rowChanged',
            });
        }
    }
    setCols(cols) {
        if (this._colsInput != cols) {
            this._colsInput = cols;
            this.linearRender.pushAndHandle({
                time: new Date(),
                type: 'columnChanged',
            });
        }
    }
    setStyle(styleObject) {
        var _a;
        if (JSON.stringify((_a = this._stylesInput) !== null && _a !== void 0 ? _a : {}) !=
            JSON.stringify(styleObject !== null && styleObject !== void 0 ? styleObject : {})) {
            this._stylesInput = styleObject;
            this.linearRender.pushAndHandle({
                time: new Date(),
                type: 'none',
            });
        }
    }
    constructor(renderer, //Render is being used for fast rendering without markForCheck().
    hostRef, loggingService) {
        this.renderer = renderer;
        this.hostRef = hostRef;
        this.loggingService = loggingService;
        this.dataSubject = new Subject();
        this.keySubject = new Subject();
        this.keyInputSubjectSubscription = undefined;
        this.keyEventSubjectSubscription = undefined;
        this.allLogsSubjectSubscription = undefined;
        this.dataSourceSubscription = undefined;
        this.resizableObservers = [];
        this.dataSource = undefined;
        this.paddingSize = 5;
        this.stylesForResizeBox = { display: 'block' };
        /**
         * @deprecated use (data)='' instead.
         * An emitter emits printable characters pushed from xterm's onData() when a user typed on the terminal.
         */
        this.keyInputEmitter = new EventEmitter();
        /**
         * @deprecated use (key)='' instead.
         * An emitter emits key and keybaord event pushed from xterm's onKey() when a user typed on the terminal.
         */
        this.keyEventEmitter = new EventEmitter();
        /**
         * An emitter emits printable characters pushed from xterm's onData() when a user typed on the terminal.
         */
        this.dataEmitter = this.keyInputEmitter;
        /**
         * An emitter emits key and keybaord event pushed from xterm's onKey() when a user typed on the terminal.
         */
        this.keyEmitter = this.keyEventEmitter;
        /**
         * An wrapper of {@link ITerminalOptions} for Xterm.
         */
        this._xtermOptions = {};
        this.lastDraggedPosition = undefined;
        this._draggable = false;
        this._stylesInput = {};
        this.handleToCheckLazyContainer = undefined;
        this.lastDetectedWidth = 0;
        this.linearRender = new LinearRenderService(hostRef);
    }
    setup() {
        if (this.xterm) {
            this.xterm.onData((input) => {
                this.dataSubject.next(input);
            });
            this.xterm.onKey((e) => {
                this.keySubject.next(e);
            });
        }
        this.keyInputSubjectSubscription = this.dataSubject.subscribe((data) => {
            this.keyInputEmitter.emit(data);
        });
        this.keyEventSubjectSubscription = this.keySubject.subscribe((e) => {
            this.keyEventEmitter.emit(e);
        });
        this.setupResizeObservers();
        // if (ob3) this.resizableObservers.push(ob3);
        this.allLogsSubjectSubscription =
            this.linearRender.renderObservable.subscribe((change) => {
                if (change)
                    this.coordinateOuterAndTerminal(change);
                else
                    this.coordinateOuterAndTerminal(change);
                this.linearRender.handleNextOne();
            });
        this.linearRender.handleNextOne();
    }
    /**
     * set dimensions
     */
    setOuterDimensions(left, top, width, height) {
        this.linearRender.pushAndHandle({
            time: new Date(),
            type: 'dragged',
            dragged: { draggedWidth: `${width}px`, draggedHeight: `${height}px` },
        });
    }
    applyStylesToResizeBox() {
        Object.keys(this.stylesForResizeBox)
            .map((key) => {
            return { key, value: this.stylesForResizeBox[key] };
        })
            .forEach(({ key, value }) => {
            if (this.resizeBox) {
                if (value)
                    this.renderer.setStyle(this.resizeBox.nativeElement, key, value);
                else {
                    this.renderer.removeStyle(this.resizeBox.nativeElement, key);
                }
            }
        });
        this.stylesForResizeBox = this.stylesForResizeBox; //invalidate
    }
    ngOnInit() { }
    /**
     * It creates new terminal in #terminal.
     */
    ngAfterViewInit() {
        this.fitAddon = new FitAddon();
        this.xterm = new Terminal({
            allowProposedApi: true,
        });
        if (!this.terminalOuter.nativeElement.isConnected) {
            this.handleToCheckLazyContainer = setInterval(() => {
                if (this.terminalOuter.nativeElement.isConnected) {
                    try {
                        this.loggingService.log(() => console.debug("The container's been connected."));
                        this.xterm.open(this.terminalOuter.nativeElement);
                        this.xterm.loadAddon(this.fitAddon);
                        this.setup();
                        this.linearRender.pushAndHandle({ time: new Date(), type: 'none' });
                    }
                    finally {
                        if (this.handleToCheckLazyContainer)
                            clearInterval(this.handleToCheckLazyContainer);
                    }
                }
            }, 500);
        }
        else {
            this.xterm.open(this.terminalOuter.nativeElement);
            this.xterm.loadAddon(this.fitAddon);
            this.setup();
            this.linearRender.pushAndHandle({ time: new Date(), type: 'none' });
        }
    }
    ngOnChanges(changes) {
        var _a, _b, _c, _d;
        this.loggingService.log(() => console.group('onChanges'));
        this.loggingService.log(() => console.debug('prop: ', changes));
        this.loggingService.log(() => console.groupEnd());
        if (changes === null || changes === void 0 ? void 0 : changes['_rowsInput']) {
            if (((_a = changes === null || changes === void 0 ? void 0 : changes['_rowsInput']) === null || _a === void 0 ? void 0 : _a.previousValue) !=
                ((_b = changes === null || changes === void 0 ? void 0 : changes['_rowsInput']) === null || _b === void 0 ? void 0 : _b.currentValue)) {
                this.linearRender.pushAndHandle({
                    time: new Date(),
                    type: 'rowChanged',
                });
            }
        }
        if (changes === null || changes === void 0 ? void 0 : changes['_colsInput']) {
            if (((_c = changes === null || changes === void 0 ? void 0 : changes['_colsInput']) === null || _c === void 0 ? void 0 : _c.previousValue) !=
                ((_d = changes === null || changes === void 0 ? void 0 : changes['_colsInput']) === null || _d === void 0 ? void 0 : _d.currentValue)) {
                this.linearRender.pushAndHandle({
                    time: new Date(),
                    type: 'columnChanged',
                });
            }
        }
        if (changes === null || changes === void 0 ? void 0 : changes['draggable'])
            this.linearRender.pushAndHandle({ time: new Date(), type: 'none' });
    }
    /**
     * It serves a callback function to adjust the dimensions of the xterm-screen, xterm-view, and resize box
     * after making any changes to the outer box, rows, or columns, or when the resize box is being dragged.
     *
     * There several factors that affect dimensions, as I mentioned earlier.
     * Regardless of whether the draggable feature is on, if new row or column value is input, this value will be applied.
     * - Draggable = New specified Row/Column value > Full (Default)
     * @param change This argument represents a single change that occured.
     * @returns
     */
    coordinateOuterAndTerminal(change) {
        var _a;
        this.loggingService.log(() => console.debug(`changeList: ${JSON.stringify(change)}`));
        if (!this.xterm)
            return;
        const isHostElementVisible = ((_a = this.hostRef.nativeElement) === null || _a === void 0 ? void 0 : _a.offsetParent) !== null;
        if (!isHostElementVisible) {
            // Do nothing if the host element is invisible.
            this.loggingService.log(() => console.debug('`display` of host element was set to `none`'));
            return;
        }
        this.doUpdateXtermStyles();
        this.doAdjustDimensionOfResizeBox(change);
        this.doAdjustSizeOfXtermScreen(change);
        this.doUpdateViewportAndResizeBoxWithPixcelUnit();
    }
    /**
     * apply options to the xterm terminal
     * @returns
     */
    doUpdateXtermStyles() {
        var _a, _b;
        if (!this.xterm)
            return;
        this.xterm.options = Object.assign({}, this._xtermOptions);
        // apply the theme to the background of the handle
        if ((_a = this._xtermOptions.theme) === null || _a === void 0 ? void 0 : _a.background) {
            if (!this.resizeHandleStyleRule)
                this.resizeHandleStyleRule = this.findCssStyleRule('.resize-handle[');
            if (this.resizeHandleStyleRule)
                this.resizeHandleStyleRule.style.backgroundColor =
                    this._xtermOptions.theme.background;
        }
        if ((_b = this._xtermOptions.theme) === null || _b === void 0 ? void 0 : _b.border) {
            if (!this.resizeHandleActiveStyleRule)
                this.resizeHandleActiveStyleRule =
                    this.findCssStyleRule('.handle-active');
            if (this.resizeHandleActiveStyleRule)
                this.resizeHandleActiveStyleRule.style.backgroundColor =
                    this._xtermOptions.theme.border;
        }
    }
    /**
     * If the resize handles are moved, the resize box adjusts to the new dimensions;
     * otherwise, it defaults to a maximized size.
     * @param change
     */
    doAdjustDimensionOfResizeBox(change) {
        var _a, _b;
        this.stylesForResizeBox = Object.assign(Object.assign(Object.assign({}, this.stylesForResizeBox), this._stylesInput), { width: this.stylesForResizeBox.width, height: this.stylesForResizeBox.height });
        // Reset styles of the resize element
        if (change.type === 'dragged') {
            const minWidth = (_a = this._minWidthInput) !== null && _a !== void 0 ? _a : 24;
            const minHeight = (_b = this._minHeightInput) !== null && _b !== void 0 ? _b : 24;
            const width = parseInt(change.dragged.draggedWidth) > minWidth
                ? change.dragged.draggedWidth
                : `${minWidth}px`;
            const height = parseInt(change.dragged.draggedHeight) > minHeight
                ? change.dragged.draggedHeight
                : `${minHeight}px`;
            this.stylesForResizeBox.width = width;
            this.stylesForResizeBox.height = height;
            this.lastDraggedPosition = {
                width,
                height,
            };
            this.applyStylesToResizeBox();
        }
        else if (!(this.draggable && this.lastDraggedPosition)) {
            // When `_colsInput` and `draggable` is not enabled,
            // it fits the size to the host element.
            const currentHostWidth = getComputedStyle(this.hostRef.nativeElement).width;
            const detectBoxWidth = getComputedStyle(this.detectBox.nativeElement).width;
            let smallParent = false;
            if (parseFloat(detectBoxWidth) < parseFloat(currentHostWidth)) {
                // the width of the parent is smaller than that of resize-box element
                smallParent = true;
            }
            if (smallParent) {
                // It's been written to solve https://github.com/qwefgh90/ng-terminal/issues/79
                // If the width of the flex-box (that is the parent of the host element) is smaller than that of child element, the host element is adjusted to the width of child element
                // host element: 1000px, resize-box(child): 985px -> host element: 985px, resize-box(child): 970px -> ... -> stop
                // This code check if the parent element (that is the parent of `<ng-terminal>), is smaller than `.resize-box`
                // and ensures that the width of the `<ng-terminal>` adjusts to match that of the parent element rather than the child elements, in the subsequent events.
                this.stylesForResizeBox.width = `${parseFloat(detectBoxWidth)}px`;
                this.applyStylesToResizeBox();
            }
            else {
                // but if the dimension of host element is resized, update width and height
                // If `_rowsInput` is specified, NgTerminal keep the current height; otherwise, the height is set to 100%
                if (!this._rowsInput)
                    this.stylesForResizeBox.height = '100%';
                if (!this._colsInput)
                    this.stylesForResizeBox.width = '100%';
                this.applyStylesToResizeBox();
            }
        }
    }
    /**
     * This function uses fitAddon() to adjust the dimension of xterm-screen to character unit
     * If the draggable value is true or there are no fixed values for the row or column,
     * it fits the xterm terminal boxes into the resize box;
     * otherwise, it resizes the xterm terminal with specified row and column values.
     */
    doAdjustSizeOfXtermScreen(change) {
        var _a, _b, _c;
        if (!this.xterm)
            return;
        if ((change.type == 'rowChanged' && this._rowsInput) ||
            (change.type == 'columnChanged' && this._colsInput)) {
            this.xterm.resize((_a = this._colsInput) !== null && _a !== void 0 ? _a : this.xterm.cols, (_b = this._rowsInput) !== null && _b !== void 0 ? _b : this.xterm.rows);
        }
        else {
            if (this.xterm.element) {
                // The fitAddon.fit() operation doesn't recognize the padding values of terminalOuter.
                // It seems to be using the padding values of xterm element instead.
                // Therefore, we establish a brief time frame to adjust the padding values before and after executing fitAddon.fit().
                // If this line is removed, when dragging resize-box vertically, the width is decreased.
                this.xterm.element.style.paddingLeft = `${this.paddingSize}px`;
                this.printDimension('Before fitAddon.fit() of Xterm');
                (_c = this.fitAddon) === null || _c === void 0 ? void 0 : _c.fit();
                this.printDimension('After fitAddon.fit() of Xterm');
                this.xterm.element.style.paddingLeft = `${0}px`;
            }
        }
    }
    /**
     * This functions sets width of the resize box, xterm-viewport and xterm-screen with specific pixel values.
     */
    doUpdateViewportAndResizeBoxWithPixcelUnit() {
        var _a;
        if ((_a = this.xterm) === null || _a === void 0 ? void 0 : _a.element) {
            let xtermScreen = this.xterm.element.getElementsByClassName('xterm-screen')[0];
            let xtermViewport = this.xterm.element.getElementsByClassName('xterm-viewport')[0];
            const screenWidth = xtermScreen.clientWidth;
            const screenHeight = xtermScreen.clientHeight;
            const core = this.underlying._core;
            const scrollBarWidth = core.viewport.scrollBarWidth;
            const hostWidth = parseInt(getComputedStyle(this.hostRef.nativeElement).width);
            // It fixes a bug where the viewport's width isn't updated by fitAddon.fit()
            this.renderer.setStyle(xtermViewport, 'width', `${screenWidth + scrollBarWidth}px`);
            // It adjusts the dimension of the resize box to the xterm-screen element.
            const calulatedBoxWidth = screenWidth + scrollBarWidth + this.paddingSize * 2;
            const componentElement = this.hostRef.nativeElement;
            const componentWith = parseInt(getComputedStyle(componentElement).width);
            const restrictedWidth = calulatedBoxWidth > componentWith ? componentWith : calulatedBoxWidth;
            this.stylesForResizeBox = Object.assign(Object.assign({}, this.stylesForResizeBox), { width: `${restrictedWidth}px`, height: `${screenHeight + this.paddingSize * 2}px` });
            this.applyStylesToResizeBox();
            this.printDimension('After update the dimensions for all boxes with pixel values');
        }
    }
    printDimension(title) {
        var _a;
        if ((_a = this.xterm) === null || _a === void 0 ? void 0 : _a.element) {
            let resizeBox = this.resizeBox.nativeElement;
            let xtermScreen = this.xterm.element.getElementsByClassName('xterm-screen')[0];
            let xtermViewport = this.xterm.element.getElementsByClassName('xterm-viewport')[0];
            const screenWidth = xtermScreen.clientWidth;
            const screenHeight = xtermScreen.clientHeight;
            this.loggingService.log(() => console.group(`${title}`));
            this.loggingService.log(() => console.debug(`width(resizeBox): ${getComputedStyle(resizeBox).width},
width(viewport): ${getComputedStyle(xtermViewport).width},
width(screen): ${screenWidth}
scrollBarWidth: ${this.scrollBarWidth}`));
            this.loggingService.log(() => console.debug(`height(resizeBox): ${getComputedStyle(resizeBox).height},
height(viewport) ${getComputedStyle(xtermViewport).height},
height(screen): ${screenHeight}`));
            this.loggingService.log(() => console.groupEnd());
        }
    }
    /**
     * If pushAndHandle() were used, there could be an issue
     * because it can adjust the size of elements during a loop of ResizeObserver.
     */
    setupResizeObservers() {
        this.resizableObservers = [];
        let ob1 = this.observeXtermViewportDimension();
        let ob2 = this.observeHostDimension();
        if (ob1)
            this.resizableObservers.push(ob1);
        if (ob2)
            this.resizableObservers.push(ob2);
    }
    observeXtermViewportDimension() {
        let xtermViewport = this.terminalOuter.nativeElement.querySelector('.xterm-viewport');
        if (xtermViewport) {
            const resizeObserver = new ResizeObserver((entries) => {
                var _a, _b;
                const outerDivWidth = (_a = this.terminalOuter.nativeElement) === null || _a === void 0 ? void 0 : _a.clientWidth;
                const outerDivHeight = (_b = this.terminalOuter.nativeElement) === null || _b === void 0 ? void 0 : _b.clientHeight;
                for (let entry of entries) {
                    if (entry.contentBoxSize.length > 0) {
                        let width = entry.target.clientWidth;
                        let height = entry.target.clientHeight;
                        if ((outerDivWidth && width > outerDivWidth) ||
                            (outerDivHeight && height > outerDivHeight)) {
                            this.loggingService.log(() => console.debug('Changes on a xterm viewport element will be handled.'));
                            this.linearRender.pushAndHandle({
                                time: new Date(),
                                type: 'xtermViewportExceedingOuterDiv',
                                xtermViewportExceedingOuterDiv: {
                                    width: `${width}`,
                                    height: `${height}`,
                                    outerDivWidth: `${outerDivWidth}`,
                                    outerDivHeight: `${outerDivHeight}`,
                                },
                            }, true);
                        }
                    }
                }
            });
            resizeObserver.observe(xtermViewport);
            return resizeObserver;
        }
        else {
            this.loggingService.log(() => console.error('Invalid state is detected. xterm element should exist below .terminal-outer.'));
        }
        return undefined;
    }
    observeHostDimension() {
        let hostElement = this.hostRef.nativeElement;
        let detectBox = this.detectBox.nativeElement;
        if (hostElement && detectBox) {
            const resizeObserver = new ResizeObserver((entries) => {
                for (let entry of entries) {
                    if (entry.target === hostElement) {
                        if (entry.contentBoxSize.length > 0) {
                            let width = getComputedStyle(entry.target).width;
                            let height = getComputedStyle(entry.target).height;
                            if (parseInt(width) >= 0 && parseInt(height) >= 0) {
                                this.loggingService.log(() => console.debug('Changes on a host element will be handled.'));
                                this.linearRender.pushAndHandle({
                                    time: new Date(),
                                    type: 'hostResized',
                                    hostResized: { width: `${width}`, height: `${height}` },
                                }, true);
                            }
                        }
                    }
                    if (entry.target === detectBox) {
                        if (entry.contentBoxSize.length > 0) {
                            let width = getComputedStyle(entry.target).width;
                            if (parseInt(width) >= 0 &&
                                parseInt(width) <= this.lastDetectedWidth) {
                                this.loggingService.log(() => console.debug('Changes on a detect-box element will be handled.'));
                                this.linearRender.pushAndHandle({
                                    time: new Date(),
                                    type: 'detectBoxResized',
                                    detectBoxResized: { width: `${width}` },
                                }, true);
                            }
                            this.lastDetectedWidth = parseInt(width);
                        }
                    }
                }
            });
            resizeObserver.observe(hostElement);
            resizeObserver.observe(detectBox);
            return resizeObserver;
        }
        else {
            this.loggingService.log(() => console.error('Invalid state is detected. xterm element should exist below .terminal-outer.'));
        }
        return undefined;
    }
    /**
     * clean all resources
     */
    ngOnDestroy() {
        this.resizableObservers.forEach((ob) => ob.disconnect());
        if (this.keyInputSubjectSubscription)
            this.keyInputSubjectSubscription.unsubscribe();
        if (this.dataSourceSubscription)
            this.dataSourceSubscription.unsubscribe();
        if (this.keyEventSubjectSubscription)
            this.keyEventSubjectSubscription.unsubscribe();
        if (this.allLogsSubjectSubscription)
            this.allLogsSubjectSubscription.unsubscribe();
        if (this.handleToCheckLazyContainer)
            clearInterval(this.handleToCheckLazyContainer);
        if (this.xterm)
            this.xterm.dispose();
        this.loggingService.log(() => console.debug('All resources has been cleaned up.'));
    }
    write(chars) {
        var _a;
        (_a = this.xterm) === null || _a === void 0 ? void 0 : _a.write(chars);
    }
    get keyInput() {
        return this.dataSubject;
    }
    onData() {
        return this.dataSubject;
    }
    get keyEventInput() {
        return this.keySubject;
    }
    onKey() {
        return this.keySubject;
    }
    get underlying() {
        return this.xterm;
    }
    get isDraggableOnEdgeActivated() {
        // return this.displayOption.activateDraggableOnEdge != undefined && this.displayOption.fixedGrid == undefined;
        return this._draggable;
    }
    get scrollBarWidth() {
        const core = this.underlying._core;
        return core.viewport.scrollBarWidth;
    }
    /**
     * After user coordinate dimensions of terminal, it's called.
     * @param left
     * @param top
     * @param width
     * @param height
     */
    onResizeEnd(left, top, width, height) {
        this.setOuterDimensions(left, top, width, height);
    }
    /**
     * Before onResizeEnd is called, it valiates dimensions to change.
     * @param re dimension to be submitted from resizable stuff
     */
    validatorFactory() {
        const comp = this;
        return (re) => {
            if (this._draggable) {
                return true;
            }
            else
                return false;
        };
    }
    findCssStyleRule(containingSelector) {
        for (let i = 0; i < document.styleSheets.length; i++) {
            let sheet = document.styleSheets.item(i);
            if (sheet) {
                for (let i = 0; i < sheet.cssRules.length; i++) {
                    let rule = sheet.cssRules.item(i);
                    if ('selectorText' in rule)
                        if (rule.selectorText.includes(containingSelector))
                            return rule;
                }
            }
        }
        return undefined;
    }
}
NgTerminalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgTerminalComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: LoggingService }], target: i0.ɵɵFactoryTarget.Component });
NgTerminalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NgTerminalComponent, selector: "ng-terminal", inputs: { _dataSource: ["dataSource", "_dataSource"], _rowsInput: ["rows", "_rowsInput"], _colsInput: ["cols", "_colsInput"], _minWidthInput: ["minWidth", "_minWidthInput"], _minHeightInput: ["minHeight", "_minHeightInput"], draggable: "draggable", _xtermOptions: ["xtermOptions", "_xtermOptions"] }, outputs: { keyInputEmitter: "keyInput", keyEventEmitter: "keyEvent", dataEmitter: "data", keyEmitter: "key" }, providers: [LinearRenderService], viewQueries: [{ propertyName: "terminalOuter", first: true, predicate: ["terminal"], descendants: true, static: true }, { propertyName: "resizeBox", first: true, predicate: ["resizeBox"], descendants: true, static: true }, { propertyName: "detectBox", first: true, predicate: ["detectBox"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Hierarchy: parent element(user) > host element(ng-terminal) > resize-box element > outer element -->\n<global-style></global-style>\n<div mwlResizable #resizeBox class=\"resize-box\" [validateResize]=\"validatorFactory()\" [enableGhostResize]=\"true\"\n    (resizeEnd)=\"onResizeEnd($event.rectangle.left, $event.rectangle.top, $event.rectangle.width??0, $event.rectangle.height??0)\">\n    <div #terminal class=\"terminal-outer\">\n    </div>\n    <div class=\"resize-handle resize-handle-top\" mwlResizeHandle [ngClass]=\"{'handle-active' : isDraggableOnEdgeActivated}\"\n        [resizeEdges]=\"{ top: false }\"></div>\n    <div class=\"resize-handle resize-handle-left\" mwlResizeHandle [ngClass]=\"{'handle-active' : isDraggableOnEdgeActivated}\"\n        [resizeEdges]=\"{ left: false }\"></div>\n    <div class=\"resize-handle resize-handle-right\" mwlResizeHandle [ngClass]=\"{'handle-active' : isDraggableOnEdgeActivated}\"\n        [resizeEdges]=\"isDraggableOnEdgeActivated ? { right: true } : { right: false }\"></div>\n    <div class=\"resize-handle resize-handle-bottom\" mwlResizeHandle [ngClass]=\"{'handle-active' : isDraggableOnEdgeActivated}\"\n        [resizeEdges]=\"isDraggableOnEdgeActivated ? { bottom: true } : { bottom: false }\"></div>\n</div>\n<div #detectBox style=\"width: 100%; height: 0px; position: absolute;\">\n</div>", styles: [".terminal-outer{box-sizing:border-box;height:100%;width:100%;padding:5px}:host{display:block;height:100%;width:100%}.resize-box{box-sizing:border-box;height:100%;width:100%;position:relative}div>.handle-active{z-index:100;background-color:#85858a!important}.resize-handle{background-color:#000}.resize-handle-top.handle-active,.resize-handle-bottom.handle-active{cursor:row-resize}.resize-handle-left.handle-active,.resize-handle-right.handle-active{cursor:col-resize}.resize-handle-top,.resize-handle-bottom{position:absolute;height:5px;width:100%}.resize-handle-top{top:0}.resize-handle-bottom{bottom:0}.resize-handle-left,.resize-handle-right{position:absolute;height:100%;width:5px}.resize-handle-left{left:0;top:0}.resize-handle-right{right:0;top:0}\n"], dependencies: [{ kind: "directive", type: i2.ResizableDirective, selector: "[mwlResizable]", inputs: ["validateResize", "enableGhostResize", "resizeSnapGrid", "resizeCursors", "ghostElementPositioning", "allowNegativeResizes", "mouseMoveThrottleMS"], outputs: ["resizeStart", "resizing", "resizeEnd"], exportAs: ["mwlResizable"] }, { kind: "directive", type: i2.ResizeHandleDirective, selector: "[mwlResizeHandle]", inputs: ["resizeEdges", "resizableContainer"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: GlobalStyleComponent, selector: "global-style" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgTerminalComponent, decorators: [{
            type: Component,
            args: [{ selector: 'ng-terminal', providers: [LinearRenderService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Hierarchy: parent element(user) > host element(ng-terminal) > resize-box element > outer element -->\n<global-style></global-style>\n<div mwlResizable #resizeBox class=\"resize-box\" [validateResize]=\"validatorFactory()\" [enableGhostResize]=\"true\"\n    (resizeEnd)=\"onResizeEnd($event.rectangle.left, $event.rectangle.top, $event.rectangle.width??0, $event.rectangle.height??0)\">\n    <div #terminal class=\"terminal-outer\">\n    </div>\n    <div class=\"resize-handle resize-handle-top\" mwlResizeHandle [ngClass]=\"{'handle-active' : isDraggableOnEdgeActivated}\"\n        [resizeEdges]=\"{ top: false }\"></div>\n    <div class=\"resize-handle resize-handle-left\" mwlResizeHandle [ngClass]=\"{'handle-active' : isDraggableOnEdgeActivated}\"\n        [resizeEdges]=\"{ left: false }\"></div>\n    <div class=\"resize-handle resize-handle-right\" mwlResizeHandle [ngClass]=\"{'handle-active' : isDraggableOnEdgeActivated}\"\n        [resizeEdges]=\"isDraggableOnEdgeActivated ? { right: true } : { right: false }\"></div>\n    <div class=\"resize-handle resize-handle-bottom\" mwlResizeHandle [ngClass]=\"{'handle-active' : isDraggableOnEdgeActivated}\"\n        [resizeEdges]=\"isDraggableOnEdgeActivated ? { bottom: true } : { bottom: false }\"></div>\n</div>\n<div #detectBox style=\"width: 100%; height: 0px; position: absolute;\">\n</div>", styles: [".terminal-outer{box-sizing:border-box;height:100%;width:100%;padding:5px}:host{display:block;height:100%;width:100%}.resize-box{box-sizing:border-box;height:100%;width:100%;position:relative}div>.handle-active{z-index:100;background-color:#85858a!important}.resize-handle{background-color:#000}.resize-handle-top.handle-active,.resize-handle-bottom.handle-active{cursor:row-resize}.resize-handle-left.handle-active,.resize-handle-right.handle-active{cursor:col-resize}.resize-handle-top,.resize-handle-bottom{position:absolute;height:5px;width:100%}.resize-handle-top{top:0}.resize-handle-bottom{bottom:0}.resize-handle-left,.resize-handle-right{position:absolute;height:100%;width:5px}.resize-handle-left{left:0;top:0}.resize-handle-right{right:0;top:0}\n"] }]
        }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: LoggingService }]; }, propDecorators: { keyInputEmitter: [{
                type: Output,
                args: ['keyInput']
            }], keyEventEmitter: [{
                type: Output,
                args: ['keyEvent']
            }], dataEmitter: [{
                type: Output,
                args: ['data']
            }], keyEmitter: [{
                type: Output,
                args: ['key']
            }], _dataSource: [{
                type: Input,
                args: ['dataSource']
            }], _rowsInput: [{
                type: Input,
                args: ['rows']
            }], _colsInput: [{
                type: Input,
                args: ['cols']
            }], _minWidthInput: [{
                type: Input,
                args: ['minWidth']
            }], _minHeightInput: [{
                type: Input,
                args: ['minHeight']
            }], draggable: [{
                type: Input,
                args: ['draggable']
            }], _xtermOptions: [{
                type: Input,
                args: ['xtermOptions']
            }], terminalOuter: [{
                type: ViewChild,
                args: ['terminal', { static: true }]
            }], resizeBox: [{
                type: ViewChild,
                args: ['resizeBox', { static: true }]
            }], detectBox: [{
                type: ViewChild,
                args: ['detectBox', { static: true }]
            }] } });

class NgTerminalModule {
    static forRoot(config) {
        return {
            ngModule: NgTerminalModule,
            providers: [
                { provide: ModuleOptions, useValue: config }
            ]
        };
    }
}
NgTerminalModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgTerminalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
NgTerminalModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: NgTerminalModule, declarations: [NgTerminalComponent, GlobalStyleComponent], imports: [ResizableModule, CommonModule], exports: [NgTerminalComponent] });
NgTerminalModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgTerminalModule, imports: [ResizableModule, CommonModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgTerminalModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [NgTerminalComponent, GlobalStyleComponent],
                    imports: [ResizableModule, CommonModule],
                    exports: [NgTerminalComponent],
                }]
        }] });

/**
 *
 * It is a CSI sequences generator
 * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Functions-using-CSI-_-ordered-by-the-final-character_s_
 */
let CSI = '\x9b';
class FunctionsUsingCSI {
    static get CSI() {
        return CSI;
    }
    /**
     *  CSI Ps @  Insert Ps (Blank) Character(s) (default = 1) (ICH).
     *
     * */
    static insertBlank(count) {
        return `${CSI}${count}@`;
    }
    /**
     *  CSI Ps SP @ */
    /**
     *  CSI Ps A  Cursor Up Ps Times (default = 1) (CUU).
     * \x9b3A */
    static cursorUp(count) {
        return `${CSI}${count}A`;
    }
    /**
     *  CSI Ps SP A */
    /**
     *  CSI Ps B  Cursor Down Ps Times (default = 1) (CUD).
     * \x9b3B */
    static cursorDown(count) {
        return `${CSI}${count}B`;
    }
    /**
     *  CSI Ps C  Cursor Forward Ps Times (default = 1) (CUF).
     * \x9b3C */
    static cursorForward(count) {
        return `${CSI}${count}C`;
    }
    /**
     *  CSI Ps D  Cursor Backward Ps Times (default = 1) (CUB).
     * \x9b3D */
    static cursorBackward(count) {
        return `${CSI}${count}D`;
    }
    /**
     *  CSI Ps E  Cursor Next Line Ps Times (default = 1) (CNL).
     * \x9b3E
     * */
    static cursorNextLine(count) {
        return `${CSI}${count}E`;
    }
    /**
     *  CSI Ps F  Cursor Preceding Line Ps Times (default = 1) (CPL).
     * \x9b3F
     *  */
    static cursorPrecedingLine(count) {
        return `${CSI}${count}F`;
    }
    /**
     *  CSI Ps G  Cursor Character Absolute  [column] (default = [row,1]) (CHA).
     *  \x9b9G
     *  */
    static cursorColumn(count) {
        return `${CSI}${count}G`;
    }
    /**
     *  CSI Ps ; Ps H  Cursor Position [row;column] (default = [1,1]) (CUP).
     * \x9b2;2H
     * */
    static cursorPosition(row, col) {
        return `${CSI}${row};${col}H`;
    }
    /**
     *  CSI Ps I  Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). */
    /**
     *  CSI Ps J  Erase in Display (ED), VT100.
     *      Ps = 0  -> Erase Below (default).
     *      Ps = 1  -> Erase Above.
     *      Ps = 2  -> Erase All.
     *      Ps = 3  -> Erase Saved Lines (xterm).
     * \x9b2J
     *  */
    static eraseInDisplay(category) {
        return `${CSI}${category}J`;
    }
    /**
     *  CSI ? Ps J
     *  Erase in Display (DECSED), VT220.
     *    Ps = 0  -> Selective Erase Below (default).
     *    Ps = 1  -> Selective Erase Above.
     *    Ps = 2  -> Selective Erase All.
     *    Ps = 3  -> Selective Erase Saved Lines (xterm).
     * \x9b?2J
     * */
    static eraseSelectiveThingsInDisplay(category) {
        return `${CSI}?${category}J`;
    }
    /**
     *  CSI Ps K
     *   Erase in Line (EL), VT100.
     *     Ps = 0  -> Erase to Right (default).
     *     Ps = 1  -> Erase to Left.
     *     Ps = 2  -> Erase All.
     * \x9b?1K
     * */
    static eraseInLine(category) {
        return `${CSI}${category}K`;
    }
    /**
     *  CSI ? Ps K
     *    Erase in Line (DECSEL), VT220.
     *      Ps = 0  -> Selective Erase to Right (default).
     *      Ps = 1  -> Selective Erase to Left.
     *      Ps = 2  -> Selective Erase All.
     * \x9b?1K
     * */
    static eraseSelectiveThingsInLine(category) {
        return `${CSI}?${category}K`;
    }
    /**
     *  CSI Ps L  Insert Ps Line(s) (default = 1) (IL).
     * \x9b2L
     *  */
    static insertLines(count) {
        return `${CSI}${count}L`;
    }
    /**
     *  CSI Ps M  Delete Ps Line(s) (default = 1) (DL).
     * \x9b2M
     *  */
    static deleteLines(count) {
        return `${CSI}${count}M`;
    }
    /**
     *  CSI Ps P  Delete Ps Character(s) (default = 1) (DCH).
     * \x9b2P
     *  */
    static deleteCharacter(count) {
        return `${CSI}${count}P`;
    }
    /**
     *  CSI Ps S  Scroll up Ps lines (default = 1) (SU), VT420, ECMA-48.
     * \x9b2S
     *  */
    static scrollUpLines(count) {
        return `${CSI}${count}S`;
    }
    /**
     *  CSI ? Pi ; Pa ; Pv S */
    /**
     *  CSI Ps T  Scroll down Ps lines (default = 1) (SD), VT420.
     * \x9b2T
     * */
    static scrollDownLines(count) {
        return `${CSI}${count}T`;
    }
    /**
     *  CSI Ps ; Ps ; Ps ; Ps ; Ps T */
    /**
     *  CSI > Ps ; Ps T */
    /**
     *  CSI Ps X  Erase Ps Character(s) (default = 1) (ECH).
     * \x9b2X
     *  */
    static eraseCharacters(count) {
        return `${CSI}${count}X`;
    }
    /**
     *  CSI Ps Z  Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).
     * \x9b2Z
     * */
    static cursorBackwardTabulationPstabstops(count) {
        return `${CSI}${count}Z`;
    }
    /**
     *  CSI Ps ^  Scroll down Ps lines (default = 1) (SD), ECMA-48.
     * \x9b2^
     * */
    static scrolldownPslines(count) {
        return `${CSI}${count}^`;
    }
    /**
     *  CSI Ps `  Character Position Absolute  [column] (default = [row,1])
     * \x9b1` */
    static characterPositionAbsolute(count) {
        return `${CSI}${count}\``;
    }
    /**
     *  CSI Ps a  Character Position Relative  [columns] (default = [row,col+1])
     * \x9b1a */
    static characterPositionRelative(count) {
        return `${CSI}${count}a`;
    }
    /**
     *  CSI Ps b  Repeat the preceding graphic character Ps times (REP).
     * \x9b1b
     * */
    static repeatThePrecedingGraphicCharacter(count) {
        return `${CSI}${count}b`;
    }
    /**
     *  CSI Pm d  Line Position Absolute  [row] (default = [1,column]) (VPA).
     * \x9b4d
     * */
    static linePositionAbsolute(count) {
        return `${CSI}${count}d`;
    }
    /**
     *  CSI Pm e  Line Position Relative  [rows] (default = [row+1,column])
     * \x9b1e
     * */
    static linePositionRelative(count) {
        return `${CSI}${count}e`;
    }
    /**
     *  CSI Ps ; Ps f  Horizontal and Vertical Position [row;column] (default =
     *       [1,1])
     * \x9b3;5f
     * */
    static horizontalandVerticalPosition(row, column) {
        return `${CSI}${row};${column}f`;
    }
    /**
     *  CSI Ps g  Tab Clear (TBC).
     * \x9b3g
     * */
    /**
     *  CSI Pm h  Set Mode (SM).
     *  \x9b4h
     *  */
    static setMode(mode, ...additionalModes) {
        const modes = [mode, ...(additionalModes !== null && additionalModes !== void 0 ? additionalModes : [])];
        return `${CSI}${modes.join(";")}h`;
    }
    /**
     *  CSI ? Pm h  DEC Private Mode Set (DECSET).
     * */
    /**
     *  CSI Pm i  Media Copy (MC). */
    /**
     *  CSI ? Pm i */
    /**
     *  CSI Pm l  Reset Mode (RM).
     * \x9b4l
     * */
    static resetMode(mode, ...additionalModes) {
        const modes = [mode, ...(additionalModes !== null && additionalModes !== void 0 ? additionalModes : [])];
        return `${CSI}${modes.join(";")}l`;
    }
    /**
     *  CSI ? Pm l */
    /**
     *  CSI Pm m  Character Attributes (SGR).
     * \x9b31m
     * */
    static characterAttributes(firstAttribute, ...additionalAttributes) {
        const chars = [
            firstAttribute,
            ...(additionalAttributes !== null && additionalAttributes !== void 0 ? additionalAttributes : []),
        ];
        return `${CSI}${chars.join(';')}m`;
    }
}
var KindOfEraseInDisplay;
(function (KindOfEraseInDisplay) {
    KindOfEraseInDisplay[KindOfEraseInDisplay["Below"] = 0] = "Below";
    KindOfEraseInDisplay[KindOfEraseInDisplay["Above"] = 1] = "Above";
    KindOfEraseInDisplay[KindOfEraseInDisplay["All"] = 2] = "All";
    KindOfEraseInDisplay[KindOfEraseInDisplay["SavedLines"] = 3] = "SavedLines";
})(KindOfEraseInDisplay || (KindOfEraseInDisplay = {}));
var KindOfEraseInLine;
(function (KindOfEraseInLine) {
    KindOfEraseInLine[KindOfEraseInLine["Right"] = 0] = "Right";
    KindOfEraseInLine[KindOfEraseInLine["Left"] = 1] = "Left";
    KindOfEraseInLine[KindOfEraseInLine["All"] = 2] = "All";
})(KindOfEraseInLine || (KindOfEraseInLine = {}));
var KindOfTabClear;
(function (KindOfTabClear) {
    KindOfTabClear[KindOfTabClear["ClearCurrentColumn"] = 0] = "ClearCurrentColumn";
    KindOfTabClear[KindOfTabClear["ClearAll"] = 3] = "ClearAll";
})(KindOfTabClear || (KindOfTabClear = {}));
var KindOfSetMode;
(function (KindOfSetMode) {
    KindOfSetMode[KindOfSetMode["KeyboardActionMode"] = 2] = "KeyboardActionMode";
    KindOfSetMode[KindOfSetMode["InsertMode"] = 4] = "InsertMode";
    KindOfSetMode[KindOfSetMode["SendReceive"] = 12] = "SendReceive";
    KindOfSetMode[KindOfSetMode["AutomaticNewline"] = 20] = "AutomaticNewline";
})(KindOfSetMode || (KindOfSetMode = {}));
var KindOfResetMode;
(function (KindOfResetMode) {
    KindOfResetMode[KindOfResetMode["KeyboardActionMode"] = 2] = "KeyboardActionMode";
    KindOfResetMode[KindOfResetMode["ReplaceMode"] = 4] = "ReplaceMode";
    KindOfResetMode[KindOfResetMode["SendReceive"] = 12] = "SendReceive";
    KindOfResetMode[KindOfResetMode["NormalNewline"] = 20] = "NormalNewline";
})(KindOfResetMode || (KindOfResetMode = {}));
var KindOfCharacterAttributes;
(function (KindOfCharacterAttributes) {
    KindOfCharacterAttributes[KindOfCharacterAttributes["Normal"] = 0] = "Normal";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Bold"] = 1] = "Bold";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Faint"] = 2] = "Faint";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Italicized"] = 3] = "Italicized";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Underlined"] = 4] = "Underlined";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Blink"] = 5] = "Blink";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Inverse"] = 7] = "Inverse";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Invisible"] = 8] = "Invisible";
    KindOfCharacterAttributes[KindOfCharacterAttributes["CrossedOutcharacters"] = 9] = "CrossedOutcharacters";
    KindOfCharacterAttributes[KindOfCharacterAttributes["DoublyUnderlined"] = 21] = "DoublyUnderlined";
    KindOfCharacterAttributes[KindOfCharacterAttributes["NormalNeitherBoldNorFaint"] = 22] = "NormalNeitherBoldNorFaint";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Notitalicized"] = 23] = "Notitalicized";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Notunderlined"] = 24] = "Notunderlined";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Steady"] = 25] = "Steady";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Positive"] = 27] = "Positive";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Visible"] = 28] = "Visible";
    KindOfCharacterAttributes[KindOfCharacterAttributes["NotcrossedOut"] = 29] = "NotcrossedOut";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetforegroundcolortoBlack"] = 30] = "SetforegroundcolortoBlack";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetforegroundcolortoRed"] = 31] = "SetforegroundcolortoRed";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetforegroundcolortoGreen"] = 32] = "SetforegroundcolortoGreen";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetforegroundcolortoYellow"] = 33] = "SetforegroundcolortoYellow";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetforegroundcolortoBlue"] = 34] = "SetforegroundcolortoBlue";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetforegroundcolortoMagenta"] = 35] = "SetforegroundcolortoMagenta";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetforegroundcolortoCyan"] = 36] = "SetforegroundcolortoCyan";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetforegroundcolortoWhite"] = 37] = "SetforegroundcolortoWhite";
    KindOfCharacterAttributes[KindOfCharacterAttributes["Setforegroundcolortodefault"] = 39] = "Setforegroundcolortodefault";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetbackgroundcolortoBlack"] = 40] = "SetbackgroundcolortoBlack";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetbackgroundcolortoRed"] = 41] = "SetbackgroundcolortoRed";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetbackgroundcolortoGreen"] = 42] = "SetbackgroundcolortoGreen";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetbackgroundcolortoYellow"] = 43] = "SetbackgroundcolortoYellow";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetbackgroundcolortoBlue"] = 44] = "SetbackgroundcolortoBlue";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetbackgroundcolortoMagenta"] = 45] = "SetbackgroundcolortoMagenta";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetbackgroundcolortoCyan"] = 46] = "SetbackgroundcolortoCyan";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetbackgroundcolortoWhite"] = 47] = "SetbackgroundcolortoWhite";
    KindOfCharacterAttributes[KindOfCharacterAttributes["SetbackgroundcolortoDefault"] = 49] = "SetbackgroundcolortoDefault";
})(KindOfCharacterAttributes || (KindOfCharacterAttributes = {}));

/*
 * Public API Surface of ng-terminal
 */

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

export { FunctionsUsingCSI, KindOfCharacterAttributes, KindOfEraseInDisplay, KindOfEraseInLine, KindOfResetMode, KindOfSetMode, KindOfTabClear, ModuleOptions, NgTerminalComponent, NgTerminalModule };
//# sourceMappingURL=ng-terminal.mjs.map