• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jcubic / jquery.terminal / 25376898073

05 May 2026 12:39PM UTC coverage: 82.944% (-0.3%) from 83.197%
25376898073

push

github

jcubic
update contributors

4912 of 6133 branches covered (80.09%)

5641 of 6801 relevant lines covered (82.94%)

15689.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.53
/js/unix_formatting.js
1
/**@license
2
 *       __ _____                     ________                              __
3
 *      / // _  /__ __ _____ ___ __ _/__  ___/__ ___ ______ __ __  __ ___  / /
4
 *  __ / // // // // // _  // _// // / / // _  // _//     // //  \/ // _ \/ /
5
 * /  / // // // // // ___// / / // / / // ___// / / / / // // /\  // // / /__
6
 * \___//____ \\___//____//_/ _\_  / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
7
 *           \/              /____/
8
 * http://terminal.jcubic.pl
9
 *
10
 * This is an example of how to create custom formatter for jQuery Terminal
11
 *
12
 * Copyright (c) 2014-2026 Jakub Jankiewicz <https://jcubic.pl/me>
13
 * Released under the MIT license
14
 *
15
 * Includes: node-ansiparser, MIT license, Copyright (c) 2014 Joerg Breitbart
16
 *
17
 * Last Update in jQuery Terminal 2.23.0
18
 *
19
 */
20
/* global define */
21
(function(factory) {
2✔
22
    var root;
23
    if (typeof window !== 'undefined') {
2!
24
        root = window;
2✔
25
    } else if (typeof self !== 'undefined') {
×
26
        root = self;
×
27
    } else if (typeof global !== 'undefined') {
×
28
        root = global;
×
29
    } else {
30
        throw new Error('Unknow context');
×
31
    }
32
    if (typeof define === 'function' && define.amd) {
2!
33
        // AMD. Register as an anonymous module.
34
        // istanbul ignore next
35
        define(['jquery', 'jquery.terminal'], factory);
36
    } else if (typeof module === 'object' && module.exports) {
2!
37
        // Node/CommonJS
38
        module.exports = function(root, jQuery) {
2✔
39
            if (jQuery === undefined) {
2!
40
                // require('jQuery') returns a factory that requires window to
41
                // build a jQuery instance, we normalize how we use modules
42
                // that require this pattern but the window provided is a noop
43
                // if it's defined (how jquery works)
44
                if (typeof window !== 'undefined') {
2!
45
                    jQuery = require('jquery');
2✔
46
                } else {
47
                    jQuery = require('jquery')(root);
×
48
                }
49
            }
50
            if (!jQuery.fn.terminal) {
2!
51
                if (typeof window !== 'undefined') {
×
52
                    require('jquery.terminal');
×
53
                } else {
54
                    require('jquery.terminal')(jQuery);
×
55
                }
56
            }
57
            factory(jQuery);
2✔
58
            return jQuery;
2✔
59
        };
60
    } else {
61
        // Browser
62
        // istanbul ignore next
63
        factory(root.jQuery);
64
    }
65
})(function($) {
66
    var DEBUG = false;
2✔
67
    /* eslint-disable */
68
    /* istanbul ignore next */
69
    function warn(str) {
70
        if ('warn' in console) {
71
            console.warn(str);
72
        }
73
    }
74
    function log(str) {
75
        if (DEBUG) {
×
76
            consoel.log(str);
×
77
        }
78
    }
79
    // node-ansiparser
80
    // The MIT License (MIT)
81
    // Copyright (c) 2014 Joerg Breitbart
82
    /* istanbul ignore next */
83
    var AnsiParser = (function () {
84
        'use strict';
85

86
        /**
87
         * range function for numbers [a, .., b-1]
88
         *
89
         * @param {number} a
90
         * @param {number} b
91
         * @return {Array}
92
         */
93
        function r(a, b) {
94
            var c = b - a;
95
            var arr = new Array(c);
96
            while (c--)
97
                arr[c] = --b;
98
            return arr;
99
        }
100

101
        /**
102
         * Add a transition to the transition table.
103
         *
104
         * @param table - table to add transition
105
         * @param {number} inp - input character code
106
         * @param {number} state - current state
107
         * @param {number=} action - action to be taken
108
         * @param {number=} next - next state
109
         */
110
        function add(table, inp, state, action, next) {
111
            table[state<<8|inp] = ((action | 0) << 4) | ((next === undefined) ? state : next);
112
        }
113

114
        /**
115
         * Add multiple transitions to the transition table.
116
         *
117
         * @param table - table to add transition
118
         * @param {Array} inps - array of input character codes
119
         * @param {number} state - current state
120
         * @param {number=} action - action to be taken
121
         * @param {number=} next - next state
122
         */
123
        function add_list(table, inps, state, action, next) {
124
            for (var i=0; i<inps.length; i++)
125
                add(table, inps[i], state, action, next);
126
        }
127

128
        /** global definition of printables and executables */
129
        var PRINTABLES = r(0x20, 0x7f);
130
        var EXECUTABLES = r(0x00, 0x18);
131
        EXECUTABLES.push(0x19);
132
        EXECUTABLES.push(0x1E);
133
        EXECUTABLES = EXECUTABLES.concat(r(0x1c, 0x20));
134

135
        /* meaning of state and action indices
136
           var STATES = [
137
           'GROUND',
138
           'ESCAPE',
139
           'ESCAPE_INTERMEDIATE',
140
           'CSI_ENTRY',
141
           'CSI_PARAM',
142
           'CSI_INTERMEDIATE',
143
           'CSI_IGNORE',
144
           'SOS_PM_APC_STRING',
145
           'OSC_STRING',
146
           'DCS_ENTRY',
147
           'DCS_PARAM',
148
           'DCS_IGNORE',
149
           'DCS_INTERMEDIATE',
150
           'DCS_PASSTHROUGH'
151
           ];
152
           var ACTIONS = [
153
           'ignore',
154
           'error',
155
           'print',
156
           'execute',
157
           'osc_start',
158
           'osc_put',
159
           'osc_end',
160
           'csi_dispatch',
161
           'param',
162
           'collect',
163
           'esc_dispatch',
164
           'clear',
165
           'dcs_hook',
166
           'dcs_put',
167
           'dcs_unhook'
168
           ];
169
        */
170

171
        /**
172
         * create the standard transition table - used by all parser instances
173
         *
174
         *     table[state << 8 | character code] = action << 4 | next state
175
         *
176
         *     - states are indices of STATES (0 to 13)
177
         *     - control character codes defined from 0 to 159 (C0 and C1)
178
         *     - actions are indices of ACTIONS (0 to 14)
179
         *     - any higher character than 159 is handled by the 'error' action
180
         */
181
        var TRANSITION_TABLE = (function() {
182
            var t = new Uint8Array(4095);
183

184
            // table with default transition [any] --> [error, GROUND]
185
            for (var state=0; state<14; ++state) {
186
                for (var code=0; code<160; ++code) {
187
                    t[state<<8|code] = 16;
188
                }
189
            }
190

191
            // apply transitions
192
            // printables
193
            add_list(t, PRINTABLES, 0, 2);
194
            // global anywhere rules
195
            for (state=0; state<14; ++state) {
196
                add_list(t, [0x18, 0x1a, 0x99, 0x9a], state, 3, 0);
197
                add_list(t, r(0x80, 0x90), state, 3, 0);
198
                add_list(t, r(0x90, 0x98), state, 3, 0);
199
                add(t, 0x9c, state, 0, 0);   // ST as terminator
200
                add(t, 0x1b, state, 11, 1);  // ESC
201
                add(t, 0x9d, state, 4, 8);   // OSC
202
                add_list(t, [0x98, 0x9e, 0x9f], state, 0, 7);
203
                add(t, 0x9b, state, 11, 3);  // CSI
204
                add(t, 0x90, state, 11, 9);  // DCS
205
            }
206
            // rules for executables and 7f
207
            add_list(t, EXECUTABLES, 0, 3);
208
            add_list(t, EXECUTABLES, 1, 3);
209
            add(t, 0x7f, 1);
210
            add_list(t, EXECUTABLES, 8);
211
            add_list(t, EXECUTABLES, 3, 3);
212
            add(t, 0x7f, 3);
213
            add_list(t, EXECUTABLES, 4, 3);
214
            add(t, 0x7f, 4);
215
            add_list(t, EXECUTABLES, 6, 3);
216
            add_list(t, EXECUTABLES, 5, 3);
217
            add(t, 0x7f, 5);
218
            add_list(t, EXECUTABLES, 2, 3);
219
            add(t, 0x7f, 2);
220
            // osc
221
            add(t, 0x5d, 1, 4, 8);
222
            add_list(t, PRINTABLES, 8, 5);
223
            add(t, 0x7f, 8, 5);
224
            add_list(t, [0x9c, 0x1b, 0x18, 0x1a, 0x07], 8, 6, 0);
225
            add_list(t, r(0x1c, 0x20), 8, 0);
226
            // sos/pm/apc does nothing
227
            add_list(t, [0x58, 0x5e, 0x5f], 1, 0, 7);
228
            add_list(t, PRINTABLES, 7);
229
            add_list(t, EXECUTABLES, 7);
230
            add(t, 0x9c, 7, 0, 0);
231
            // csi entries
232
            add(t, 0x5b, 1, 11, 3);
233
            add_list(t, r(0x40, 0x7f), 3, 7, 0);
234
            add_list(t, r(0x30, 0x3a), 3, 8, 4);
235
            add(t, 0x3b, 3, 8, 4);
236
            add_list(t, [0x3c, 0x3d, 0x3e, 0x3f], 3, 9, 4);
237
            add_list(t, r(0x30, 0x3a), 4, 8);
238
            add(t, 0x3b, 4, 8);
239
            add_list(t, r(0x40, 0x7f), 4, 7, 0);
240
            add_list(t, [0x3a, 0x3c, 0x3d, 0x3e, 0x3f], 4, 0, 6);
241
            add_list(t, r(0x20, 0x40), 6);
242
            add(t, 0x7f, 6);
243
            add_list(t, r(0x40, 0x7f), 6, 0, 0);
244
            add(t, 0x3a, 3, 0, 6);
245
            add_list(t, r(0x20, 0x30), 3, 9, 5);
246
            add_list(t, r(0x20, 0x30), 5, 9);
247
            add_list(t, r(0x30, 0x40), 5, 0, 6);
248
            add_list(t, r(0x40, 0x7f), 5, 7, 0);
249
            add_list(t, r(0x20, 0x30), 4, 9, 5);
250
            // esc_intermediate
251
            add_list(t, r(0x20, 0x30), 1, 9, 2);
252
            add_list(t, r(0x20, 0x30), 2, 9);
253
            add_list(t, r(0x30, 0x7f), 2, 10, 0);
254
            add_list(t, r(0x30, 0x50), 1, 10, 0);
255
            add_list(t, [0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x59, 0x5a, 0x5c], 1, 10, 0);
256
            add_list(t, r(0x60, 0x7f), 1, 10, 0);
257
            // dcs entry
258
            add(t, 0x50, 1, 11, 9);
259
            add_list(t, EXECUTABLES, 9);
260
            add(t, 0x7f, 9);
261
            add_list(t, r(0x1c, 0x20), 9);
262
            add_list(t, r(0x20, 0x30), 9, 9, 12);
263
            add(t, 0x3a, 9, 0, 11);
264
            add_list(t, r(0x30, 0x3a), 9, 8, 10);
265
            add(t, 0x3b, 9, 8, 10);
266
            add_list(t, [0x3c, 0x3d, 0x3e, 0x3f], 9, 9, 10);
267
            add_list(t, EXECUTABLES, 11);
268
            add_list(t, r(0x20, 0x80), 11);
269
            add_list(t, r(0x1c, 0x20), 11);
270
            add_list(t, EXECUTABLES, 10);
271
            add(t, 0x7f, 10);
272
            add_list(t, r(0x1c, 0x20), 10);
273
            add_list(t, r(0x30, 0x3a), 10, 8);
274
            add(t, 0x3b, 10, 8);
275
            add_list(t, [0x3a, 0x3c, 0x3d, 0x3e, 0x3f], 10, 0, 11);
276
            add_list(t, r(0x20, 0x30), 10, 9, 12);
277
            add_list(t, EXECUTABLES, 12);
278
            add(t, 0x7f, 12);
279
            add_list(t, r(0x1c, 0x20), 12);
280
            add_list(t, r(0x20, 0x30), 12, 9);
281
            add_list(t, r(0x30, 0x40), 12, 0, 11);
282
            add_list(t, r(0x40, 0x7f), 12, 12, 13);
283
            add_list(t, r(0x40, 0x7f), 10, 12, 13);
284
            add_list(t, r(0x40, 0x7f), 9, 12, 13);
285
            add_list(t, EXECUTABLES, 13, 13);
286
            add_list(t, PRINTABLES, 13, 13);
287
            add(t, 0x7f, 13);
288
            add_list(t, [0x1b, 0x9c], 13, 14, 0);
289

290
            return t;
291
        })();
292

293

294
        /**
295
         *  AnsiParser - Parser for ANSI terminal escape sequences.
296
         *
297
         * @param {Object=} terminal emulation object
298
         * @constructor
299
         */
300
        function AnsiParser(terminal) {
301
            this.initial_state = 0;  // 'GROUND' is default
302
            this.current_state = this.initial_state|0;
303

304
            // clone global transition table
305
            this.transitions = new Uint8Array(4095);
306
            this.transitions.set(TRANSITION_TABLE);
307

308
            // global non pushable buffers for multiple parse invocations
309
            this.osc = '';
310
            this.params = [0];
311
            this.collected = '';
312

313
            // back reference to terminal
314
            this.term = terminal || {};
315
            var instructions = ['inst_p', 'inst_o', 'inst_x', 'inst_c',
316
                                'inst_e', 'inst_H', 'inst_P', 'inst_U', 'inst_E'];
317
            for (var i=0; i<instructions.length; ++i)
318
                if (!(instructions[i] in this.term))
319
                    this.term[instructions[i]] = function() {};
320
        }
321

322
        /**
323
         * Reset the parser.
324
         */
325
        AnsiParser.prototype.reset = function() {
326
            this.current_state = this.initial_state|0;
327
            this.osc = '';
328
            this.params = [0];
329
            this.collected = '';
330
        };
331

332
        /**
333
         * Parse string s.
334
         * @param {string} s
335
         */
336
        AnsiParser.prototype.parse = function(s) {
337
            var code = 0,
338
                transition = 0,
339
                error = false,
340
                current_state = this.current_state|0;
341

342
            // local buffers
343
            var printed = -1;
344
            var dcs = -1;
345
            var osc = this.osc;
346
            var collected = this.collected;
347
            var params = this.params;
348

349
            // process input string
350
            for (var i=0, l=s.length|0; i<l; ++i) {
351
                code = s.charCodeAt(i)|0;
352
                // shortcut for most chars (print action)
353
                if (current_state===0 && code>0x1f && code<0x80) {
354
                    printed = (printed + 1) ? printed|0: i|0;
355
                    continue;
356
                }
357
                transition = ((code < 0xa0) ? (this.transitions[(current_state<<8|code)|0])|0 : 16)|0;
358
                switch ((transition >> 4)|0) {
359
                    case 2: // print
360
                        printed = (printed + 1) ? printed|0: i|0;
361
                        break;
362
                    case 3: // execute
363
                        if (printed + 1) {
364
                            this.term.inst_p(s.substring(printed, i));
365
                            printed = -1;
366
                        }
367
                        this.term.inst_x(String.fromCharCode(code));
368
                        break;
369
                    case 0: // ignore
370
                        // handle leftover print and dcs chars
371
                        if (printed + 1) {
372
                            this.term.inst_p(s.substring(printed, i));
373
                            printed = -1;
374
                        } else if (dcs + 1) {
375
                            this.term.inst_P(s.substring(dcs, i));
376
                            dcs = -1;
377
                        }
378
                        break;
379
                    case 1: // error
380
                        // handle unicode chars in write buffers w'o state change
381
                        if (code > 0x9f) {
382
                            switch (current_state) {
383
                                case 0: // GROUND -> add char to print string
384
                                    printed = (!(printed+1)) ? i|0 : printed|0;
385
                                    break;
386
                                case 8: // OSC_STRING -> add char to osc string
387
                                    osc += String.fromCharCode(code);
388
                                    transition = (transition | 8)|0;
389
                                    break;
390
                                case 6: // CSI_IGNORE -> ignore char
391
                                    transition = (transition | 6)|0;
392
                                    break;
393
                                case 11: // DCS_IGNORE -> ignore char
394
                                    transition = (transition | 11)|0;
395
                                    break;
396
                                case 13: // DCS_PASSTHROUGH -> add char to dcs
397
                                    if (!(dcs + 1))
398
                                        dcs = i|0;
399
                                    transition = (transition | 13)|0;
400
                                    break;
401
                                default: // real error
402
                                    error = true;
403
                            }
404
                        } else { // real error
405
                            error = true;
406
                        }
407
                        if (error) {
408
                            if (this.term.inst_E(
409
                                {
410
                                    pos: i,                 // position in parse string
411
                                    character: String.fromCharCode(code), // wrong character
412
                                    state: current_state,   // in state
413
                                    print: printed,         // print buffer
414
                                    dcs: dcs,               // dcs buffer
415
                                    osc: osc,               // osc buffer
416
                                    collect: collected,     // collect buffer
417
                                    params: params          // params buffer
418
                                })) {
419
                                return;
420
                            }
421
                            error = false;
422
                        }
423
                        break;
424
                    case 7: // csi_dispatch
425
                        this.term.inst_c(collected, params, String.fromCharCode(code));
426
                        break;
427
                    case 8: // param
428
                        if (code === 0x3b)
429
                            params.push(0);
430
                        else
431
                            params[params.length-1] = (params[params.length-1] * 10 + code - 48)|0;
432
                        break;
433
                    case 9: // collect
434
                        collected += String.fromCharCode(code);
435
                        break;
436
                    case 10: // esc_dispatch
437
                        this.term.inst_e(collected, String.fromCharCode(code));
438
                        break;
439
                    case 11: // clear
440
                        if (printed + 1) {
441
                            this.term.inst_p(s.substring(printed, i));
442
                            printed = -1;
443
                        }
444
                        osc = '';
445
                        params = [0];
446
                        collected = '';
447
                        dcs = -1;
448
                        break;
449
                    case 12: // dcs_hook
450
                        this.term.inst_H(collected, params, String.fromCharCode(code));
451
                        break;
452
                    case 13: // dcs_put
453
                        if (!(dcs + 1))
454
                            dcs = i|0;
455
                        break;
456
                    case 14: // dcs_unhook
457
                        if (dcs + 1) {
458
                            this.term.inst_P(s.substring(dcs, i));
459
                        }
460
                        this.term.inst_U();
461
                        if (code === 0x1b)
462
                            transition = (transition | 1)|0;
463
                        osc = '';
464
                        params = [0];
465
                        collected = '';
466
                        dcs = -1;
467
                        break;
468
                    case 4: // osc_start
469
                        if (~printed) {
470
                            this.term.inst_p(s.substring(printed, i));
471
                            printed = -1;
472
                        }
473
                        osc = '';
474
                        break;
475
                    case 5: // osc_put
476
                        osc += s.charAt(i);
477
                        break;
478
                    case 6: // osc_end
479
                        if (osc && code !== 0x18 && code !== 0x1a)
480
                            this.term.inst_o(osc);
481
                        if (code === 0x1b)
482
                            transition = (transition | 1)|0;
483
                        osc = '';
484
                        params = [0];
485
                        collected = '';
486
                        dcs = -1;
487
                        break;
488
                }
489
                current_state = (transition & 15)|0;
490
            }
491

492
            // push leftover pushable buffers to terminal
493
            if (!current_state && (printed + 1)) {
494
                this.term.inst_p(s.substring(printed));
495
            } else if (current_state===13 && (dcs + 1)) {
496
                this.term.inst_P(s.substring(dcs));
497
            }
498

499
            // save non pushable buffers
500
            this.osc = osc;
501
            this.collected = collected;
502
            this.params = params;
503

504
            // save state
505
            this.current_state = current_state|0;
506
        };
507
        return AnsiParser;
508
    })();
509
    /* eslint-enable */
510
    // ---------------------------------------------------------------------
511
    $.terminal.AnsiParser = AnsiParser;
2✔
512
    // ---------------------------------------------------------------------
513
    // we match characters and html entities because command line escape brackets
514
    // echo don't, when writing formatter always process html entitites so it work
515
    // for cmd plugin as well for echo
516
    var chr = '[^\\x08]|[\\r\\n]{2}|&[^;]+;';
2✔
517
    var backspace_re = new RegExp('^(' + chr + ')?\\x08');
2✔
518
    var overtyping_re = new RegExp('^(?:(' + chr + ')?\\x08(_|\\1)|' +
2✔
519
                                   '(_)\\x08(' + chr + '))');
520
    var new_line_re = /^(\r\n|\n\r|\r|\n)/;
2✔
521
    var clear_line_re = /[^\r\n]+\r\x1B\[K/g;
2✔
522
    // ---------------------------------------------------------------------
523
    function length(string) {
524
        return $.terminal.length(string);
21,622✔
525
    }
526
    // ---------------------------------------------------------------------
527
    function get_settings(options) {
528
        var unixFormatting = {
12,974✔
529
            escapeBrackets: false,
530
            ansiParser: {},
531
            position: 0,
532
            ansiArt: false
533
        };
534
        if (options) {
12,974✔
535
            if (options.unixFormatting) {
12,962✔
536
                $.extend(unixFormatting, options.unixFormatting);
2,812✔
537
            }
538
            if ('position' in options) {
12,962✔
539
                unixFormatting.position = options.position;
12,944✔
540
            }
541
            if ('unixFormattingEscapeBrackets' in options) {
12,962✔
542
                unixFormatting.escapeBrackets = options.unixFormattingEscapeBrackets;
4,318✔
543
            }
544
            if ('ansiParser' in options) {
12,962!
545
                unixFormatting.ansiParser = options.ansiParser;
×
546
            }
547
        }
548
        return unixFormatting;
12,974✔
549
    }
550
    // ---------------------------------------------------------------------
551
    // :: Replace overtyping (from man) formatting with terminal formatting
552
    // ---------------------------------------------------------------------
553
    $.terminal.overtyping = function overtyping(string, options) {
2✔
554
        string = $.terminal.unescape_brackets(string);
6,484✔
555
        var settings = get_settings(options);
6,484✔
556
        var removed_chars = [];
6,484✔
557
        var new_position;
558
        var char_count = 0;
6,484✔
559
        var backspaces = [];
6,484✔
560
        function replace(string, position) {
561
            var result = '';
9,504✔
562
            var push = 0;
9,504✔
563
            var start;
564
            char_count = 0;
9,504✔
565
            function correct_position(start, match, rep_string) {
566
                // logic taken from $.terminal.tracking_replace
567
                if (start < position) {
10,136✔
568
                    var last_index = start + length(match);
7,254✔
569
                    if (last_index < position) {
7,254✔
570
                        // It's after the replacement, move it
571
                        new_position = Math.max(
7,114✔
572
                            0,
573
                            new_position +
574
                            length(rep_string) -
575
                            length(match)
576
                        );
577
                    } else {
578
                        // It's *in* the replacement, put it just after
579
                        new_position += length(rep_string) - (position - start);
140✔
580
                    }
581
                }
582
            }
583
            for (var i = 0; i < string.length; ++i) {
9,504✔
584
                var partial = string.substring(i);
646,956✔
585
                var match = partial.match(backspace_re);
646,956✔
586
                var removed_char = removed_chars[0];
646,956✔
587
                if (match) {
646,956✔
588
                    // we remove backspace and character or html entity before it
589
                    // but we keep it in removed array so we can put it back
590
                    // when we have caritage return or line feed
591
                    if (match[1]) {
8,908!
592
                        start = i - match[1].length + push;
8,908✔
593
                        removed_chars.push({
8,908✔
594
                            index: start,
595
                            string: match[1],
596
                            overtyping: partial.match(overtyping_re)
597
                        });
598
                        correct_position(start, match[0], '');
8,908✔
599
                    }
600
                    if (char_count < 0) {
8,908!
601
                        char_count = 0;
×
602
                    }
603
                    backspaces = backspaces.map(function(b) {
8,908✔
604
                        return b - 1;
25,812✔
605
                    });
606
                    backspaces.push(start);
8,908✔
607
                    return result + partial.replace(backspace_re, '');
8,908✔
608
                } else if (partial.match(new_line_re)) {
638,048✔
609
                    // if newline we need to add at the end all characters
610
                    // removed by backspace but only if there are no more
611
                    // other characters than backspaces added between
612
                    // backspaces and newline
613
                    if (removed_chars.length) {
41,036✔
614
                        var chars = removed_chars;
36,934✔
615
                        removed_chars = [];
36,934✔
616
                        chars.reverse().forEach(function(char) {
36,934✔
617
                            if (i > char.index) {
114,330✔
618
                                if (--char_count <= 0) {
8,820✔
619
                                    correct_position(char.index, '', char.string);
1,176✔
620
                                    result += char.string;
1,176✔
621
                                }
622
                            } else {
623
                                removed_chars.unshift(char);
105,510✔
624
                            }
625
                        });
626
                    }
627
                    var m = partial.match(new_line_re);
41,036✔
628
                    result += m[1];
41,036✔
629
                    i += m[1].length - 1;
41,036✔
630
                } else {
631
                    if (backspaces.length) {
597,012✔
632
                        var backspace = backspaces[0];
567,616✔
633
                        if (i === backspace) {
567,616✔
634
                            backspaces.shift();
7,054✔
635
                        }
636
                        if (i >= backspace) {
567,616✔
637
                            char_count++;
98,874✔
638
                        }
639
                    }
640
                    if (removed_chars.length) {
597,012✔
641
                        // if we are in index of removed character we check if the
642
                        // character is the same it will be bold or if removed char
643
                        // or char at index is underscore then it will
644
                        // be terminal formatting with underscore
645
                        if (i > removed_char.index && removed_char.overtyping) {
534,184✔
646
                            removed_chars.shift();
52✔
647
                            correct_position(removed_char.index, '', removed_char.string);
52✔
648
                            // if we add special character we need to correct
649
                            // next push to removed_char array
650
                            push++;
52✔
651
                            // we use special characters instead of terminal
652
                            // formatting so it's easier to proccess when removing
653
                            // backspaces
654
                            if (removed_char.string === string[i]) {
52✔
655
                                result += string[i] + '\uFFF1';
26✔
656
                                continue;
26✔
657
                            } else if (removed_char.string === '_' ||
26!
658
                                       string[i] === '_') {
659
                                var chr;
660
                                if (removed_char.string === '_') {
26!
661
                                    chr = string[i];
×
662
                                } else {
663
                                    chr = removed_char.string;
26✔
664
                                }
665
                                result += chr + '\uFFF2';
26✔
666
                                continue;
26✔
667
                            }
668
                        }
669
                    }
670
                    result += string[i];
596,960✔
671
                }
672
            }
673
            return result;
596✔
674
        }
675
        var break_next = false;
6,484✔
676
        // loop until not more backspaces
677
        new_position = settings.position;
6,484✔
678
        // we need to clear line \x1b[K in overtyping because it need to be before
679
        // overtyping and from_ansi need to be called after so it escape stuff
680
        // between Escape Code and cmd will have escaped formatting typed by user
681
        var rep = $.terminal.tracking_replace(string, clear_line_re, '', new_position);
6,484✔
682
        string = rep[0];
6,484✔
683
        new_position = rep[1];
6,484✔
684
        while (string.match(/\x08/) || removed_chars.length) {
6,484✔
685
            string = replace(string, new_position);
9,504✔
686
            if (break_next) {
9,504✔
687
                break;
596✔
688
            }
689
            if (!string.match(/\x08/)) {
8,908✔
690
                // we break the loop so if removed_chars still chave items
691
                // we don't have infite loop
692
                break_next = true;
596✔
693
            }
694
        }
695
        function format(string, chr, style) {
696
            var re = new RegExp('((:?.' + chr + ')+)', 'g');
12,968✔
697
            return string.replace(re, function(_, string) {
12,968✔
698
                var re = new RegExp(chr, 'g');
8✔
699
                return '[[' + style + ']' + string.replace(re, '') + ']';
8✔
700
            });
701
        }
702
        // replace special characters with terminal formatting
703
        string = format(string, '\uFFF1', 'b;#fff;');
6,484✔
704
        string = format(string, '\uFFF2', 'u;;');
6,484✔
705
        if (settings.escapeBrackets) {
6,484✔
706
            string = $.terminal.escape_brackets(string);
2,158✔
707
        }
708
        if (options && typeof options.position === 'number') {
6,484✔
709
            return [string, new_position];
6,472✔
710
        }
711
        return string;
12✔
712
    };
713
    var CHARSETS = {};
2✔
714
    // taken from xterm.js MIT License
715
    // see https://github.com/xtermjs/xterm.js for more details
716
    CHARSETS['0'] = {
2✔
717
        '`': '\u25c6', // '◆'
718
        'a': '\u2592', // '▒'
719
        'b': '\u2409', // (HT)
720
        'c': '\u240c', // (FF)
721
        'd': '\u240d', // (CR)
722
        'e': '\u240a', // (LF)
723
        'f': '\u00b0', // '°'
724
        'g': '\u00b1', // '±'
725
        'h': '\u2424', // (NL)
726
        'i': '\u240b', // (VT)
727
        'j': '\u2518', // '┘'
728
        'k': '\u2510', // '┐'
729
        'l': '\u250c', // '┌'
730
        'm': '\u2514', // '└'
731
        'n': '\u253c', // '┼'
732
        'o': '\u23ba', // '⎺'
733
        'p': '\u23bb', // '⎻'
734
        'q': '\u2500', // '─'
735
        'r': '\u23bc', // '⎼'
736
        's': '\u23bd', // '⎽'
737
        't': '\u251c', // '├'
738
        'u': '\u2524', // '┤'
739
        'v': '\u2534', // '┴'
740
        'w': '\u252c', // '┬'
741
        'x': '\u2502', // '│'
742
        'y': '\u2264', // '≤'
743
        'z': '\u2265', // '≥'
744
        '{': '\u03c0', // 'π'
745
        '|': '\u2260', // '≠'
746
        '}': '\u00a3', // '£'
747
        '~': '\u00b7' // '·'
748
    };
749

750
    /**
751
     * British character set
752
     * ESC (A
753
     * Reference: http://vt100.net/docs/vt220-rm/table2-5.html
754
     */
755
    CHARSETS['A'] = {
2✔
756
        '#': '£'
757
    };
758

759
    /**
760
     * United States character set
761
     * ESC (B
762
     */
763
    CHARSETS['B'] = null;
2✔
764

765
    /**
766
     * Dutch character set
767
     * ESC (4
768
     * Reference: http://vt100.net/docs/vt220-rm/table2-6.html
769
     */
770
    CHARSETS['4'] = {
2✔
771
        '#': '£',
772
        '@': '¾',
773
        '[': 'ij',
774
        '\\': '½',
775
        ']': '|',
776
        '{': '¨',
777
        '|': 'f',
778
        '}': '¼',
779
        '~': '´'
780
    };
781

782
    /**
783
     * Finnish character set
784
     * ESC (C or ESC (5
785
     * Reference: http://vt100.net/docs/vt220-rm/table2-7.html
786
     */
787
    CHARSETS['C'] = CHARSETS['5'] = {
2✔
788
        '[': 'Ä',
789
        '\\': 'Ö',
790
        ']': 'Å',
791
        '^': 'Ü',
792
        '`': 'é',
793
        '{': 'ä',
794
        '|': 'ö',
795
        '}': 'å',
796
        '~': 'ü'
797
    };
798

799
    /**
800
     * French character set
801
     * ESC (R
802
     * Reference: http://vt100.net/docs/vt220-rm/table2-8.html
803
     */
804
    CHARSETS['R'] = {
2✔
805
        '#': '£',
806
        '@': 'à',
807
        '[': '°',
808
        '\\': 'ç',
809
        ']': '§',
810
        '{': 'é',
811
        '|': 'ù',
812
        '}': 'è',
813
        '~': '¨'
814
    };
815

816
    /**
817
     * French Canadian character set
818
     * ESC (Q
819
     * Reference: http://vt100.net/docs/vt220-rm/table2-9.html
820
     */
821
    CHARSETS['Q'] = {
2✔
822
        '@': 'à',
823
        '[': 'â',
824
        '\\': 'ç',
825
        ']': 'ê',
826
        '^': 'î',
827
        '`': 'ô',
828
        '{': 'é',
829
        '|': 'ù',
830
        '}': 'è',
831
        '~': 'û'
832
    };
833

834
    /**
835
     * German character set
836
     * ESC (K
837
     * Reference: http://vt100.net/docs/vt220-rm/table2-10.html
838
     */
839
    CHARSETS['K'] = {
2✔
840
        '@': '§',
841
        '[': 'Ä',
842
        '\\': 'Ö',
843
        ']': 'Ü',
844
        '{': 'ä',
845
        '|': 'ö',
846
        '}': 'ü',
847
        '~': 'ß'
848
    };
849

850
    /**
851
     * Italian character set
852
     * ESC (Y
853
     * Reference: http://vt100.net/docs/vt220-rm/table2-11.html
854
     */
855
    CHARSETS['Y'] = {
2✔
856
        '#': '£',
857
        '@': '§',
858
        '[': '°',
859
        '\\': 'ç',
860
        ']': 'é',
861
        '`': 'ù',
862
        '{': 'à',
863
        '|': 'ò',
864
        '}': 'è',
865
        '~': 'ì'
866
    };
867

868
    /**
869
     * Norwegian/Danish character set
870
     * ESC (E or ESC (6
871
     * Reference: http://vt100.net/docs/vt220-rm/table2-12.html
872
     */
873
    CHARSETS['E'] =
2✔
874
        CHARSETS['6'] = {
875
            '@': 'Ä',
876
            '[': 'Æ',
877
            '\\': 'Ø',
878
            ']': 'Å',
879
            '^': 'Ü',
880
            '`': 'ä',
881
            '{': 'æ',
882
            '|': 'ø',
883
            '}': 'å',
884
            '~': 'ü'
885
        };
886

887
    /**
888
     * Spanish character set
889
     * ESC (Z
890
     * Reference: http://vt100.net/docs/vt220-rm/table2-13.html
891
     */
892
    CHARSETS['Z'] = {
2✔
893
        '#': '£',
894
        '@': '§',
895
        '[': '¡',
896
        '\\': 'Ñ',
897
        ']': '¿',
898
        '{': '°',
899
        '|': 'ñ',
900
        '}': 'ç'
901
    };
902

903
    /**
904
     * Swedish character set
905
     * ESC (H or ESC (7
906
     * Reference: http://vt100.net/docs/vt220-rm/table2-14.html
907
     */
908
    CHARSETS['H'] =
2✔
909
        CHARSETS['7'] = {
910
            '@': 'É',
911
            '[': 'Ä',
912
            '\\': 'Ö',
913
            ']': 'Å',
914
            '^': 'Ü',
915
            '`': 'é',
916
            '{': 'ä',
917
            '|': 'ö',
918
            '}': 'å',
919
            '~': 'ü'
920
        };
921

922
    /**
923
     * Swiss character set
924
     * ESC (=
925
     * Reference: http://vt100.net/docs/vt220-rm/table2-15.html
926
     */
927
    CHARSETS['='] = {
2✔
928
        '#': 'ù',
929
        '@': 'à',
930
        '[': 'é',
931
        '\\': 'ç',
932
        ']': 'ê',
933
        '^': 'î',
934
        '_': 'è',
935
        '`': 'ô',
936
        '{': 'ä',
937
        '|': 'ö',
938
        '}': 'ü',
939
        '~': 'û'
940
    };
941
    // ---------------------------------------------------------------------
942
    // :: Html colors taken from ANSI formatting in Linux Terminal
943
    // ---------------------------------------------------------------------
944
    $.terminal.ansi_colors = {
2✔
945
        normal: {
946
            black: '#000',
947
            red: '#A00',
948
            green: '#008400',
949
            yellow: '#A50',
950
            blue: '#00A',
951
            magenta: '#A0A',
952
            cyan: '#0AA',
953
            white: '#AAA'
954
        },
955
        faited: {
956
            black: '#000',
957
            red: '#640000',
958
            green: '#006100',
959
            yellow: '#737300',
960
            blue: '#000087',
961
            magenta: '#650065',
962
            cyan: '#008787',
963
            white: '#818181'
964
        },
965
        bold: {
966
            black: '#555',
967
            red: '#F55',
968
            green: '#44D544',
969
            yellow: '#FF5',
970
            blue: '#55F',
971
            magenta: '#F5F',
972
            cyan: '#5FF',
973
            white: '#FFF'
974
        },
975
        // XTerm 8-bit pallete
976
        palette: [
977
            '#000000', '#AA0000', '#00AA00', '#AA5500', '#0000AA', '#AA00AA',
978
            '#00AAAA', '#AAAAAA', '#555555', '#FF5555', '#55FF55', '#FFFF55',
979
            '#5555FF', '#FF55FF', '#55FFFF', '#FFFFFF', '#000000', '#00005F',
980
            '#000087', '#0000AF', '#0000D7', '#0000FF', '#005F00', '#005F5F',
981
            '#005F87', '#005FAF', '#005FD7', '#005FFF', '#008700', '#00875F',
982
            '#008787', '#0087AF', '#0087D7', '#0087FF', '#00AF00', '#00AF5F',
983
            '#00AF87', '#00AFAF', '#00AFD7', '#00AFFF', '#00D700', '#00D75F',
984
            '#00D787', '#00D7AF', '#00D7D7', '#00D7FF', '#00FF00', '#00FF5F',
985
            '#00FF87', '#00FFAF', '#00FFD7', '#00FFFF', '#5F0000', '#5F005F',
986
            '#5F0087', '#5F00AF', '#5F00D7', '#5F00FF', '#5F5F00', '#5F5F5F',
987
            '#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF', '#5F8700', '#5F875F',
988
            '#5F8787', '#5F87AF', '#5F87D7', '#5F87FF', '#5FAF00', '#5FAF5F',
989
            '#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF', '#5FD700', '#5FD75F',
990
            '#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF', '#5FFF00', '#5FFF5F',
991
            '#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF', '#870000', '#87005F',
992
            '#870087', '#8700AF', '#8700D7', '#8700FF', '#875F00', '#875F5F',
993
            '#875F87', '#875FAF', '#875FD7', '#875FFF', '#878700', '#87875F',
994
            '#878787', '#8787AF', '#8787D7', '#8787FF', '#87AF00', '#87AF5F',
995
            '#87AF87', '#87AFAF', '#87AFD7', '#87AFFF', '#87D700', '#87D75F',
996
            '#87D787', '#87D7AF', '#87D7D7', '#87D7FF', '#87FF00', '#87FF5F',
997
            '#87FF87', '#87FFAF', '#87FFD7', '#87FFFF', '#AF0000', '#AF005F',
998
            '#AF0087', '#AF00AF', '#AF00D7', '#AF00FF', '#AF5F00', '#AF5F5F',
999
            '#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF', '#AF8700', '#AF875F',
1000
            '#AF8787', '#AF87AF', '#AF87D7', '#AF87FF', '#AFAF00', '#AFAF5F',
1001
            '#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF', '#AFD700', '#AFD75F',
1002
            '#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF', '#AFFF00', '#AFFF5F',
1003
            '#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF', '#D70000', '#D7005F',
1004
            '#D70087', '#D700AF', '#D700D7', '#D700FF', '#D75F00', '#D75F5F',
1005
            '#D75F87', '#D75FAF', '#D75FD7', '#D75FFF', '#D78700', '#D7875F',
1006
            '#D78787', '#D787AF', '#D787D7', '#D787FF', '#D7AF00', '#D7AF5F',
1007
            '#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF', '#D7D700', '#D7D75F',
1008
            '#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF', '#D7FF00', '#D7FF5F',
1009
            '#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF', '#FF0000', '#FF005F',
1010
            '#FF0087', '#FF00AF', '#FF00D7', '#FF00FF', '#FF5F00', '#FF5F5F',
1011
            '#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF', '#FF8700', '#FF875F',
1012
            '#FF8787', '#FF87AF', '#FF87D7', '#FF87FF', '#FFAF00', '#FFAF5F',
1013
            '#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF', '#FFD700', '#FFD75F',
1014
            '#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF', '#FFFF00', '#FFFF5F',
1015
            '#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF', '#080808', '#121212',
1016
            '#1C1C1C', '#262626', '#303030', '#3A3A3A', '#444444', '#4E4E4E',
1017
            '#585858', '#626262', '#6C6C6C', '#767676', '#808080', '#8A8A8A',
1018
            '#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', '#BCBCBC', '#C6C6C6',
1019
            '#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
1020
        ]
1021
    };
1022
    // ---------------------------------------------------------------------
1023
    // :: Replace ANSI formatting with terminal formatting
1024
    // ---------------------------------------------------------------------
1025
    $.terminal.from_ansi = (function() {
2✔
1026
        var color_list = {
2✔
1027
            30: 'black',
1028
            31: 'red',
1029
            32: 'green',
1030
            33: 'yellow',
1031
            34: 'blue',
1032
            35: 'magenta',
1033
            36: 'cyan',
1034
            37: 'white',
1035

1036
            39: 'inherit' // default color
1037
        };
1038
        var background_list = {
2✔
1039
            40: 'black',
1040
            41: 'red',
1041
            42: 'green',
1042
            43: 'yellow',
1043
            44: 'blue',
1044
            45: 'magenta',
1045
            46: 'cyan',
1046
            47: 'white',
1047

1048
            49: 'transparent' // default background
1049
        };
1050
        function format_ansi(controls, state, ansi_art) {
1051
            var num;
1052
            var styles = [];
9,230✔
1053
            var output_color;
1054
            var output_background;
1055
            var _process_true_color = -1;
9,230✔
1056
            var _ex_color = false;
9,230✔
1057
            var _ex_background = false;
9,230✔
1058
            var _process_8bit = false;
9,230✔
1059
            var palette = $.terminal.ansi_colors.palette;
9,230✔
1060
            function set_styles(num) {
1061
                switch (num) {
14,078✔
1062
                    case 0:
1063
                        Object.keys(state).forEach(function(key) {
2,592✔
1064
                            delete state[key];
11,442✔
1065
                        });
1066
                        state.blink = false;
2,592✔
1067
                        state.bold = false;
2,592✔
1068
                        state.faited = false;
2,592✔
1069
                        break;
2,592✔
1070
                    case 1:
1071
                        styles.push('b');
1,760✔
1072
                        state.bold = true;
1,760✔
1073
                        state.faited = false;
1,760✔
1074
                        break;
1,760✔
1075
                    case 4:
1076
                        styles.push('u');
4✔
1077
                        break;
4✔
1078
                    case 3:
1079
                        styles.push('i');
4✔
1080
                        break;
4✔
1081
                    case 5:
1082
                        if (_ex_color || _ex_background) {
736!
1083
                            _process_8bit = true;
736✔
1084
                        } else {
1085
                            state.blink = true;
×
1086
                        }
1087
                        break;
736✔
1088
                    case 38:
1089
                        _ex_color = true;
594✔
1090
                        break;
594✔
1091
                    case 48:
1092
                        _ex_background = true;
152✔
1093
                        break;
152✔
1094
                    case 2:
1095
                        if (_ex_color || _ex_background) {
12✔
1096
                            _process_true_color = 0;
8✔
1097
                        } else {
1098
                            state.faited = true;
4✔
1099
                            state.bold = false;
4✔
1100
                        }
1101
                        break;
12✔
1102
                    case 7:
1103
                        state.reverse = true;
4✔
1104
                        break;
4✔
1105
                    default:
1106
                        if (color_list[num]) {
8,220✔
1107
                            output_color = color_list[num];
4,354✔
1108
                        }
1109
                        if (background_list[num]) {
8,220✔
1110
                            output_background = background_list[num];
3,864✔
1111
                        }
1112
                }
1113
            }
1114
            // -----------------------------------------------------------------
1115
            function process_true_color() {
1116
                if (_ex_color) {
24✔
1117
                    if (!output_color) {
12✔
1118
                        output_color = '#';
4✔
1119
                    }
1120
                    if (output_color.length < 7) {
12!
1121
                        output_color += ('0' + num.toString(16)).slice(-2);
12✔
1122
                    }
1123
                }
1124
                if (_ex_background) {
24!
1125
                    if (!output_background) {
24✔
1126
                        output_background = '#';
4✔
1127
                    }
1128
                    if (output_background.length < 7) {
24✔
1129
                        output_background += ('0' + num.toString(16)).slice(-2);
12✔
1130
                    }
1131
                }
1132
                if (_process_true_color === 2) {
24✔
1133
                    _process_true_color = -1;
8✔
1134
                } else {
1135
                    _process_true_color++;
16✔
1136
                }
1137
            }
1138
            // -----------------------------------------------------------------
1139
            function should__process_8bit() {
1140
                return _process_8bit && ((_ex_background && !output_background) ||
14,814✔
1141
                                        (_ex_color && !output_color));
1142
            }
1143
            // -----------------------------------------------------------------
1144
            function process_8bit() {
1145
                if (_ex_color && palette[num] && !output_color) {
736✔
1146
                    output_color = palette[num];
588✔
1147
                }
1148
                if (_ex_background && palette[num] && !output_background) {
736✔
1149
                    output_background = palette[num];
148✔
1150
                }
1151
                _process_8bit = false;
736✔
1152
            }
1153
            // -----------------------------------------------------------------
1154
            for (var i in controls) {
9,230✔
1155
                if (controls.hasOwnProperty(i)) {
14,838!
1156
                    num = parseInt(controls[i], 10);
14,838✔
1157
                    if (_process_true_color > -1) {
14,838✔
1158
                        process_true_color();
24✔
1159
                    } else if (should__process_8bit()) {
14,814✔
1160
                        process_8bit();
736✔
1161
                    } else {
1162
                        set_styles(num);
14,078✔
1163
                    }
1164
                }
1165
            }
1166
            if (state.reverse) {
9,230✔
1167
                if (output_color || output_background) {
4!
1168
                    var tmp = output_background;
×
1169
                    output_background = output_color;
×
1170
                    output_color = tmp;
×
1171
                } else {
1172
                    output_color = 'black';
4✔
1173
                    output_background = 'white';
4✔
1174
                }
1175
            }
1176
            output_color = output_color || state.color;
9,230✔
1177
            output_background = output_background || state.background;
9,230✔
1178
            var colors, color, background;
1179
            if (state.bold) {
9,230✔
1180
                colors = $.terminal.ansi_colors.bold;
3,492✔
1181
            } else if (state.faited) {
5,738✔
1182
                colors = $.terminal.ansi_colors.faited;
4✔
1183
            } else {
1184
                colors = $.terminal.ansi_colors.normal;
5,734✔
1185
            }
1186
            if (typeof output_color !== 'undefined') {
9,230✔
1187
                if (output_color.match(/^#/)) {
6,396✔
1188
                    color = output_color;
814✔
1189
                } else if (output_color === 'inherit') {
5,582✔
1190
                    color = output_color;
8✔
1191
                } else {
1192
                    color = colors[output_color];
5,574✔
1193
                }
1194
                state.color = output_color;
6,396✔
1195
            } else {
1196
                color = colors['white'];
2,834✔
1197
            }
1198
            if (typeof output_background !== 'undefined') {
9,230✔
1199
                if (output_background.match(/^#/)) { // already 8bit color #460
5,184✔
1200
                    background = output_background;
284✔
1201
                } else if (output_background === 'transparent') {
4,900✔
1202
                    background = output_background;
8✔
1203
                } else if (state.blink && ansi_art) {
4,892!
1204
                    background = $.terminal.ansi_colors.bold[output_background];
×
1205
                } else {
1206
                    // background is not changed by bold flag
1207
                    background = $.terminal.ansi_colors.normal[output_background];
4,892✔
1208
                }
1209
                state.background = output_background;
5,184✔
1210
            } else if (state.blink && ansi_art) {
4,046!
1211
                background = $.terminal.ansi_colors.bold['black'];
×
1212
            }
1213
            var ret = [styles.join(''), color, background];
9,230✔
1214
            if (state.blink && !ansi_art) {
9,230!
1215
                ret.push('terminal-blink');
×
1216
            }
1217
            return ret;
9,230✔
1218
        }
1219
        // -------------------------------------------------------------------------------
1220
        return function from_ansi(input, options) {
2✔
1221
            options = options || {};
6,490✔
1222
            var settings = get_settings(options);
6,490✔
1223
            var ansi_art = settings.ansiArt;
6,490✔
1224
            // if there are SAUCE record if something after end of file
1225
            input = input.replace(/\x1A.*/, '');
6,490✔
1226
            input = input.replace(/\r?\n?\x1b\[A\x1b\[[0-9]+C/g, '');
6,490✔
1227
            input = $.terminal.unescape_brackets(input);
6,490✔
1228
            var code, inside, format, charset, saved_cursor;
1229
            var print = function print(s) {
6,490✔
1230
                var s_len = s.length;
39,566✔
1231
                if (settings.escapeBrackets) {
39,566✔
1232
                    s = $.terminal.escape_formatting(s);
9,352✔
1233
                }
1234
                if (charset) {
39,566✔
1235
                    s = s.split('').map(function(chr) {
26✔
1236
                        return charset[chr] || chr;
182!
1237
                    }).join('');
1238
                }
1239
                if (format) {
39,566✔
1240
                    // this will always need to be escaped
1241
                    if (s.match(/\\$|[[\]]/) &&
7,626✔
1242
                        !settings.escapeBrackets &&
1243
                        !$.terminal.have_formatting(s)) {
1244
                        s = $.terminal.escape_formatting(s);
16✔
1245
                    }
1246
                    s = format + s + ']';
7,626✔
1247
                }
1248
                var line = this.result[this.cursor.y];
39,566✔
1249
                var len, after, before, line_len;
1250
                if (!line) {
39,566✔
1251
                    if (this.cursor.x > 0) {
14,466✔
1252
                        var space = new Array(this.cursor.x + 1).join(' ');
224✔
1253
                        this.result[this.cursor.y] = space + s;
224✔
1254
                    } else {
1255
                        this.result[this.cursor.y] = s;
14,242✔
1256
                    }
1257
                } else {
1258
                    var stripped = $.terminal.strip(line);
25,100✔
1259
                    line_len = $.terminal.unescape_brackets(stripped).length;
25,100✔
1260
                    if (this.cursor.x === 0) {
25,100✔
1261
                        after = $.terminal.substring(line, s_len);
22✔
1262
                        this.result[this.cursor.y] = s + after;
22✔
1263
                    } else if (line_len < this.cursor.x) {
25,078✔
1264
                        len = this.cursor.x - (line_len - 1);
476✔
1265
                        this.result[this.cursor.y] += new Array(len).join(' ') + s;
476✔
1266
                    } else if (line_len === this.cursor.x) {
24,602✔
1267
                        this.result[this.cursor.y] += s;
24,538✔
1268
                    } else {
1269
                        before = $.terminal.substring(line, 0, this.cursor.x);
64✔
1270
                        after = $.terminal.substring(line, this.cursor.x + s_len);
64✔
1271
                        this.result[this.cursor.y] = before + s + after;
64✔
1272
                    }
1273
                }
1274
                this.cursor.x += s_len;
39,566✔
1275
            };
1276
            var term = $.terminal.active();
6,490✔
1277
            var ROWS = term && term.rows() || 1000;
6,490✔
1278
            var COLS = term && term.cols() || 80;
6,490!
1279
            // correction to CP 437
1280
            // ref: https://unix.stackexchange.com/a/611513/1806
1281
            //      https://unix.stackexchange.com/a/611344/1806
1282
            var cp_437_control = {
6,490✔
1283
                0x00: ' ',
1284
                0x01: '☺',
1285
                0x02: '☻',
1286
                0x03: '♥',
1287
                0x07: '•',
1288
                0x08: '█',
1289
                0x0F: '*',
1290
                0x10: '█',
1291
                0x11: '◄',
1292
                0x12: '↕',
1293
                0x14: '¶',
1294
                0x15: '§',
1295
                0x16: '▬',
1296
                0x17: '↨',
1297
                0x18: '↑',
1298
                0x19: '↓',
1299
                0x1E: '▲'
1300
            };
1301
            var characters = 'qwertyuiopasdfghjklzxcvbnm';
6,490✔
1302
            var prev_code;
1303
            var parser_events = {
6,490✔
1304
                cursor: {x: 0, y: 0},
1305
                result: [],
1306
                state: {},
1307
                inst_p: print,
1308
                inst_x: function(flag) {
1309
                    var code = flag.charCodeAt(0);
21,272✔
1310
                    if (code === 13) {
21,272✔
1311
                        this.cursor.x = 0;
502✔
1312
                    } else if (code === 10) {
20,770✔
1313
                        this.cursor.y++;
10,468✔
1314
                        if (prev_code !== 13) {
10,468✔
1315
                            this.cursor.x = 0;
9,966✔
1316
                        }
1317
                    } else if (code === 9) {
10,302✔
1318
                        print.call(this, '\t');
10,300✔
1319
                    } else if (ansi_art && code in cp_437_control) {
2!
1320
                        // eslint-disable-next-line no-console
1321
                        console.log({code: '0x' + code.toString(16)});
×
1322
                        print.call(this, cp_437_control[code]);
×
1323
                    } else if (DEBUG) {
2!
1324
                        var mod = code % characters.length;
×
1325
                        var char = characters[mod];
×
1326
                        // eslint-disable-next-line no-console
1327
                        console.log({code: code, char: char});
×
1328
                        print.call(this, char);
×
1329
                    }
1330
                    if (!this.result[this.cursor.y]) {
21,272✔
1331
                        this.result[this.cursor.y] = '';
10,426✔
1332
                    }
1333
                    prev_code = code;
21,272✔
1334
                },
1335
                inst_e: function(collected, flag) {
1336
                    if (collected === '(') {
84✔
1337
                        if (flag in CHARSETS) {
78!
1338
                            charset = CHARSETS[flag];
78✔
1339
                        }
1340
                    }
1341
                },
1342
                inst_E: function(data) {
1343
                    /* eslint-disable no-console */
1344
                    console.log(data);
×
1345
                    /* eslint-enable no-console */
1346
                },
1347
                inst_c: function(collected, params, flag) {
1348
                    var value = params[0] === 0 ? 1 : params[0];
10,316✔
1349
                    switch (flag) {
10,316!
1350
                        case 's':
1351
                            saved_cursor = Object.assign({}, this.cursor);
×
1352
                            break;
×
1353
                        case 'u':
1354
                            this.cursor = saved_cursor;
×
1355
                            break;
×
1356
                        case 'A': // UP
1357
                            this.cursor.y -= value;
58✔
1358
                            break;
58✔
1359
                        case 'B': // Down
1360
                            this.cursor.y += value;
52✔
1361
                            break;
52✔
1362
                        case 'C': // Forward
1363
                            this.cursor.x += value;
728✔
1364
                            break;
728✔
1365
                        case 'D': // Backward
1366
                            this.cursor.x -= value;
64✔
1367
                            break;
64✔
1368
                        case 'E': // Cursor Next Line
1369
                            this.cursor.x = 0;
×
1370
                            this.cursor.y += value;
×
1371
                            break;
×
1372
                        case 'F': // Cursor Previous Line
1373
                            this.cursor.x = 0;
×
1374
                            this.cursor.y -= value;
×
1375
                            break;
×
1376
                        case 'H':
1377
                            // -1 since CUP is 1-based
1378
                            this.cursor.y = Math.min(params[0] || 1, ROWS) - 1;
36✔
1379
                            this.cursor.x = Math.min(params[1] || 1, COLS) - 1;
36✔
1380
                            break;
36✔
1381
                        case 'm':
1382
                            code = format_ansi(params, this.state, ansi_art);
9,230✔
1383
                            var empty = params.length === 1 && params[0] === 0;
9,230✔
1384
                            if (inside) {
9,230✔
1385
                                if (empty) {
7,568✔
1386
                                    inside = false;
1,542✔
1387
                                    format = null;
1,542✔
1388
                                } else {
1389
                                    format = '[[' + code.join(';') + ']';
6,026✔
1390
                                }
1391
                            } else if (empty) {
1,662✔
1392
                                format = null;
116✔
1393
                            } else {
1394
                                format = '[[' + code.join(';') + ']';
1,546✔
1395
                                inside = true;
1,546✔
1396
                            }
1397
                            break;
9,230✔
1398
                    }
1399
                    if (this.cursor.x < 0) {
10,316✔
1400
                        this.cursor.x = 0;
6✔
1401
                    }
1402
                    if (this.cursor.y < 0) {
10,316!
1403
                        this.cursor.y = 0;
×
1404
                    }
1405
                }
1406
            };
1407
            // extra parser options not used by unix_formatting
1408
            Object.keys(settings.ansiParser).forEach(function(name) {
6,490✔
1409
                var original = parser_events[name];
×
1410
                var fn = settings.ansiParser[name];
×
1411
                if (typeof fn === 'function') {
×
1412
                    parser_events[name] = original ? function() {
×
1413
                        if (fn.apply(parser_events, arguments) !== false) {
×
1414
                            return original.apply(parser_events, arguments);
×
1415
                        }
1416
                    } : function() {
1417
                        return fn.apply(parser_events, arguments);
×
1418
                    };
1419
                    settings.ansiParser[name] = parser_events[name];
×
1420
                }
1421
            });
1422
            var parser = new AnsiParser(parser_events);
6,490✔
1423
            parser.parse(input);
6,490✔
1424
            var output = parser_events.result.join('\n');
6,490✔
1425
            if (input !== output) {
6,490✔
1426
                return output;
220✔
1427
            }
1428
            if (typeof options.position === 'number') {
6,270✔
1429
                return [input, options.position];
6,268✔
1430
            }
1431
            return input;
2✔
1432
        };
1433
    })();
1434
    $.terminal.from_ansi.__no_warn__ = true;
2✔
1435
    $.terminal.defaults.formatters.unshift($.terminal.from_ansi);
2✔
1436
    $.terminal.defaults.formatters.unshift($.terminal.overtyping);
2✔
1437
});
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc