From 6a6043daa3ff2b62c4c70fb8da0aaf6311fdf2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Fri, 22 Oct 2021 18:17:52 +0200 Subject: [PATCH 01/58] properly parse xcolor names --- src/common/InputHandler.test.ts | 61 ++++++++++++++++++ src/common/InputHandler.ts | 109 ++++++++++++++++++++++++++++---- 2 files changed, 159 insertions(+), 11 deletions(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index e25c3df1..a09f0020 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -54,6 +54,10 @@ class TestInputHandler extends InputHandler { prev = await result; } } + + public parseXColorName(data: string): void | [number, number, number] { + return this._parseXColorName(data); + } } describe('InputHandler', () => { @@ -1865,6 +1869,63 @@ describe('InputHandler', () => { }); }); describe('OSC', () => { + describe.only('parse xcolor names', () => { + it('rgb:// scheme in 4/8/12/16 bit', () => { + // 4 bit + assert.deepEqual(inputHandler.parseXColorName('rgb:0/0/0'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseXColorName('rgb:f/f/f'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseXColorName('rgb:1/2/3'), [17, 34, 51]); + // 8 bit + assert.deepEqual(inputHandler.parseXColorName('rgb:00/00/00'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseXColorName('rgb:ff/ff/ff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseXColorName('rgb:11/22/33'), [17, 34, 51]); + // 12 bit + assert.deepEqual(inputHandler.parseXColorName('rgb:000/000/000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseXColorName('rgb:fff/fff/fff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseXColorName('rgb:111/222/333'), [17, 34, 51]); + // 16 bit + assert.deepEqual(inputHandler.parseXColorName('rgb:0000/0000/0000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseXColorName('rgb:ffff/ffff/ffff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseXColorName('rgb:1111/2222/3333'), [17, 34, 51]); + }); + it('#RGB scheme in 4/8/12/16 bit', () => { + // 4 bit + assert.deepEqual(inputHandler.parseXColorName('#000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseXColorName('#fff'), [240, 240, 240]); + assert.deepEqual(inputHandler.parseXColorName('#123'), [16, 32, 48]); + // 8 bit + assert.deepEqual(inputHandler.parseXColorName('#000000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseXColorName('#ffffff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseXColorName('#112233'), [17, 34, 51]); + // 12 bit + assert.deepEqual(inputHandler.parseXColorName('#000000000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseXColorName('#fffffffff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseXColorName('#111222333'), [17, 34, 51]); + // 16 bit + assert.deepEqual(inputHandler.parseXColorName('#000000000000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseXColorName('#ffffffffffff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseXColorName('#111122223333'), [17, 34, 51]); + }); + it('supports upper case', () => { + assert.deepEqual(inputHandler.parseXColorName('RGB:0/A/F'), [0, 170, 255]); + assert.deepEqual(inputHandler.parseXColorName('#FFF'), [240, 240, 240]); + }); + it('does not parse illegal combinations', () => { + // shifting bit width + assert.equal(inputHandler.parseXColorName('rgb:0/11/222'), undefined); + // unsupported scheme + assert.equal(inputHandler.parseXColorName('rgbi:00/11/22'), undefined); + // broken # specifier + assert.equal(inputHandler.parseXColorName('#aabbbcc'), undefined); + // out of range + assert.equal(inputHandler.parseXColorName('#aabbgg'), undefined); + assert.equal(inputHandler.parseXColorName('rgb:aa/bb/gg'), undefined); + }); + }); + + + + it('4: should parse correct Ansi color change data', () => { // this is testing a private method const event = inputHandler.parseAnsiColorChange('19;rgb:a1/b2/c3'); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 9371e5f5..a6c425b6 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -25,7 +25,7 @@ import { IBuffer } from 'common/buffer/Types'; /** * Map collect to glevel. Used in `selectCharset`. */ -const GLEVEL: {[key: string]: number} = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 }; +const GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 }; /** * VT commands done by the parser - FIXME: move this to the parser? @@ -167,7 +167,7 @@ class DECRQSS implements IDcsHandler { break; case 'r': // DECSTBM const pt = '' + (this._bufferService.buffer.scrollTop + 1) + - ';' + (this._bufferService.buffer.scrollBottom + 1) + 'r'; + ';' + (this._bufferService.buffer.scrollBottom + 1) + 'r'; this._coreService.triggerDataEvent(`${C0.ESC}P1$r${pt}${C0.ESC}\\`); break; case 'm': // SGR @@ -175,7 +175,7 @@ class DECRQSS implements IDcsHandler { this._coreService.triggerDataEvent(`${C0.ESC}P1$r0m${C0.ESC}\\`); break; case ' q': // DECSCUSR - const STYLES: {[key: string]: number} = { 'block': 2, 'underline': 4, 'bar': 6 }; + const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 }; let style = STYLES[this._optionsService.options.cursorStyle]; style -= this._optionsService.options.cursorBlink ? 1 : 0; this._coreService.triggerDataEvent(`${C0.ESC}P1$r${style} q${C0.ESC}\\`); @@ -403,7 +403,9 @@ export class InputHandler extends Disposable implements IInputHandler { // 6 - Enable/disable Special Color Number c // 7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939) // 10 - Change VT100 text foreground color to Pt. + this._parser.registerOscHandler(10, new OscHandler(data => this.queryOrSetFgColor(data))); // 11 - Change VT100 text background color to Pt. + this._parser.registerOscHandler(11, new OscHandler(data => this.queryOrSetBgColor(data))); // 12 - Change text cursor color to Pt. // 13 - Change mouse foreground color to Pt. // 14 - Change mouse background color to Pt. @@ -855,10 +857,9 @@ export class InputHandler extends Disposable implements IInputHandler { * - any cursor movement sequence keeps working as expected */ if (this._activeBuffer.x === 0 - && this._activeBuffer.y > this._activeBuffer.scrollTop - && this._activeBuffer.y <= this._activeBuffer.scrollBottom - && this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) - { + && this._activeBuffer.y > this._activeBuffer.scrollTop + && this._activeBuffer.y <= this._activeBuffer.scrollBottom + && this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) { this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false; this._activeBuffer.y--; this._activeBuffer.x = this._bufferService.cols - 1; @@ -1977,7 +1978,7 @@ export class InputHandler extends Disposable implements IInputHandler { break; case 1049: // alt screen buffer cursor this.saveCursor(); - // FALL-THROUGH + // FALL-THROUGH case 47: // alt screen buffer case 1047: // alt screen buffer this._bufferService.buffers.activateAltBuffer(this._eraseAttrData()); @@ -2197,7 +2198,7 @@ export class InputHandler extends Disposable implements IInputHandler { this.restoreCursor(); break; case 1049: // alt screen buffer cursor - // FALL-THROUGH + // FALL-THROUGH case 47: // normal screen buffer case 1047: // normal screen buffer - clearing it first // Ensure the selection manager has the correct buffer @@ -2264,7 +2265,7 @@ export class InputHandler extends Disposable implements IInputHandler { } // exit early if can decide color mode with semicolons if ((accu[1] === 5 && advance + cSpace >= 2) - || (accu[1] === 2 && advance + cSpace >= 5)) { + || (accu[1] === 2 && advance + cSpace >= 5)) { break; } // offset colorSpace slot for semicolon mode @@ -2683,7 +2684,7 @@ export class InputHandler extends Disposable implements IInputHandler { const top = params.params[0] || 1; let bottom: number; - if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) { + if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) { bottom = this._bufferService.rows; } @@ -2862,6 +2863,56 @@ export class InputHandler extends Disposable implements IInputHandler { return result; } + /** + * Parse xcolor name to RGB values (8 bit per channel). + * See `man xparsecolor` for details about certain format specifications. + * + * Supported formats: + * - rgb:// with , , in h | hh | hhh | hhhh + * - #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB + * + * All other formats like rgbi: or device-independent string specifications + * with float numbering are not supported. + */ + protected _parseXColorName(data: string): [number, number, number] | void { + // also handle uppercases + data = data.toLowerCase(); + if (data.indexOf('rgb:') === 0) { + // 'rgb:' specifier + data = data.slice(4); + const rex = /^([\da-f]{1})\/([\da-f]{1})\/([\da-f]{1})$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$/; + const m = rex.exec(data); + if (m) { + const base = m[1] ? 15 : m[4] ? 255 : m[7] ? 4095 : 65535; + return [ + Math.round(parseInt(m[1] || m[4] || m[7] || m[10], 16) / base * 255), + Math.round(parseInt(m[2] || m[5] || m[8] || m[11], 16) / base * 255), + Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255), + ]; + } + } else if (data.indexOf('#') === 0) { + // '#' specifier + data = data.slice(1); + const rex = /^[\da-f]+$/; + if (rex.exec(data) && [3, 6, 9, 12].includes(data.length)) { + const adv = data.length / 3; + const r = parseInt(data.slice(0, adv), 16); + const g = parseInt(data.slice(adv, 2 * adv), 16); + const b = parseInt(data.slice(2 * adv, 3 * adv), 16); + switch (adv) { + case 1: + return [r << 4, g << 4, b << 4]; + case 2: + return [r, g, b]; + case 3: + return [r >> 4, g >> 4, b >> 4]; + case 4: + return [r >> 8, g >> 8, b >> 8]; + } + } + } + } + /** * OSC 4; ; ST (set ANSI color to ) * @@ -2880,6 +2931,42 @@ export class InputHandler extends Disposable implements IInputHandler { return true; } + public queryOrSetFgColor(data: string): boolean { + // note: data may contain multiple ? or color names separated with ; + // Multiple values will map through to OSC 10 - 19, but we only support 10 and 11 currently, + // thus truncate to max. 2 occurences. + const slots = data.split(';').slice(0, 2); + if (slots[0] === '?') { + // TODO: query FG color + console.log('query FG'); + } else { + const color = this._parseXColorName(slots[0]); + if (color) { + // set new FG color + console.log('set FG', color); + } + } + if (slots.length === 2) { + this.queryOrSetBgColor(slots[1]); + } + return true; + } + + public queryOrSetBgColor(data: string): boolean { + const slots = data.split(';').slice(0, 1); + if (slots[0] === '?') { + // TODO: query BG color + console.log('query BG'); + } else { + const color = this._parseXColorName(slots[0]); + if (color) { + // set new BG color + console.log('set BG', color); + } + } + return true; + } + /** * ESC E * C1.NEL From 0f4d71b8f81b0133d335e4e8c4b4ccea7c60d039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Fri, 22 Oct 2021 18:26:46 +0200 Subject: [PATCH 02/58] make linter happy --- src/common/InputHandler.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index a6c425b6..3505b548 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -2866,11 +2866,11 @@ export class InputHandler extends Disposable implements IInputHandler { /** * Parse xcolor name to RGB values (8 bit per channel). * See `man xparsecolor` for details about certain format specifications. - * + * * Supported formats: * - rgb:// with , , in h | hh | hhh | hhhh * - #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB - * + * * All other formats like rgbi: or device-independent string specifications * with float numbering are not supported. */ @@ -2887,7 +2887,7 @@ export class InputHandler extends Disposable implements IInputHandler { return [ Math.round(parseInt(m[1] || m[4] || m[7] || m[10], 16) / base * 255), Math.round(parseInt(m[2] || m[5] || m[8] || m[11], 16) / base * 255), - Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255), + Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255) ]; } } else if (data.indexOf('#') === 0) { From 8e71cec20877308a8dce5adb8d18a426dd4cde13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Fri, 22 Oct 2021 18:32:30 +0200 Subject: [PATCH 03/58] remove only from tests --- src/common/InputHandler.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index a09f0020..8d1c3b4f 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -1869,7 +1869,7 @@ describe('InputHandler', () => { }); }); describe('OSC', () => { - describe.only('parse xcolor names', () => { + describe('parse xcolor names', () => { it('rgb:// scheme in 4/8/12/16 bit', () => { // 4 bit assert.deepEqual(inputHandler.parseXColorName('rgb:0/0/0'), [0, 0, 0]); From 01a732274c40cc87e88d4eeb7f0d518c43d11c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Fri, 22 Oct 2021 22:48:57 +0200 Subject: [PATCH 04/58] OSC 10/11 working, OSC 4 partially fixed --- src/browser/Color.ts | 17 +++++++++ src/browser/Terminal.ts | 64 +++++++++++++++++++++++++++------ src/common/InputHandler.test.ts | 34 +++++++++--------- src/common/InputHandler.ts | 30 +++++++++------- src/common/Types.d.ts | 12 +++---- 5 files changed, 109 insertions(+), 48 deletions(-) diff --git a/src/browser/Color.ts b/src/browser/Color.ts index c43c5eb5..42a65876 100644 --- a/src/browser/Color.ts +++ b/src/browser/Color.ts @@ -5,6 +5,8 @@ import { IColor } from 'browser/Types'; +// FIXME: Move Color.ts lib to common? + /** * Helper functions where the source type is "channels" (individual color channels as numbers). */ @@ -17,6 +19,8 @@ export namespace channels { } export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number { + // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32 + // on LE systems, before it can be used for direct 32-bit buffer writes. // >>> 0 forces an unsigned int return (r << 24 | g << 16 | b << 8 | a) >>> 0; } @@ -81,6 +85,11 @@ export namespace color { rgba: channels.toRgba(r, g, b, a) }; } + + export function toXColorName(color: IColor): string { + const [r, g, b] = rgba.toChannels(color.rgba); + return `rgb:${toPaddedHex(r)}/${toPaddedHex(g)}/${toPaddedHex(b)}`; + } } /** @@ -197,6 +206,7 @@ export namespace rgba { return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0; } + // FIXME: Move this to channels NS? export function toChannels(value: number): [number, number, number, number] { return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF]; } @@ -207,6 +217,13 @@ export namespace rgba { rgba: channels.toRgba(r, g, b) }; } + + /** + * convert 0xRRGGBBAA to 0xAABBGGRR (32-bit representation on LE systems) + */ + export function toABGR32(rgba: number): number { + return ((rgba & 0xFF) << 24 | (rgba >>> 8 & 0xFF) << 16 | (rgba >>> 16 & 0xFF) << 8 | rgba >>> 24 & 0xFF) >>> 0; + } } export function toPaddedHex(c: number): string { diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 2cd9bf99..4dcf8460 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -21,7 +21,7 @@ * http://linux.die.net/man/7/urxvt */ -import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler, ILinkifier, IMouseZoneManager, LinkMatcherHandler, ILinkMatcherOptions, IViewport, ILinkifier2, CharacterJoinerHandler } from 'browser/Types'; +import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler, ILinkifier, IMouseZoneManager, LinkMatcherHandler, ILinkMatcherOptions, IViewport, ILinkifier2, CharacterJoinerHandler, IColor } from 'browser/Types'; import { IRenderer } from 'browser/renderer/Types'; import { CompositionHelper } from 'browser/input/CompositionHelper'; import { Viewport } from 'browser/Viewport'; @@ -39,7 +39,7 @@ import { MouseZoneManager } from 'browser/MouseZoneManager'; import { AccessibilityManager } from './AccessibilityManager'; import { ITheme, IMarker, IDisposable, ISelectionPosition, ILinkProvider } from 'xterm'; import { DomRenderer } from 'browser/renderer/dom/DomRenderer'; -import { IKeyboardEvent, KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IAnsiColorChangeEvent } from 'common/Types'; +import { IKeyboardEvent, KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IColorEvent } from 'common/Types'; import { evaluateKeyboardEvent } from 'common/input/Keyboard'; import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; @@ -53,7 +53,7 @@ import { Linkifier2 } from 'browser/Linkifier2'; import { CoreBrowserService } from 'browser/services/CoreBrowserService'; import { CoreTerminal } from 'common/CoreTerminal'; import { ITerminalOptions as IInitializedTerminalOptions } from 'common/services/Services'; -import { rgba } from 'browser/Color'; +import { color, rgba } from 'browser/Color'; import { CharacterJoinerService } from 'browser/services/CharacterJoinerService'; // Let it work inside Node.js for automated testing purposes. @@ -167,7 +167,7 @@ export class Terminal extends CoreTerminal implements ITerminal { this.register(this._inputHandler.onRequestSendFocus(() => this._reportFocus())); this.register(this._inputHandler.onRequestReset(() => this.reset())); this.register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type))); - this.register(this._inputHandler.onAnsiColorChange((event) => this._changeAnsiColor(event))); + this.register(this._inputHandler.onColor((event) => this._handleColorEvent(event))); this.register(forwardEvent(this._inputHandler.onCursorMove, this._onCursorMove)); this.register(forwardEvent(this._inputHandler.onTitleChange, this._onTitleChange)); this.register(forwardEvent(this._inputHandler.onA11yChar, this._onA11yCharEmitter)); @@ -177,17 +177,59 @@ export class Terminal extends CoreTerminal implements ITerminal { this.register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows))); } - private _changeAnsiColor(event: IAnsiColorChangeEvent): void { + private _handleColorEvent(event: IColorEvent): void { if (!this._colorManager) { return; } - for (const ansiColor of event.colors) { - const color = rgba.toColor(ansiColor.red, ansiColor.green, ansiColor.blue); - - this._colorManager!.colors.ansi[ansiColor.colorIndex] = color; + let hasSet = false; + const query: string[] = []; + for (const req of event.requests) { + if (req.color === '?') { + // query color + let ident = ''; + let c: IColor; + switch (req.index) { + case 256: + ident = '10'; + c = this._colorManager.colors.foreground; + break; + case 257: + ident = '11'; + c = this._colorManager.colors.background; + break; + default: + if (0 <= req.index && req.index < 256) { + ident = '4;' + req.index; + c = this._colorManager.colors.ansi[req.index]; + } + } + if (ident) { + query.push(`${C0.ESC}]${ident};${color.toXColorName(c!)}${C0.BEL}`); + } + } else { + // set color + hasSet = true; + switch (req.index) { + case 256: + this._colorManager.colors.foreground = rgba.toColor(...req.color); + break; + case 257: + this._colorManager.colors.background = rgba.toColor(...req.color); + break; + default: + if (0 <= req.index && req.index < 256) { + this._colorManager.colors.ansi[req.index] = rgba.toColor(...req.color); + } + } + } } - this._renderService?.setColors(this._colorManager!.colors); - this.viewport?.onThemeChange(this._colorManager!.colors); + if (query.length) { + this.coreService.triggerDataEvent(query.join('')); + } + if (hasSet) { + this._renderService?.setColors(this._colorManager.colors); + this.viewport?.onThemeChange(this._colorManager.colors); + } } public dispose(): void { diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index 8d1c3b4f..f3b0f41f 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -5,7 +5,7 @@ import { assert } from 'chai'; import { InputHandler } from 'common/InputHandler'; -import { IBufferLine, IAttributeData, IAnsiColorChangeEvent } from 'common/Types'; +import { IBufferLine, IAttributeData, IColorEvent } from 'common/Types'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; import { CellData } from 'common/buffer/CellData'; import { Attributes, UnderlineStyle } from 'common/buffer/Constants'; @@ -41,7 +41,7 @@ class TestInputHandler extends InputHandler { public get curAttrData(): IAttributeData { return (this as any)._curAttrData; } public get windowTitleStack(): string[] { return this._windowTitleStack; } public get iconNameStack(): string[] { return this._iconNameStack; } - public parseAnsiColorChange(data: string): IAnsiColorChangeEvent | null { return this._parseAnsiColorChange(data); } + public parseAnsiColorChange(data: string): IColorEvent | null { return this._parseAnsiColorChange(data); } /** * Promise based parse call to await the full resolve of given input data. @@ -1924,14 +1924,12 @@ describe('InputHandler', () => { }); - - it('4: should parse correct Ansi color change data', () => { // this is testing a private method const event = inputHandler.parseAnsiColorChange('19;rgb:a1/b2/c3'); assert.isNotNull(event); - assert.deepEqual(event!.colors[0], { colorIndex: 19, red: 0xa1, green: 0xb2, blue: 0xc3 }); + assert.deepEqual(event!.requests[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); }); it('4: should ignore incorrect Ansi color change data', () => { @@ -1947,33 +1945,33 @@ describe('InputHandler', () => { const event = inputHandler.parseAnsiColorChange('19;rgb:a1/b2/c3;17;rgb:00/11/22;255;rgb:01/ef/2d'); assert.isNotNull(event); - assert.equal(event!.colors.length, 3); - assert.deepEqual(event!.colors[0], { colorIndex: 19, red: 0xa1, green: 0xb2, blue: 0xc3 }); - assert.deepEqual(event!.colors[1], { colorIndex: 17, red: 0x00, green: 0x11, blue: 0x22 }); - assert.deepEqual(event!.colors[2], { colorIndex: 255, red: 0x01, green: 0xef, blue: 0x2d }); + assert.equal(event!.requests.length, 3); + assert.deepEqual(event!.requests[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); + assert.deepEqual(event!.requests[1], { index: 17, color: [0x00, 0x11, 0x22] }); + assert.deepEqual(event!.requests[2], { index: 255, color: [0x01, 0xef, 0x2d] }); }); it('4: should ignore incorrect colors in a list of Ansi color changes', () => { // this is testing a private method const event = inputHandler.parseAnsiColorChange('19;rgb:a1/b2/c3;17;rgb:WR/ON/G;255;rgb:01/ef/2d'); - assert.equal(event!.colors.length, 2); - assert.deepEqual(event!.colors[0], { colorIndex: 19, red: 0xa1, green: 0xb2, blue: 0xc3 }); - assert.deepEqual(event!.colors[1], { colorIndex: 255, red: 0x01, green: 0xef, blue: 0x2d }); + assert.equal(event!.requests.length, 2); + assert.deepEqual(event!.requests[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); + assert.deepEqual(event!.requests[1], { index: 255, color: [0x01, 0xef, 0x2d] }); }); it('4: should be case insensitive when parsing Ansi color changes', () => { // this is testing a private method const event = inputHandler.parseAnsiColorChange('19;rGb:A1/b2/C3'); - assert.equal(event!.colors.length, 1); - assert.deepEqual(event!.colors[0], { colorIndex: 19, red: 0xa1, green: 0xb2, blue: 0xc3 }); + assert.equal(event!.requests.length, 1); + assert.deepEqual(event!.requests[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); }); it('4: should fire event on Ansi color change', async () => { return new Promise(async r => { - inputHandler.onAnsiColorChange(e => { + inputHandler.onColor(e => { assert.isNotNull(e); - assert.isNotNull(e!.colors); - assert.deepEqual(e!.colors[0], { colorIndex: 17, red: 0x1a, green: 0x2b, blue: 0x3c }); - assert.deepEqual(e!.colors[1], { colorIndex: 12, red: 0x11, green: 0x22, blue: 0x33 }); + assert.isNotNull(e!.requests); + assert.deepEqual(e!.requests[0], { index: 17, color: [0x1a, 0x2b, 0x3c] }); + assert.deepEqual(e!.requests[1], { index: 12, color: [0x11, 0x22, 0x33] }); r(); }); await inputHandler.parseP('\x1b]4;17;rgb:1a/2b/3c;12;rgb:11/22/33\x1b\\'); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 3505b548..ba51ebdd 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -4,7 +4,7 @@ * @license MIT */ -import { IInputHandler, IAttributeData, IDisposable, IWindowOptions, IAnsiColorChangeEvent, IParseStack } from 'common/Types'; +import { IInputHandler, IAttributeData, IDisposable, IWindowOptions, IColorEvent, IParseStack } from 'common/Types'; import { C0, C1 } from 'common/data/EscapeSequences'; import { CHARSETS, DEFAULT_CHARSET } from 'common/data/Charsets'; import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser'; @@ -262,8 +262,8 @@ export class InputHandler extends Disposable implements IInputHandler { public get onScroll(): IEvent { return this._onScroll.event; } private _onTitleChange = new EventEmitter(); public get onTitleChange(): IEvent { return this._onTitleChange.event; } - private _onAnsiColorChange = new EventEmitter(); - public get onAnsiColorChange(): IEvent { return this._onAnsiColorChange.event; } + private _onColor = new EventEmitter(); + public get onColor(): IEvent { return this._onColor.event; } private _parseStack: IParseStack = { paused: false, @@ -2841,22 +2841,24 @@ export class InputHandler extends Disposable implements IInputHandler { return true; } - protected _parseAnsiColorChange(data: string): IAnsiColorChangeEvent | null { - const result: IAnsiColorChangeEvent = { colors: [] }; + protected _parseAnsiColorChange(data: string): IColorEvent | null { + const result: IColorEvent = { requests: [] }; // example data: 5;rgb:aa/bb/cc const regex = /(\d+);rgb:([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})/gi; let match; while ((match = regex.exec(data)) !== null) { - result.colors.push({ - colorIndex: parseInt(match[1]), - red: parseInt(match[2], 16), - green: parseInt(match[3], 16), - blue: parseInt(match[4], 16) + result.requests.push({ + index: parseInt(match[1]), + color: [ + parseInt(match[2], 16), + parseInt(match[3], 16), + parseInt(match[4], 16) + ] }); } - if (result.colors.length === 0) { + if (result.requests.length === 0) { return null; } @@ -2923,7 +2925,7 @@ export class InputHandler extends Disposable implements IInputHandler { public setAnsiColor(data: string): boolean { const event = this._parseAnsiColorChange(data); if (event) { - this._onAnsiColorChange.fire(event); + this._onColor.fire(event); } else { this._logService.warn(`Expected format ;rgb:// but got data: ${data}`); @@ -2939,11 +2941,13 @@ export class InputHandler extends Disposable implements IInputHandler { if (slots[0] === '?') { // TODO: query FG color console.log('query FG'); + this._onColor.fire({ requests: [{ index: 256, color: '?' }] }); } else { const color = this._parseXColorName(slots[0]); if (color) { // set new FG color console.log('set FG', color); + this._onColor.fire({ requests: [{ index: 256, color }] }); } } if (slots.length === 2) { @@ -2957,11 +2961,13 @@ export class InputHandler extends Disposable implements IInputHandler { if (slots[0] === '?') { // TODO: query BG color console.log('query BG'); + this._onColor.fire({ requests: [{ index: 257, color: '?' }] }); } else { const color = this._parseXColorName(slots[0]); if (color) { // set new BG color console.log('set BG', color); + this._onColor.fire({ requests: [{ index: 257, color }] }); } } return true; diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index 78e2e62d..58adf25e 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -347,18 +347,16 @@ export interface IWindowOptions { setWinLines?: boolean; } -export interface IAnsiColorChangeEventColor { - colorIndex: number; - red: number; - green: number; - blue: number; +export interface IColorEventColor { + index: number; + color: [number, number, number] | '?'; } /** * Event fired for OSC 4 command - to change ANSI color based on its index. */ -export interface IAnsiColorChangeEvent { - colors: IAnsiColorChangeEventColor[]; +export interface IColorEvent { + requests: IColorEventColor[]; } /** From 258178fe8557f078f20e8fa232fe822945f1df6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sat, 23 Oct 2021 00:13:58 +0200 Subject: [PATCH 05/58] cleanup & docs for OSC 10/11 --- src/common/InputHandler.test.ts | 66 ++++++++++++++++----------------- src/common/InputHandler.ts | 60 +++++++++++++++++------------- 2 files changed, 68 insertions(+), 58 deletions(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index f3b0f41f..ff1879bc 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -55,8 +55,8 @@ class TestInputHandler extends InputHandler { } } - public parseXColorName(data: string): void | [number, number, number] { - return this._parseXColorName(data); + public parseColorSpec(data: string): void | [number, number, number] { + return this._parseColorSpec(data); } } @@ -1872,54 +1872,54 @@ describe('InputHandler', () => { describe('parse xcolor names', () => { it('rgb:// scheme in 4/8/12/16 bit', () => { // 4 bit - assert.deepEqual(inputHandler.parseXColorName('rgb:0/0/0'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseXColorName('rgb:f/f/f'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseXColorName('rgb:1/2/3'), [17, 34, 51]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:0/0/0'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:f/f/f'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:1/2/3'), [17, 34, 51]); // 8 bit - assert.deepEqual(inputHandler.parseXColorName('rgb:00/00/00'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseXColorName('rgb:ff/ff/ff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseXColorName('rgb:11/22/33'), [17, 34, 51]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:00/00/00'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:ff/ff/ff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:11/22/33'), [17, 34, 51]); // 12 bit - assert.deepEqual(inputHandler.parseXColorName('rgb:000/000/000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseXColorName('rgb:fff/fff/fff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseXColorName('rgb:111/222/333'), [17, 34, 51]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:000/000/000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:fff/fff/fff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:111/222/333'), [17, 34, 51]); // 16 bit - assert.deepEqual(inputHandler.parseXColorName('rgb:0000/0000/0000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseXColorName('rgb:ffff/ffff/ffff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseXColorName('rgb:1111/2222/3333'), [17, 34, 51]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:0000/0000/0000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:ffff/ffff/ffff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseColorSpec('rgb:1111/2222/3333'), [17, 34, 51]); }); it('#RGB scheme in 4/8/12/16 bit', () => { // 4 bit - assert.deepEqual(inputHandler.parseXColorName('#000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseXColorName('#fff'), [240, 240, 240]); - assert.deepEqual(inputHandler.parseXColorName('#123'), [16, 32, 48]); + assert.deepEqual(inputHandler.parseColorSpec('#000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseColorSpec('#fff'), [240, 240, 240]); + assert.deepEqual(inputHandler.parseColorSpec('#123'), [16, 32, 48]); // 8 bit - assert.deepEqual(inputHandler.parseXColorName('#000000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseXColorName('#ffffff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseXColorName('#112233'), [17, 34, 51]); + assert.deepEqual(inputHandler.parseColorSpec('#000000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseColorSpec('#ffffff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseColorSpec('#112233'), [17, 34, 51]); // 12 bit - assert.deepEqual(inputHandler.parseXColorName('#000000000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseXColorName('#fffffffff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseXColorName('#111222333'), [17, 34, 51]); + assert.deepEqual(inputHandler.parseColorSpec('#000000000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseColorSpec('#fffffffff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseColorSpec('#111222333'), [17, 34, 51]); // 16 bit - assert.deepEqual(inputHandler.parseXColorName('#000000000000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseXColorName('#ffffffffffff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseXColorName('#111122223333'), [17, 34, 51]); + assert.deepEqual(inputHandler.parseColorSpec('#000000000000'), [0, 0, 0]); + assert.deepEqual(inputHandler.parseColorSpec('#ffffffffffff'), [255, 255, 255]); + assert.deepEqual(inputHandler.parseColorSpec('#111122223333'), [17, 34, 51]); }); it('supports upper case', () => { - assert.deepEqual(inputHandler.parseXColorName('RGB:0/A/F'), [0, 170, 255]); - assert.deepEqual(inputHandler.parseXColorName('#FFF'), [240, 240, 240]); + assert.deepEqual(inputHandler.parseColorSpec('RGB:0/A/F'), [0, 170, 255]); + assert.deepEqual(inputHandler.parseColorSpec('#FFF'), [240, 240, 240]); }); it('does not parse illegal combinations', () => { // shifting bit width - assert.equal(inputHandler.parseXColorName('rgb:0/11/222'), undefined); + assert.equal(inputHandler.parseColorSpec('rgb:0/11/222'), undefined); // unsupported scheme - assert.equal(inputHandler.parseXColorName('rgbi:00/11/22'), undefined); + assert.equal(inputHandler.parseColorSpec('rgbi:00/11/22'), undefined); // broken # specifier - assert.equal(inputHandler.parseXColorName('#aabbbcc'), undefined); + assert.equal(inputHandler.parseColorSpec('#aabbbcc'), undefined); // out of range - assert.equal(inputHandler.parseXColorName('#aabbgg'), undefined); - assert.equal(inputHandler.parseXColorName('rgb:aa/bb/gg'), undefined); + assert.equal(inputHandler.parseColorSpec('#aabbgg'), undefined); + assert.equal(inputHandler.parseColorSpec('rgb:aa/bb/gg'), undefined); }); }); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index ba51ebdd..f206ac8b 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -2866,7 +2866,7 @@ export class InputHandler extends Disposable implements IInputHandler { } /** - * Parse xcolor name to RGB values (8 bit per channel). + * Parse color spec to RGB values (8 bit per channel). * See `man xparsecolor` for details about certain format specifications. * * Supported formats: @@ -2876,7 +2876,7 @@ export class InputHandler extends Disposable implements IInputHandler { * All other formats like rgbi: or device-independent string specifications * with float numbering are not supported. */ - protected _parseXColorName(data: string): [number, number, number] | void { + protected _parseColorSpec(data: string): [number, number, number] | void { // also handle uppercases data = data.toLowerCase(); if (data.indexOf('rgb:') === 0) { @@ -2898,19 +2898,12 @@ export class InputHandler extends Disposable implements IInputHandler { const rex = /^[\da-f]+$/; if (rex.exec(data) && [3, 6, 9, 12].includes(data.length)) { const adv = data.length / 3; - const r = parseInt(data.slice(0, adv), 16); - const g = parseInt(data.slice(adv, 2 * adv), 16); - const b = parseInt(data.slice(2 * adv, 3 * adv), 16); - switch (adv) { - case 1: - return [r << 4, g << 4, b << 4]; - case 2: - return [r, g, b]; - case 3: - return [r >> 4, g >> 4, b >> 4]; - case 4: - return [r >> 8, g >> 8, b >> 8]; + const result: [number, number, number] = [0, 0, 0]; + for (let i = 0; i < 3; ++i) { + const c = parseInt(data.slice(adv * i, adv * i + adv), 16); + result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8; } + return result; } } } @@ -2933,20 +2926,36 @@ export class InputHandler extends Disposable implements IInputHandler { return true; } + /** + * OSC 10 ; | ST - set or query default foreground color + * + * @vt: #Y OSC 10 "Set or query default foreground color" "OSC 10 ; Pt BEL" "Set or query default foreground color." + * To set the color, the following color specification formats are supported: + * - `rgb://` for `, , ` in `h | hh | hhh | hhhh`, where + * `h` is a single hexadecimal digit (case insignificant). The different widths scale + * from 4 bit (`h`) to 16 bit (`hhhh`) and get converted to 8 bit (`hh`). + * - `#RGB` - 4 bits per channel, expanded to `#R0G0B0` + * - `#RRGGBB` - 8 bits per channel + * - `#RRRGGGBBB` - 12 bits per channel, truncated to `#RRGGBB` + * - `#RRRRGGGGBBBB` - 16 bits per channel, truncated to `#RRGGBB` + * + * If `Pt` contains `?` instead of a color specification, the terminal + * returns a sequence with the current default foreground color + * (use that sequence to restore the color after changes). + * + * **Note:** Other than xterm, xterm.js does not support OSC 12 - 19. + * Therefore stacking multiple `Pt` separated by `;` only works for the first two entries. + */ public queryOrSetFgColor(data: string): boolean { // note: data may contain multiple ? or color names separated with ; // Multiple values will map through to OSC 10 - 19, but we only support 10 and 11 currently, - // thus truncate to max. 2 occurences. + // thus truncate to max. 2 entries. const slots = data.split(';').slice(0, 2); if (slots[0] === '?') { - // TODO: query FG color - console.log('query FG'); this._onColor.fire({ requests: [{ index: 256, color: '?' }] }); } else { - const color = this._parseXColorName(slots[0]); + const color = this._parseColorSpec(slots[0]); if (color) { - // set new FG color - console.log('set FG', color); this._onColor.fire({ requests: [{ index: 256, color }] }); } } @@ -2956,17 +2965,18 @@ export class InputHandler extends Disposable implements IInputHandler { return true; } + /** + * OSC 11 ; | ST - set or query default background color + * + * @vt: #Y OSC 11 "Set or query default background color" "OSC 11 ; Pt BEL" "Same as OSC 10, but for default background." + */ public queryOrSetBgColor(data: string): boolean { const slots = data.split(';').slice(0, 1); if (slots[0] === '?') { - // TODO: query BG color - console.log('query BG'); this._onColor.fire({ requests: [{ index: 257, color: '?' }] }); } else { - const color = this._parseXColorName(slots[0]); + const color = this._parseColorSpec(slots[0]); if (color) { - // set new BG color - console.log('set BG', color); this._onColor.fire({ requests: [{ index: 257, color }] }); } } From 9eb72ee0cc2c256482d69e3309691542628d2c68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sat, 23 Oct 2021 00:22:55 +0200 Subject: [PATCH 06/58] report 16 bit color spec for query --- src/browser/Color.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/Color.ts b/src/browser/Color.ts index 42a65876..2e71c9e6 100644 --- a/src/browser/Color.ts +++ b/src/browser/Color.ts @@ -88,7 +88,7 @@ export namespace color { export function toXColorName(color: IColor): string { const [r, g, b] = rgba.toChannels(color.rgba); - return `rgb:${toPaddedHex(r)}/${toPaddedHex(g)}/${toPaddedHex(b)}`; + return `rgb:${toPaddedHex(r)}${toPaddedHex(r)}/${toPaddedHex(g)}${toPaddedHex(g)}/${toPaddedHex(b)}${toPaddedHex(b)}`; } } From 0871ace481232eaf9d497a64fef91429b610effa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 25 Oct 2021 00:21:33 +0200 Subject: [PATCH 07/58] create minified color names module --- fixtures/x11-colornames/README.md | 14 + fixtures/x11-colornames/create_module.js | 447 ++++++++++++++ fixtures/x11-colornames/rgb.txt | 754 +++++++++++++++++++++++ src/common/InputHandler.ts | 21 +- src/common/data/ColorNames.ts | 91 +++ 5 files changed, 1318 insertions(+), 9 deletions(-) create mode 100644 fixtures/x11-colornames/README.md create mode 100644 fixtures/x11-colornames/create_module.js create mode 100644 fixtures/x11-colornames/rgb.txt create mode 100644 src/common/data/ColorNames.ts diff --git a/fixtures/x11-colornames/README.md b/fixtures/x11-colornames/README.md new file mode 100644 index 00000000..ee6d7b6d --- /dev/null +++ b/fixtures/x11-colornames/README.md @@ -0,0 +1,14 @@ +### Fixture for 11 color names + +`rgb.txt` contains X11's defined color names, copied over from `/etc/X11/rgb.txt` on Ubuntu 18. + +Run `create_module.js` to create a TS module containing the color definitions. The script performs these steps: +- extract color definitions from `rgb.txt` +- remove gray definitions (re-added programmatically later) +- create a perfect hash function +- calculate crc10 for basic collision prevention +- run several collision tests +- compress table and color data +- write data with loading shim to `ColorNames.ts` + +The final file is meant to be copied over to `../../src/common/data/`. diff --git a/fixtures/x11-colornames/create_module.js b/fixtures/x11-colornames/create_module.js new file mode 100644 index 00000000..edc1f314 --- /dev/null +++ b/fixtures/x11-colornames/create_module.js @@ -0,0 +1,447 @@ +const fs = require('fs'); +const path = require('path'); + +/** + * For decoder side: + * - reconstruct grays with f = lambda x: (x * 256 - x + 50) / 100 (needs value rounding check) + * - apply nameFilter + * - build lookup & extract functions (runtime decoding?) + * - transfer hashtable and color table + */ + +// match color entry in rgb.txt +const rexFile = /^\s*(\d+)\s*(\d+)\s*(\d+)\s*?[\t]+(.*)$/; +// match greyXX|grayXX names +const rexGrey = /^gr[ae]y\d+/; +// name match +const rexName = /^\w?[A-Za-z0-9 ]+\w/; + +function parseX11Colors(filename) { + const fileData = fs.readFileSync(filename, {encoding: 'utf8'}); + const colors = []; + for (const line of fileData.split('\n')) { + const m = rexFile.exec(line); + if (m) { + colors.push({ + color: [parseInt(m[1]), parseInt(m[2]), parseInt(m[3])], + name: m[4] + }); + } + } + return colors; +} + +// Use the FNV algorithm from http://isthe.com/chongo/tech/comp/fnv/ +function hash(d, name) { + if (!d) d = 0x01000193; + for (const c of name) { + d = ( (d * 0x01000193) ^ c.charCodeAt(0) ) & 0xffffffff; + } + return d >>> 0; +} + +// inspired from http://stevehanov.ca/blog/?id=119 +function createMinimalPerfectHash(nameList) { + const nameMap = Object.create(null); + for (const [idx, name] of nameList.entries()) { + nameMap[name] = idx; + } + const size = nameList.length; + + const buckets = []; + for (let i = 0; i < size; ++i) buckets.push([]); + const g = new Array(size).fill(0); + const v = new Array(size).fill(null); + + for (const key of nameList) { + buckets[hash(0, key) % size].push(key); + } + + buckets.sort((a, b) => b.length - a.length); + let breakIdx = 0; + for (let i = 0; i < size; ++i) { + const bucket = buckets[i]; + if (bucket.length <= 1) { + breakIdx = i; + break; + } + let d = 1; + let item = 0; + let slots = []; + + while (item < bucket.length) { + const slot = hash(d, bucket[item]) % size; + if (v[slot] !== null || slots.includes(slot)) { + d++; + item = 0; + slots = []; + } else { + slots.push(slot); + item++; + } + } + + g[hash(0, bucket[0]) % size] = d; + for (let k = 0; k < bucket.length; ++k) { + v[slots[k]] = nameMap[bucket[k]]; + } + } + + const freeList = []; + for (let i = 0; i < size; ++i) { + if (v[i] === null) freeList.push(i); + } + + for (let i = breakIdx; i < size; ++i) { + const bucket = buckets[i]; + if (!bucket.length) break; + const slot = freeList.pop(); + g[hash(0, bucket[0]) % size] = -slot - 1; + v[slot] = nameMap[bucket[0]]; + } + + return [g, v]; +} + +function lookupPerfectHash(g, v, key) { + const d = g[hash(0, key) % g.length]; + if (d < 0) return v[-d - 1]; + return v[hash(d, key) % v.length]; +} + +function checkPerfectHashTables(g, v, nameList) { + let allPassed = true; + for (const [idx, name] of nameList.entries()) { + const lookup = lookupPerfectHash(g, v, name); + if (lookup !== idx) { + console.log(`\x1b[33mmismatch: '${name}' returns ${lookup} (orig: ${idx})\x1b[m`); + allPassed = false; + } + } + return allPassed; +} + +function crc10atm(name, crc) { + if (!crc) crc = 0; + for (const c of name) { + const v = c.charCodeAt(0); + crc ^= v << 2; + for (let k = 0; k < 8; k++) { + crc = crc & 0x200 ? (crc << 1) ^ 0x233 : crc << 1; + } + } + crc &= 0x3ff; + return crc >>> 0; +} + +function checkColorList(g, v, crc, colorNames) { + let match = []; + for (const word of colorNames) { + if (!nameFilter(word)) continue; + const idx = lookupPerfectHash(g, v, word); + const crc10 = crc10atm(word); + if (crc[idx] === crc10) { + match.push({idx, word, colorName: colorNames[idx]}); + } + } + return {tested: colorNames.length, match}; +} + +function checkWordlists(g, v, crc, colorNames, filename) { + const fileData = fs.readFileSync(filename, {encoding: 'utf8'}); + const words = fileData.split('\n').filter(el => lookupPerfectHash.length !== 0); + let collisions = []; + for (const word of words) { + if (!nameFilter(word)) continue; + const idx = lookupPerfectHash(g, v, word); + const crc10 = crc10atm(word); + if (crc[idx] === crc10 && word !== colorNames[idx]) { + collisions.push({idx, word, colorName: colorNames[idx]}); + } + } + return {tested: words.length, collisions}; +} + +function nameFilter(name) { + // length 3 - 22 + if (name.length < 3 || name.length > 22) return; + // chars only in [A-Za-z0-9 ] + if (!rexName.exec(name)) return; + return name; +} + +function compressTables(g, v, crc, al) { + // g | v | crc: all in 10 bit (<1024) + // --> 30 bit + // --> fits into 5 bytes of a 64-bit char alphabet + + // g needs an offset for proper zero alignment + const gOffset = -Math.min(...g); + g = g.map(el => el + gOffset); + + // assert we are in 0..2^10 + if (Math.min(...g) < 0 || Math.min(...v) < 0 || Math.min(...crc) < 0 + || Math.max(...g) > 1023 || Math.max(...v) > 1023 || Math.max(...crc) > 1023 + ) { + console.log('\x1b[31mTables out of compressible range, manual fix needed.\x1b[m'); + process.exit(1); + } + + // assert we have same length + if (g.length !== v.length || g.length !== crc.length) { + console.log('\x1b[31mTables length mismatch, manual fix needed.\x1b[m'); + process.exit(1); + } + + // construct compressed data string + let result = ''; + const length = g.length; + for (let i = 0; i < length; ++i) { + let value = (g[i] << 20) | (v[i] << 10) | crc[i]; + let bucket = ''; + for (let k = 0; k < 5; ++k) { + bucket += al[value % al.length]; + value = Math.floor(value / al.length); + } + result += bucket.split('').reverse().join(''); + } + + return [result, length, gOffset]; +} + +function compressColors(colors, al) { + let result = ''; + for (const color of colors) { + let value = (color[0] << 16) | (color[1] << 8) | color[2]; + let bucket = ''; + for (let k = 0; k < 4; ++k) { + bucket += al[value % al.length]; + value = Math.floor(value / al.length); + } + result += bucket.split('').reverse().join(''); + } + return result; +} + +function loadData(bucket, al) { + let value = 0; + for (const c of bucket) { + value *= al.length; + value += al.indexOf(c); + } + return [value >>> 20, (value >> 10) & 0x3FF, value & 0x3FF]; +} + +function loadColor(al, data, idx) { + // color buckets are hardcoded to 4 chars + let value = 0; + for (let i = idx * 4; i < idx * 4 + 4; ++i) { + value *= al.length; + value += al.indexOf(data[i]); + } + return [value >>> 16, (value >> 8) & 0xFF, value & 0xFF]; +} + +function lookupIdx(al, data, length, gOffset, name) { + const bl = data.length / length; + let offset = (hash(0, name) % length) * bl; + let [g, v, crc] = loadData(data.slice(offset, offset + bl), al); + offset = g < gOffset + ? (-(g - gOffset) - 1) * bl + : (hash(g - gOffset, name) % length) * bl; + [_, v, _] = loadData(data.slice(offset, offset + bl), al); + offset = v * bl; + [_, _, crc] = loadData(data.slice(offset, offset + bl), al); + return crc10atm(name) === crc ? v : -1; +} + +function lookup(al, data, colorData, length, gOffset, name) { + const idx = lookupIdx(al, data, length, gOffset, name); + if (idx === -1) return; + return loadColor(al, colorData, idx); +} + +function createModule(tableData, colorData, alphabet, gOffset, length) { + const TMPL = `/** + * Copyright (c) 2021 The xterm.js authors. All rights reserved. + * @license MIT + */ + +/** + * This module enables X11 color name lookups with the help of a perfect hash function + * to not penalize the package size too much. + * saving: ~70% (from 17kB down to 5kB) + */ + +// Note: module and table data created with fixtures/x11-colornames/create_module.js +const TABLE = '${tableData}'; +const COLORS = '${colorData}'; +const ALPHABET = '${alphabet}'; +const OFFSET = ${gOffset}; +const LENGTH = ${length}; +const BUCKET_LENGTH = TABLE.length / LENGTH; + +// match greyXX|grayXX names +const rexGrey = /^gr[ae]y(\\d+)/; +// name match +const rexName = /^\\w?[A-Za-z0-9 ]+\\w/; + +function gray(n: number): [number, number, number] | undefined { + if (0 <= n && n <= 100) { + const v = Math.floor((n * 256 - n + 50) / 100); + return [v, v, v]; + } + return; +} + +function hash(d: number, name: string): number { + if (!d) d = 0x01000193; + for (const c of name) { + d = ((d * 0x01000193) ^ c.charCodeAt(0)) & 0xffffffff; + } + return d >>> 0; +} + +function crc10(name: string, crc?: number): number { + if (!crc) crc = 0; + for (const c of name) { + crc ^= c.charCodeAt(0) << 2; + for (let k = 0; k < 8; k++) { + crc = crc & 0x200 ? (crc << 1) ^ 0x233 : crc << 1; + } + } + crc &= 0x3ff; + return crc >>> 0; +} + +function loadData(idx: number): [number, number, number] { + let value = 0; + for (let i = idx * BUCKET_LENGTH; i < idx * BUCKET_LENGTH + BUCKET_LENGTH; ++i) { + value *= ALPHABET.length; + value += ALPHABET.indexOf(TABLE[i]); + } + return [value >>> 20, (value >> 10) & 0x3FF, value & 0x3FF]; +} + +function loadColor(idx: number): [number, number, number] { + // color buckets are hardcoded to 4 chars + let v = 0; + for (let i = idx * 4; i < idx * 4 + 4; ++i) { + v *= ALPHABET.length; + v += ALPHABET.indexOf(COLORS[i]); + } + return [v >>> 16, (v >> 8) & 0xFF, v & 0xFF]; +} + +function lookupIdx(name: string): number { + let b = loadData(hash(0, name) % LENGTH); + b = loadData(b[0] < OFFSET ? (-(b[0] - OFFSET) - 1) : hash(b[0] - OFFSET, name) % LENGTH); + const [ , , crc] = loadData(b[1]); + return crc10(name) === crc ? b[1] : -1; +} + +export function getColorFromName(name: string): [number, number, number] | undefined { + // basic name filtering + if (name.length < 3 || name.length > 22 || !rexName.exec(name)) return; + + // handle grays special + const m = rexGrey.exec(name); + if (m) return gray(parseInt(m[1])); + + // grab crc checked idx from PHF + const idx = lookupIdx(name); + if (idx === -1) return; + return loadColor(idx); +} +`; + return TMPL; +} + + +function main() { + // parse definitions from X11 file + const colorList = parseX11Colors(path.join(__dirname, '/rgb.txt')) + .filter(el => !rexGrey.exec(el.name)); // remove greys, as we can reconstruct them later + const nameList = colorList.map(el => el.name); + + // PHF creation and test + const [g, v] = createMinimalPerfectHash(nameList); + if (!checkPerfectHashTables(g, v, nameList)) { + console.error('\x1b[31mPHF creation failed.\x1b[m'); + process.exit(1); + } else { + console.log('\x1b[32mPHF creation successful.\x1b[m'); + } + + // calc 10-bit CRCs to rule to avoid collisions at ~1:1024 + const crc = nameList.map(el => crc10atm(el)); + + // collision check against colorNames - must all collide + console.log('Self collision test:') + const collSelf = checkColorList(g, v, crc, nameList); + console.log('self:', { + entries: collSelf.tested, + matches: collSelf.match.length, + rate: collSelf.tested / collSelf.match.length + }); + if (collSelf.match.length !== collSelf.tested) { + console.error('\x1b[31mSelf collision tested failed.\x1b[m'); + process.exit(1); + } + + // basic collision checks against dictionaries (rates should be greater than 900:1) + console.log('Dictionary collision test:') + const collEnglish = checkWordlists(g, v, crc, nameList, '/usr/share/dict/words'); + console.log('english:', { + entries: collEnglish.tested, + collisions: collEnglish.collisions.length, + rate: collEnglish.tested / collEnglish.collisions.length + }); + //console.log(collEnglish.collisions); + const collnGerman = checkWordlists(g, v, crc, nameList, '/usr/share/dict/ngerman'); + console.log('ngerman:', { + entries: collnGerman.tested, + collisions: collnGerman.collisions.length, + rate: collnGerman.tested / collnGerman.collisions.length + }); + const colloGerman = checkWordlists(g, v, crc, nameList, '/usr/share/dict/ogerman'); + console.log('ogerman:', { + entries: colloGerman.tested, + collisions: colloGerman.collisions.length, + rate: colloGerman.tested / colloGerman.collisions.length + }); + + // compression with custom alphabet + const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?'; + const [tableData, length, gOffset] = compressTables(g, v, crc, ALPHABET); + const colorData = compressColors(colorList.map(el => el.color), ALPHABET); + + // test loading of compressed table data + let failed = false; + for (const name of nameList) { + const orig = lookupPerfectHash(g, v, name); + const idx = lookupIdx(ALPHABET, tableData, length, gOffset, name); + if (idx !== orig) { + console.log('\x1b[31mcompressed loading failed for:\x1b[m', {name, idx, orig}); + failed = true; + } + } + if (failed) process.exit(1); + + // test full color decoding + for (const color of colorList) { + const loaded = lookup(ALPHABET, tableData, colorData, length, gOffset, color.name); + if (loaded[0] !== color.color[0] || loaded[1] !== color.color[1] || loaded[2] !== color.color[2]) { + console.log('\x1b[31mcolor loading failed for:\x1b[m', {color, loaded}); + failed = true; + } + } + if (failed) process.exit(1); + + // if we made it up to here, create decoding boilerplate + const moduleData = createModule(tableData, colorData, ALPHABET, gOffset, length); + fs.writeFileSync(path.join(__dirname, '/ColorNames.ts'), moduleData); + console.log(`${moduleData.length} bytes written to ${path.join(__dirname, '/ColorNames.ts')}`); +} + +main(); diff --git a/fixtures/x11-colornames/rgb.txt b/fixtures/x11-colornames/rgb.txt new file mode 100644 index 00000000..b9e56c60 --- /dev/null +++ b/fixtures/x11-colornames/rgb.txt @@ -0,0 +1,754 @@ +! $Xorg: rgb.txt,v 1.3 2000/08/17 19:54:00 cpqbld Exp $ +255 250 250 snow +248 248 255 ghost white +248 248 255 GhostWhite +245 245 245 white smoke +245 245 245 WhiteSmoke +220 220 220 gainsboro +255 250 240 floral white +255 250 240 FloralWhite +253 245 230 old lace +253 245 230 OldLace +250 240 230 linen +250 235 215 antique white +250 235 215 AntiqueWhite +255 239 213 papaya whip +255 239 213 PapayaWhip +255 235 205 blanched almond +255 235 205 BlanchedAlmond +255 228 196 bisque +255 218 185 peach puff +255 218 185 PeachPuff +255 222 173 navajo white +255 222 173 NavajoWhite +255 228 181 moccasin +255 248 220 cornsilk +255 255 240 ivory +255 250 205 lemon chiffon +255 250 205 LemonChiffon +255 245 238 seashell +240 255 240 honeydew +245 255 250 mint cream +245 255 250 MintCream +240 255 255 azure +240 248 255 alice blue +240 248 255 AliceBlue +230 230 250 lavender +255 240 245 lavender blush +255 240 245 LavenderBlush +255 228 225 misty rose +255 228 225 MistyRose +255 255 255 white + 0 0 0 black + 47 79 79 dark slate gray + 47 79 79 DarkSlateGray + 47 79 79 dark slate grey + 47 79 79 DarkSlateGrey +105 105 105 dim gray +105 105 105 DimGray +105 105 105 dim grey +105 105 105 DimGrey +112 128 144 slate gray +112 128 144 SlateGray +112 128 144 slate grey +112 128 144 SlateGrey +119 136 153 light slate gray +119 136 153 LightSlateGray +119 136 153 light slate grey +119 136 153 LightSlateGrey +190 190 190 gray +190 190 190 grey +211 211 211 light grey +211 211 211 LightGrey +211 211 211 light gray +211 211 211 LightGray + 25 25 112 midnight blue + 25 25 112 MidnightBlue + 0 0 128 navy + 0 0 128 navy blue + 0 0 128 NavyBlue +100 149 237 cornflower blue +100 149 237 CornflowerBlue + 72 61 139 dark slate blue + 72 61 139 DarkSlateBlue +106 90 205 slate blue +106 90 205 SlateBlue +123 104 238 medium slate blue +123 104 238 MediumSlateBlue +132 112 255 light slate blue +132 112 255 LightSlateBlue + 0 0 205 medium blue + 0 0 205 MediumBlue + 65 105 225 royal blue + 65 105 225 RoyalBlue + 0 0 255 blue + 30 144 255 dodger blue + 30 144 255 DodgerBlue + 0 191 255 deep sky blue + 0 191 255 DeepSkyBlue +135 206 235 sky blue +135 206 235 SkyBlue +135 206 250 light sky blue +135 206 250 LightSkyBlue + 70 130 180 steel blue + 70 130 180 SteelBlue +176 196 222 light steel blue +176 196 222 LightSteelBlue +173 216 230 light blue +173 216 230 LightBlue +176 224 230 powder blue +176 224 230 PowderBlue +175 238 238 pale turquoise +175 238 238 PaleTurquoise + 0 206 209 dark turquoise + 0 206 209 DarkTurquoise + 72 209 204 medium turquoise + 72 209 204 MediumTurquoise + 64 224 208 turquoise + 0 255 255 cyan +224 255 255 light cyan +224 255 255 LightCyan + 95 158 160 cadet blue + 95 158 160 CadetBlue +102 205 170 medium aquamarine +102 205 170 MediumAquamarine +127 255 212 aquamarine + 0 100 0 dark green + 0 100 0 DarkGreen + 85 107 47 dark olive green + 85 107 47 DarkOliveGreen +143 188 143 dark sea green +143 188 143 DarkSeaGreen + 46 139 87 sea green + 46 139 87 SeaGreen + 60 179 113 medium sea green + 60 179 113 MediumSeaGreen + 32 178 170 light sea green + 32 178 170 LightSeaGreen +152 251 152 pale green +152 251 152 PaleGreen + 0 255 127 spring green + 0 255 127 SpringGreen +124 252 0 lawn green +124 252 0 LawnGreen + 0 255 0 green +127 255 0 chartreuse + 0 250 154 medium spring green + 0 250 154 MediumSpringGreen +173 255 47 green yellow +173 255 47 GreenYellow + 50 205 50 lime green + 50 205 50 LimeGreen +154 205 50 yellow green +154 205 50 YellowGreen + 34 139 34 forest green + 34 139 34 ForestGreen +107 142 35 olive drab +107 142 35 OliveDrab +189 183 107 dark khaki +189 183 107 DarkKhaki +240 230 140 khaki +238 232 170 pale goldenrod +238 232 170 PaleGoldenrod +250 250 210 light goldenrod yellow +250 250 210 LightGoldenrodYellow +255 255 224 light yellow +255 255 224 LightYellow +255 255 0 yellow +255 215 0 gold +238 221 130 light goldenrod +238 221 130 LightGoldenrod +218 165 32 goldenrod +184 134 11 dark goldenrod +184 134 11 DarkGoldenrod +188 143 143 rosy brown +188 143 143 RosyBrown +205 92 92 indian red +205 92 92 IndianRed +139 69 19 saddle brown +139 69 19 SaddleBrown +160 82 45 sienna +205 133 63 peru +222 184 135 burlywood +245 245 220 beige +245 222 179 wheat +244 164 96 sandy brown +244 164 96 SandyBrown +210 180 140 tan +210 105 30 chocolate +178 34 34 firebrick +165 42 42 brown +233 150 122 dark salmon +233 150 122 DarkSalmon +250 128 114 salmon +255 160 122 light salmon +255 160 122 LightSalmon +255 165 0 orange +255 140 0 dark orange +255 140 0 DarkOrange +255 127 80 coral +240 128 128 light coral +240 128 128 LightCoral +255 99 71 tomato +255 69 0 orange red +255 69 0 OrangeRed +255 0 0 red +255 105 180 hot pink +255 105 180 HotPink +255 20 147 deep pink +255 20 147 DeepPink +255 192 203 pink +255 182 193 light pink +255 182 193 LightPink +219 112 147 pale violet red +219 112 147 PaleVioletRed +176 48 96 maroon +199 21 133 medium violet red +199 21 133 MediumVioletRed +208 32 144 violet red +208 32 144 VioletRed +255 0 255 magenta +238 130 238 violet +221 160 221 plum +218 112 214 orchid +186 85 211 medium orchid +186 85 211 MediumOrchid +153 50 204 dark orchid +153 50 204 DarkOrchid +148 0 211 dark violet +148 0 211 DarkViolet +138 43 226 blue violet +138 43 226 BlueViolet +160 32 240 purple +147 112 219 medium purple +147 112 219 MediumPurple +216 191 216 thistle +255 250 250 snow1 +238 233 233 snow2 +205 201 201 snow3 +139 137 137 snow4 +255 245 238 seashell1 +238 229 222 seashell2 +205 197 191 seashell3 +139 134 130 seashell4 +255 239 219 AntiqueWhite1 +238 223 204 AntiqueWhite2 +205 192 176 AntiqueWhite3 +139 131 120 AntiqueWhite4 +255 228 196 bisque1 +238 213 183 bisque2 +205 183 158 bisque3 +139 125 107 bisque4 +255 218 185 PeachPuff1 +238 203 173 PeachPuff2 +205 175 149 PeachPuff3 +139 119 101 PeachPuff4 +255 222 173 NavajoWhite1 +238 207 161 NavajoWhite2 +205 179 139 NavajoWhite3 +139 121 94 NavajoWhite4 +255 250 205 LemonChiffon1 +238 233 191 LemonChiffon2 +205 201 165 LemonChiffon3 +139 137 112 LemonChiffon4 +255 248 220 cornsilk1 +238 232 205 cornsilk2 +205 200 177 cornsilk3 +139 136 120 cornsilk4 +255 255 240 ivory1 +238 238 224 ivory2 +205 205 193 ivory3 +139 139 131 ivory4 +240 255 240 honeydew1 +224 238 224 honeydew2 +193 205 193 honeydew3 +131 139 131 honeydew4 +255 240 245 LavenderBlush1 +238 224 229 LavenderBlush2 +205 193 197 LavenderBlush3 +139 131 134 LavenderBlush4 +255 228 225 MistyRose1 +238 213 210 MistyRose2 +205 183 181 MistyRose3 +139 125 123 MistyRose4 +240 255 255 azure1 +224 238 238 azure2 +193 205 205 azure3 +131 139 139 azure4 +131 111 255 SlateBlue1 +122 103 238 SlateBlue2 +105 89 205 SlateBlue3 + 71 60 139 SlateBlue4 + 72 118 255 RoyalBlue1 + 67 110 238 RoyalBlue2 + 58 95 205 RoyalBlue3 + 39 64 139 RoyalBlue4 + 0 0 255 blue1 + 0 0 238 blue2 + 0 0 205 blue3 + 0 0 139 blue4 + 30 144 255 DodgerBlue1 + 28 134 238 DodgerBlue2 + 24 116 205 DodgerBlue3 + 16 78 139 DodgerBlue4 + 99 184 255 SteelBlue1 + 92 172 238 SteelBlue2 + 79 148 205 SteelBlue3 + 54 100 139 SteelBlue4 + 0 191 255 DeepSkyBlue1 + 0 178 238 DeepSkyBlue2 + 0 154 205 DeepSkyBlue3 + 0 104 139 DeepSkyBlue4 +135 206 255 SkyBlue1 +126 192 238 SkyBlue2 +108 166 205 SkyBlue3 + 74 112 139 SkyBlue4 +176 226 255 LightSkyBlue1 +164 211 238 LightSkyBlue2 +141 182 205 LightSkyBlue3 + 96 123 139 LightSkyBlue4 +198 226 255 SlateGray1 +185 211 238 SlateGray2 +159 182 205 SlateGray3 +108 123 139 SlateGray4 +202 225 255 LightSteelBlue1 +188 210 238 LightSteelBlue2 +162 181 205 LightSteelBlue3 +110 123 139 LightSteelBlue4 +191 239 255 LightBlue1 +178 223 238 LightBlue2 +154 192 205 LightBlue3 +104 131 139 LightBlue4 +224 255 255 LightCyan1 +209 238 238 LightCyan2 +180 205 205 LightCyan3 +122 139 139 LightCyan4 +187 255 255 PaleTurquoise1 +174 238 238 PaleTurquoise2 +150 205 205 PaleTurquoise3 +102 139 139 PaleTurquoise4 +152 245 255 CadetBlue1 +142 229 238 CadetBlue2 +122 197 205 CadetBlue3 + 83 134 139 CadetBlue4 + 0 245 255 turquoise1 + 0 229 238 turquoise2 + 0 197 205 turquoise3 + 0 134 139 turquoise4 + 0 255 255 cyan1 + 0 238 238 cyan2 + 0 205 205 cyan3 + 0 139 139 cyan4 +151 255 255 DarkSlateGray1 +141 238 238 DarkSlateGray2 +121 205 205 DarkSlateGray3 + 82 139 139 DarkSlateGray4 +127 255 212 aquamarine1 +118 238 198 aquamarine2 +102 205 170 aquamarine3 + 69 139 116 aquamarine4 +193 255 193 DarkSeaGreen1 +180 238 180 DarkSeaGreen2 +155 205 155 DarkSeaGreen3 +105 139 105 DarkSeaGreen4 + 84 255 159 SeaGreen1 + 78 238 148 SeaGreen2 + 67 205 128 SeaGreen3 + 46 139 87 SeaGreen4 +154 255 154 PaleGreen1 +144 238 144 PaleGreen2 +124 205 124 PaleGreen3 + 84 139 84 PaleGreen4 + 0 255 127 SpringGreen1 + 0 238 118 SpringGreen2 + 0 205 102 SpringGreen3 + 0 139 69 SpringGreen4 + 0 255 0 green1 + 0 238 0 green2 + 0 205 0 green3 + 0 139 0 green4 +127 255 0 chartreuse1 +118 238 0 chartreuse2 +102 205 0 chartreuse3 + 69 139 0 chartreuse4 +192 255 62 OliveDrab1 +179 238 58 OliveDrab2 +154 205 50 OliveDrab3 +105 139 34 OliveDrab4 +202 255 112 DarkOliveGreen1 +188 238 104 DarkOliveGreen2 +162 205 90 DarkOliveGreen3 +110 139 61 DarkOliveGreen4 +255 246 143 khaki1 +238 230 133 khaki2 +205 198 115 khaki3 +139 134 78 khaki4 +255 236 139 LightGoldenrod1 +238 220 130 LightGoldenrod2 +205 190 112 LightGoldenrod3 +139 129 76 LightGoldenrod4 +255 255 224 LightYellow1 +238 238 209 LightYellow2 +205 205 180 LightYellow3 +139 139 122 LightYellow4 +255 255 0 yellow1 +238 238 0 yellow2 +205 205 0 yellow3 +139 139 0 yellow4 +255 215 0 gold1 +238 201 0 gold2 +205 173 0 gold3 +139 117 0 gold4 +255 193 37 goldenrod1 +238 180 34 goldenrod2 +205 155 29 goldenrod3 +139 105 20 goldenrod4 +255 185 15 DarkGoldenrod1 +238 173 14 DarkGoldenrod2 +205 149 12 DarkGoldenrod3 +139 101 8 DarkGoldenrod4 +255 193 193 RosyBrown1 +238 180 180 RosyBrown2 +205 155 155 RosyBrown3 +139 105 105 RosyBrown4 +255 106 106 IndianRed1 +238 99 99 IndianRed2 +205 85 85 IndianRed3 +139 58 58 IndianRed4 +255 130 71 sienna1 +238 121 66 sienna2 +205 104 57 sienna3 +139 71 38 sienna4 +255 211 155 burlywood1 +238 197 145 burlywood2 +205 170 125 burlywood3 +139 115 85 burlywood4 +255 231 186 wheat1 +238 216 174 wheat2 +205 186 150 wheat3 +139 126 102 wheat4 +255 165 79 tan1 +238 154 73 tan2 +205 133 63 tan3 +139 90 43 tan4 +255 127 36 chocolate1 +238 118 33 chocolate2 +205 102 29 chocolate3 +139 69 19 chocolate4 +255 48 48 firebrick1 +238 44 44 firebrick2 +205 38 38 firebrick3 +139 26 26 firebrick4 +255 64 64 brown1 +238 59 59 brown2 +205 51 51 brown3 +139 35 35 brown4 +255 140 105 salmon1 +238 130 98 salmon2 +205 112 84 salmon3 +139 76 57 salmon4 +255 160 122 LightSalmon1 +238 149 114 LightSalmon2 +205 129 98 LightSalmon3 +139 87 66 LightSalmon4 +255 165 0 orange1 +238 154 0 orange2 +205 133 0 orange3 +139 90 0 orange4 +255 127 0 DarkOrange1 +238 118 0 DarkOrange2 +205 102 0 DarkOrange3 +139 69 0 DarkOrange4 +255 114 86 coral1 +238 106 80 coral2 +205 91 69 coral3 +139 62 47 coral4 +255 99 71 tomato1 +238 92 66 tomato2 +205 79 57 tomato3 +139 54 38 tomato4 +255 69 0 OrangeRed1 +238 64 0 OrangeRed2 +205 55 0 OrangeRed3 +139 37 0 OrangeRed4 +255 0 0 red1 +238 0 0 red2 +205 0 0 red3 +139 0 0 red4 +215 7 81 DebianRed +255 20 147 DeepPink1 +238 18 137 DeepPink2 +205 16 118 DeepPink3 +139 10 80 DeepPink4 +255 110 180 HotPink1 +238 106 167 HotPink2 +205 96 144 HotPink3 +139 58 98 HotPink4 +255 181 197 pink1 +238 169 184 pink2 +205 145 158 pink3 +139 99 108 pink4 +255 174 185 LightPink1 +238 162 173 LightPink2 +205 140 149 LightPink3 +139 95 101 LightPink4 +255 130 171 PaleVioletRed1 +238 121 159 PaleVioletRed2 +205 104 137 PaleVioletRed3 +139 71 93 PaleVioletRed4 +255 52 179 maroon1 +238 48 167 maroon2 +205 41 144 maroon3 +139 28 98 maroon4 +255 62 150 VioletRed1 +238 58 140 VioletRed2 +205 50 120 VioletRed3 +139 34 82 VioletRed4 +255 0 255 magenta1 +238 0 238 magenta2 +205 0 205 magenta3 +139 0 139 magenta4 +255 131 250 orchid1 +238 122 233 orchid2 +205 105 201 orchid3 +139 71 137 orchid4 +255 187 255 plum1 +238 174 238 plum2 +205 150 205 plum3 +139 102 139 plum4 +224 102 255 MediumOrchid1 +209 95 238 MediumOrchid2 +180 82 205 MediumOrchid3 +122 55 139 MediumOrchid4 +191 62 255 DarkOrchid1 +178 58 238 DarkOrchid2 +154 50 205 DarkOrchid3 +104 34 139 DarkOrchid4 +155 48 255 purple1 +145 44 238 purple2 +125 38 205 purple3 + 85 26 139 purple4 +171 130 255 MediumPurple1 +159 121 238 MediumPurple2 +137 104 205 MediumPurple3 + 93 71 139 MediumPurple4 +255 225 255 thistle1 +238 210 238 thistle2 +205 181 205 thistle3 +139 123 139 thistle4 + 0 0 0 gray0 + 0 0 0 grey0 + 3 3 3 gray1 + 3 3 3 grey1 + 5 5 5 gray2 + 5 5 5 grey2 + 8 8 8 gray3 + 8 8 8 grey3 + 10 10 10 gray4 + 10 10 10 grey4 + 13 13 13 gray5 + 13 13 13 grey5 + 15 15 15 gray6 + 15 15 15 grey6 + 18 18 18 gray7 + 18 18 18 grey7 + 20 20 20 gray8 + 20 20 20 grey8 + 23 23 23 gray9 + 23 23 23 grey9 + 26 26 26 gray10 + 26 26 26 grey10 + 28 28 28 gray11 + 28 28 28 grey11 + 31 31 31 gray12 + 31 31 31 grey12 + 33 33 33 gray13 + 33 33 33 grey13 + 36 36 36 gray14 + 36 36 36 grey14 + 38 38 38 gray15 + 38 38 38 grey15 + 41 41 41 gray16 + 41 41 41 grey16 + 43 43 43 gray17 + 43 43 43 grey17 + 46 46 46 gray18 + 46 46 46 grey18 + 48 48 48 gray19 + 48 48 48 grey19 + 51 51 51 gray20 + 51 51 51 grey20 + 54 54 54 gray21 + 54 54 54 grey21 + 56 56 56 gray22 + 56 56 56 grey22 + 59 59 59 gray23 + 59 59 59 grey23 + 61 61 61 gray24 + 61 61 61 grey24 + 64 64 64 gray25 + 64 64 64 grey25 + 66 66 66 gray26 + 66 66 66 grey26 + 69 69 69 gray27 + 69 69 69 grey27 + 71 71 71 gray28 + 71 71 71 grey28 + 74 74 74 gray29 + 74 74 74 grey29 + 77 77 77 gray30 + 77 77 77 grey30 + 79 79 79 gray31 + 79 79 79 grey31 + 82 82 82 gray32 + 82 82 82 grey32 + 84 84 84 gray33 + 84 84 84 grey33 + 87 87 87 gray34 + 87 87 87 grey34 + 89 89 89 gray35 + 89 89 89 grey35 + 92 92 92 gray36 + 92 92 92 grey36 + 94 94 94 gray37 + 94 94 94 grey37 + 97 97 97 gray38 + 97 97 97 grey38 + 99 99 99 gray39 + 99 99 99 grey39 +102 102 102 gray40 +102 102 102 grey40 +105 105 105 gray41 +105 105 105 grey41 +107 107 107 gray42 +107 107 107 grey42 +110 110 110 gray43 +110 110 110 grey43 +112 112 112 gray44 +112 112 112 grey44 +115 115 115 gray45 +115 115 115 grey45 +117 117 117 gray46 +117 117 117 grey46 +120 120 120 gray47 +120 120 120 grey47 +122 122 122 gray48 +122 122 122 grey48 +125 125 125 gray49 +125 125 125 grey49 +127 127 127 gray50 +127 127 127 grey50 +130 130 130 gray51 +130 130 130 grey51 +133 133 133 gray52 +133 133 133 grey52 +135 135 135 gray53 +135 135 135 grey53 +138 138 138 gray54 +138 138 138 grey54 +140 140 140 gray55 +140 140 140 grey55 +143 143 143 gray56 +143 143 143 grey56 +145 145 145 gray57 +145 145 145 grey57 +148 148 148 gray58 +148 148 148 grey58 +150 150 150 gray59 +150 150 150 grey59 +153 153 153 gray60 +153 153 153 grey60 +156 156 156 gray61 +156 156 156 grey61 +158 158 158 gray62 +158 158 158 grey62 +161 161 161 gray63 +161 161 161 grey63 +163 163 163 gray64 +163 163 163 grey64 +166 166 166 gray65 +166 166 166 grey65 +168 168 168 gray66 +168 168 168 grey66 +171 171 171 gray67 +171 171 171 grey67 +173 173 173 gray68 +173 173 173 grey68 +176 176 176 gray69 +176 176 176 grey69 +179 179 179 gray70 +179 179 179 grey70 +181 181 181 gray71 +181 181 181 grey71 +184 184 184 gray72 +184 184 184 grey72 +186 186 186 gray73 +186 186 186 grey73 +189 189 189 gray74 +189 189 189 grey74 +191 191 191 gray75 +191 191 191 grey75 +194 194 194 gray76 +194 194 194 grey76 +196 196 196 gray77 +196 196 196 grey77 +199 199 199 gray78 +199 199 199 grey78 +201 201 201 gray79 +201 201 201 grey79 +204 204 204 gray80 +204 204 204 grey80 +207 207 207 gray81 +207 207 207 grey81 +209 209 209 gray82 +209 209 209 grey82 +212 212 212 gray83 +212 212 212 grey83 +214 214 214 gray84 +214 214 214 grey84 +217 217 217 gray85 +217 217 217 grey85 +219 219 219 gray86 +219 219 219 grey86 +222 222 222 gray87 +222 222 222 grey87 +224 224 224 gray88 +224 224 224 grey88 +227 227 227 gray89 +227 227 227 grey89 +229 229 229 gray90 +229 229 229 grey90 +232 232 232 gray91 +232 232 232 grey91 +235 235 235 gray92 +235 235 235 grey92 +237 237 237 gray93 +237 237 237 grey93 +240 240 240 gray94 +240 240 240 grey94 +242 242 242 gray95 +242 242 242 grey95 +245 245 245 gray96 +245 245 245 grey96 +247 247 247 gray97 +247 247 247 grey97 +250 250 250 gray98 +250 250 250 grey98 +252 252 252 gray99 +252 252 252 grey99 +255 255 255 gray100 +255 255 255 grey100 +169 169 169 dark grey +169 169 169 DarkGrey +169 169 169 dark gray +169 169 169 DarkGray +0 0 139 dark blue +0 0 139 DarkBlue +0 139 139 dark cyan +0 139 139 DarkCyan +139 0 139 dark magenta +139 0 139 DarkMagenta +139 0 0 dark red +139 0 0 DarkRed +144 238 144 light green +144 238 144 LightGreen diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index f206ac8b..9a56de6f 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -21,6 +21,7 @@ import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowSe import { OscHandler } from 'common/parser/OscParser'; import { DcsHandler } from 'common/parser/DcsParser'; import { IBuffer } from 'common/buffer/Types'; +import { getColorFromName } from 'common/data/ColorNames'; /** * Map collect to glevel. Used in `selectCharset`. @@ -2877,13 +2878,14 @@ export class InputHandler extends Disposable implements IInputHandler { * with float numbering are not supported. */ protected _parseColorSpec(data: string): [number, number, number] | void { + if (!data) return; // also handle uppercases - data = data.toLowerCase(); - if (data.indexOf('rgb:') === 0) { + let low = data.toLowerCase(); + if (low.indexOf('rgb:') === 0) { // 'rgb:' specifier - data = data.slice(4); + low = low.slice(4); const rex = /^([\da-f]{1})\/([\da-f]{1})\/([\da-f]{1})$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$/; - const m = rex.exec(data); + const m = rex.exec(low); if (m) { const base = m[1] ? 15 : m[4] ? 255 : m[7] ? 4095 : 65535; return [ @@ -2892,20 +2894,21 @@ export class InputHandler extends Disposable implements IInputHandler { Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255) ]; } - } else if (data.indexOf('#') === 0) { + } else if (low.indexOf('#') === 0) { // '#' specifier - data = data.slice(1); + low = low.slice(1); const rex = /^[\da-f]+$/; - if (rex.exec(data) && [3, 6, 9, 12].includes(data.length)) { - const adv = data.length / 3; + if (rex.exec(low) && [3, 6, 9, 12].includes(low.length)) { + const adv = low.length / 3; const result: [number, number, number] = [0, 0, 0]; for (let i = 0; i < 3; ++i) { - const c = parseInt(data.slice(adv * i, adv * i + adv), 16); + const c = parseInt(low.slice(adv * i, adv * i + adv), 16); result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8; } return result; } } + return getColorFromName(data); } /** diff --git a/src/common/data/ColorNames.ts b/src/common/data/ColorNames.ts new file mode 100644 index 00000000..68dd06b6 --- /dev/null +++ b/src/common/data/ColorNames.ts @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2021 The xterm.js authors. All rights reserved. + * @license MIT + */ + +/** + * This module enables X11 color name lookups with the help of a perfect hash function + * to not penalize the package size too much. + * saving: ~70% (from 17kB down to 5kB) + */ + +// Note: module and table data created with fixtures/x11-colornames/create_module.js +const TABLE = 'AB!!!id!jsih!ZYigHp3AkceNiiImVihW3Uih?DFihrenihDEQiwgziieGJvAoMnsidOM3idOtQiciazAsFrtieFZyidKSgAx8odip818ieFiXieF97ic34eihOxpA4UPNidz51A8znjBAX?uBU9ynitOZdigRMNBYgIEBcaXPBk9LVB0xlOB9mcFihmlWCRq0yidmG7idqsHid7RmCV7pCClqRAimG5kCpsb4ipt78CtqLeig17aigJb7ioC4rihzLdigmoNigEDTihzZKCwIz1C4j5sih4QQihlg2igwsHDBFTuDESshDJFzIig1cbihZ3wipZphigiKcihZUxihZLODRm7RilG1Cid3tmDVGffDYJsPDc1JrixgxGidDn3Dli9uDsOl0imDQPiyDhbimDyZihU00icbZSEJs6VieEzpicF2YEqB?PicemNiduxiihEL9ieBjnEuI53icdLPiqBYWiduYFExunsFB3JqFEXPuihnyvFQkNAFVVjlic8SLicIeOFYvurFwrh5icQ4RicHUgidVbJidVA3idN3LGECqgGJiKSGRl8UidT9qipssVGZHNyidy3widTu8idgHsidgcgGdggRGkODXihH!8ilyhpihWj0ihWcailWHjGwO?OilD4BG888ZHJzmGHZtoyicqlkiwWfkicEbdHg3uEHtMkRH0TgkH5MBRIQE9VIUh5VIYeSyieFFgIlC6Qidvc5idv65icprGicNfhItjoJI4N3mJRFpIicLVGJgMY7J2GebKAPoGKyITuidFGWic2olicYLfLFuJDidnoticCc!icx2bieAcuLIv3UicoYuic594LRQ86LZc3NidcphicnOVic09yisjDiitRyFLc7NTicTaFicFbvic6jPLk3JtigqSiL1QJUjJQZpidQvJicUVVidYVsidNOjidNQfidNnLicyCAicHGeidY17icL3cL8DSKMcPzVMgc8dicEg6ig61OMwImmM06KXM6Hl!M96LNicQEbicUjBNAt2Aid4Hwix3w0Ndba5Nt5pqNwuVljBbJaicYjeigAxGN1b!LOEvTnisIIoORf1cOVV!TiczJbiddd5iddgpiclyxidfd8idfuEieACwid?zWih2rlOp2waid?r2OtUKQOxMyjihUpcigKWQO4y32PNAPFidAU6PZAhBPhjAni0PYUiceDridjwXPqEBxPsZ5Cicoi9icBWoieHXOP0B?9QF50CigWlyQJBkUQMs8nici3YQQ?MXidedxicjVCidhu9icqIFidhZjidhBQid0avicmIYQZLp!QdLBNQwFKyipSwfikPB5Q1SZKipSC1idL08Q44Vaic4tpikVWWQ9x5KikK4sig4Afit?bgihvhKRA?wsidxIfidGjgikw?ORRruoRYQWbRh2dkRk!EPRo!Vpig!taR92Glicf4gicxZGSCIB1jED6KSF0tyid0MUieEUnidLfYSRRoKSUk5sSczRfih06gSkpOgikVvGio5X1icp8Kio5NFik0sjix9EQSp8Pvide28icanaidyPpidekWSx71CTANkkicssXTE1nojEbGQTJp32ic?fFTcYU6icuDuicNCIT1B67T4DhEice8dihBd7ismVIUIRe3UVJeiUZBPEVNXn3idXcIj0jici5yT6VgGbJVlXA2idcRxicfAXicT4kicRjbVpnXZieEm?V4feMigLlzV95OGip4?git4nTWF3csicyWQWJGH2ikH?FWMo06ieCn5WSC2fieDOsWUm1Tidor2WZoaQidoCjicz5cWlxroicTKOW4dS9ido5CidnBwic0AWXJX4lXNdDaicS!nXkWPBXotnyYAgsNicrXhicnmHidHe0idHlLicaNvicG8Jida06YMOfFidTV!icY0YidDcrYRiXUYZivaigDO8ig8GPigGNwi88iCikuzkiharXicoAoihJPbihae9ihJmOihJ9xigV9UiwsMyidaEBichf!ic9ZEYk9oiigCARY9kLuidkWPidknpidk?aihh0likBkKZEJFsidjdfieJmgZIU5dieH47isgQIZNxb3ZQn7hidI6HZVIi0il9ZLix9nYih92!ihCeNZZClyZhISFi1IDjid6bQicwQvZl66Eid6riZoGjRicpYuieBC5ic5jfZwlrsicKATimA?cZ8ZO6icxGJieAt2iculVaA40zidYsAacin?aglNzalwMVi9d0mictfZascgqicbxMbABJ?ignSAjYM8?bIhNZigd1qig7eVieJNPbQq8pikKkaigVPligW!fjgR?5bWCHKidCM1bcrI5idppfidpRsi5P6TbkXgIbo2xucEAZdihvCiidPJXidPYxicAACcIXb9isr67cMtDzcgfiVctsKmc8khZigZjTilrC1ihpKGjQhh5dJr30igymSjKJehihMVeig3VrigwENipRc!idKnBdRRFodhKEOdxEc9idEnCidE8zic!9VidK1md18eZit!FHieGkhicJ8SieCXticlSNidbjridA7YeIdgneNtbMeVlKqeZlSZicbpmixtEVesAlzfU2dAfdwW?fsSYbf5w59gB1xOicMKxgN1q8icZbagZPjpidSoWid1Y0ic2JSid1Bhgo7qeidcLjilYKFiw6S2isa5Jgxwl9g00UbicSMohA73XhELGKhUQqNi8cGshgsaridfCIhkkePhtUeth0vCqileCnit5YaiE?plieHKPiJTPmiN7Kt'; +const COLORS = '??r6!Pj?!Pj?9fX19fX13Nzc??rw??rw?fXm?fXm!vDm!uvX!uvX?!?V?!?V?!vN?!vN?!TE?9q5?9q5?96t?96t?!S1??jc???w??rN??rN??Xu8P?w9f?69f?68P??8Pj?8Pj?5ub6??D1??D1?!Th?!Th????AAAAL09PL09PL09PL09PaWlpaWlpaWlpaWlpcICQcICQcICQcICQd4iZd4iZd4iZd4iZvr6!vr6!09PT09PT09PT09PTGRlwGRlwAACAAACAAACAZJXtZJXtSD2LSD2LalrNalrNe2jue2juhHD?hHD?AADNAADNQWnhQWnhAAD?HpD?HpD?AL??AL??h87rh87rh876h876RoK0RoK0sMTesMTerdjmrdjmsODmsODmr!7ur!7uAM7RAM7RSNHMSNHMQODQAP??4P??4P??X56gX56gZs2qZs2qf??UAGQAAGQAVWsvVWsvj7yPj7yPLotXLotXPLNxPLNxILKqILKqmPuYmPuYAP9?AP9?fPwAfPwAAP8Af?8AAPqaAPqarf8vrf8vMs0yMs0yms0yms0yIosiIosia44ja44jvbdrvbdr8OaM7uiq7uiq!vrS!vrS???g???g??8A?9cA7t2C7t2C2qUguIYLuIYLvI!PvI!PzVxczVxci0UTi0UToFItzYU?3riH9fXc9d6z9KRg9KRg0rSM0mkesiIipSoq6ZZ66ZZ6!oBy?6B6?6B6?6UA?4wA?4wA?39Q8ICA8ICA?2NH?0UA?0UA?wAA?2m0?2m0?xST?xST?8DL?7bB?7bB23CT23CTsDBgxxWFxxWF0CCQ0CCQ?wD?7oLu3aDd2nDWulXTulXTmTLMmTLMlADTlADTiiviiivioCDwk3Dbk3Db2L?Y??r67unpzcnJi4mJ??Xu7uXezcW?i4aC?!?b7t?MzcCwi4N4?!TE7tW3zbeei31r?9q57sutza!Vi3dl?96t7s!hzbOLi3le??rN7um?zcmli4lw??jc7ujNzcixi4h4???w7u7gzc3Bi4uD8P?w4O7gwc3Bg4uD??D17uDlzcHFi4OG?!Th7tXSzbe1i3178P??4O7uwc3Ng4uLg2??emfuaVnNRzyLSHb?Q27uOl?NJ0CLAAD?AADuAADNAACLHpD?HIbuGHTNEE6LY7j?XKzuT5TNNmSLAL??ALLuAJrNAGiLh87?fsDubKbNSnCLsOL?pNPujbbNYHuLxuL?udPun7bNbHuLyuH?vNLuorXNbnuLv!??st?umsDNaIOL4P??0e7utM3NeouLu???ru7uls3NZouLmPX?juXuesXNU4aLAPX?AOXuAMXNAIaLAP??AO7uAM3NAIuLl???je7uec3NUouLf??Udu7GZs2qRYt0wf?BtO60m82baYtpVP!fTu6UQ82ALotXmv!akO6QfM18VItUAP9?AO52AM1mAItFAP8AAO4AAM0AAIsAf?8Adu4AZs0ARYsAwP8!s!46ms0yaYsiyv9wvO5oos1abos9??aP7uaFzcZzi4ZO?!yL7tyCzb5wi4FM???g7u7Rzc20i4t6??8A7u4Azc0Ai4sA?9cA7skAza0Ai3UA?8El7rQizZsdi2kU?7kP7q0OzZUMi2UI?8HB7rS0zZubi2lp?2pq7mNjzVVVizo6?4JH7nlCzWg5i0cm?9Ob7sWRzap9i3NV?!e67tiuzbqWi35m?6VP7ppJzYU?i1or?38k7nYhzWYdi0UT?zAw7iwszSYmixoa?0BA7js7zTMziyMj?4xp7oJizXBUi0w5?6B67pVyzYFii1dC?6UA7poAzYUAi1oA?38A7nYAzWYAi0UA?3JW7mpQzVtFiz4v?2NH7lxCzU85izYm?0UA7kAAzTcAiyUA?wAA7gAAzQAAiwAA1wdR?xST7hKJzRB2iwpQ?2607mqnzWCQizpi?7XF7qm4zZGei2Ns?6657qKtzYyVi19l?4Kr7nmfzWiJi0dd?zSz7jCnzSmQixxi?z6W7jqMzTJ4iyJS?wD?7gDuzQDNiwCL?4P67nrpzWnJi0eJ?7v?7q7uzZbNi2aL4Gb?0V?utFLNejeLvz7?sjrumjLNaCKLmzD?kSzufSbNVRqLq4L?n3nuiWjNXUeL?!H?7tLuzbXNi3uLqampqampqampqampAACLAACLAIuLAIuLiwCLiwCLiwAAiwAAkO6QkO6Q'; +const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?'; +const OFFSET = 551; +const LENGTH = 551; +const BUCKET_LENGTH = TABLE.length / LENGTH; + +// match greyXX|grayXX names +const rexGrey = /^gr[ae]y(\d+)/; +// name match +const rexName = /^\w?[A-Za-z0-9 ]+\w/; + +function gray(n: number): [number, number, number] | undefined { + if (0 <= n && n <= 100) { + const v = Math.floor((n * 256 - n + 50) / 100); + return [v, v, v]; + } + return; +} + +function hash(d: number, name: string): number { + if (!d) d = 0x01000193; + for (const c of name) { + d = ((d * 0x01000193) ^ c.charCodeAt(0)) & 0xffffffff; + } + return d >>> 0; +} + +function crc10(name: string, crc?: number): number { + if (!crc) crc = 0; + for (const c of name) { + crc ^= c.charCodeAt(0) << 2; + for (let k = 0; k < 8; k++) { + crc = crc & 0x200 ? (crc << 1) ^ 0x233 : crc << 1; + } + } + crc &= 0x3ff; + return crc >>> 0; +} + +function loadData(idx: number): [number, number, number] { + let value = 0; + for (let i = idx * BUCKET_LENGTH; i < idx * BUCKET_LENGTH + BUCKET_LENGTH; ++i) { + value *= ALPHABET.length; + value += ALPHABET.indexOf(TABLE[i]); + } + return [value >>> 20, (value >> 10) & 0x3FF, value & 0x3FF]; +} + +function loadColor(idx: number): [number, number, number] { + // color buckets are hardcoded to 4 chars + let v = 0; + for (let i = idx * 4; i < idx * 4 + 4; ++i) { + v *= ALPHABET.length; + v += ALPHABET.indexOf(COLORS[i]); + } + return [v >>> 16, (v >> 8) & 0xFF, v & 0xFF]; +} + +function lookupIdx(name: string): number { + let b = loadData(hash(0, name) % LENGTH); + b = loadData(b[0] < OFFSET ? (-(b[0] - OFFSET) - 1) : hash(b[0] - OFFSET, name) % LENGTH); + const [ , , crc] = loadData(b[1]); + return crc10(name) === crc ? b[1] : -1; +} + +export function getColorFromName(name: string): [number, number, number] | undefined { + // basic name filtering + if (name.length < 3 || name.length > 22 || !rexName.exec(name)) return; + + // handle grays special + const m = rexGrey.exec(name); + if (m) return gray(parseInt(m[1])); + + // grab crc checked idx from PHF + const idx = lookupIdx(name); + if (idx === -1) return; + return loadColor(idx); +} From 5c9adeef930b969bc822470b504ae690d82dd05e Mon Sep 17 00:00:00 2001 From: ElJeffe Date: Tue, 26 Oct 2021 11:44:52 -0400 Subject: [PATCH 08/58] Check to make sure cols & rows are INT I've noticed that if the terminal is hidden and the screen experiences a resize trigger from a blur / focus, it can cause the dimensions to be undefined. This creates an exception in Xterm.js that the values are not integers. Figured it would be ok to just check before doing a resize. --- addons/xterm-addon-fit/src/FitAddon.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/xterm-addon-fit/src/FitAddon.ts b/addons/xterm-addon-fit/src/FitAddon.ts index f4e5c772..360397ec 100644 --- a/addons/xterm-addon-fit/src/FitAddon.ts +++ b/addons/xterm-addon-fit/src/FitAddon.ts @@ -33,7 +33,7 @@ export class FitAddon implements ITerminalAddon { public fit(): void { const dims = this.proposeDimensions(); - if (!dims || !this._terminal) { + if (!dims || !this._terminal || isNaN(dims.cols) || isNaN(dims.rows)) { return; } From b627f003e3c8c62e14500bf2adc6f4d210491070 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 27 Oct 2021 08:38:04 -0700 Subject: [PATCH 09/58] Revert "Avoid property use and float->number conversion" This reverts commit ffef3dba002e91ecac6b0d6a888fac1076cc7279. --- src/browser/Viewport.ts | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/browser/Viewport.ts b/src/browser/Viewport.ts index 3c9bea4c..d8df4efa 100644 --- a/src/browser/Viewport.ts +++ b/src/browser/Viewport.ts @@ -8,8 +8,6 @@ import { addDisposableDomListener } from 'browser/Lifecycle'; import { IColorSet, IViewport } from 'browser/Types'; import { ICharSizeService, IRenderService } from 'browser/services/Services'; import { IBufferService, IOptionsService } from 'common/services/Services'; -import { IBuffer } from 'common/buffer/Types'; -import { IRenderDimensions } from 'browser/renderer/Types'; const FALLBACK_SCROLL_BAR_WIDTH = 15; @@ -20,15 +18,12 @@ const FALLBACK_SCROLL_BAR_WIDTH = 15; export class Viewport extends Disposable implements IViewport { public scrollBarWidth: number = 0; private _currentRowHeight: number = 0; - private _currentScaledCellHeight: number = 0; private _lastRecordedBufferLength: number = 0; private _lastRecordedViewportHeight: number = 0; private _lastRecordedBufferHeight: number = 0; private _lastTouchY: number = 0; private _lastScrollTop: number = 0; private _lastHadScrollBar: boolean = false; - private _activeBuffer: IBuffer; - private _renderDimensions: IRenderDimensions; // Stores a partial line amount when scrolling, this is used to keep track of how much of a line // is scrolled so we can "scroll" over partial lines and feel natural on touchpads. This is a @@ -56,12 +51,6 @@ export class Viewport extends Disposable implements IViewport { this._lastHadScrollBar = true; this.register(addDisposableDomListener(this._viewportElement, 'scroll', this._onScroll.bind(this))); - // Track properties used in performance critical code manually to avoid using slow getters - this._activeBuffer = this._bufferService.buffer; - this.register(this._bufferService.buffers.onBufferActivate(e => this._activeBuffer = e.activeBuffer)); - this._renderDimensions = this._renderService.dimensions; - this.register(this._renderService.onDimensionsChange(e => this._renderDimensions = e)); - // Perform this async to ensure the ICharSizeService is ready. setTimeout(() => this.syncScrollArea(), 0); } @@ -90,7 +79,6 @@ export class Viewport extends Disposable implements IViewport { private _innerRefresh(): void { if (this._charSizeService.height > 0) { this._currentRowHeight = this._renderService.dimensions.scaledCellHeight / window.devicePixelRatio; - this._currentScaledCellHeight = this._renderService.dimensions.scaledCellHeight; this._lastRecordedViewportHeight = this._viewportElement.offsetHeight; const newBufferHeight = Math.round(this._currentRowHeight * this._lastRecordedBufferLength) + (this._lastRecordedViewportHeight - this._renderService.dimensions.canvasHeight); if (this._lastRecordedBufferHeight !== newBufferHeight) { @@ -138,13 +126,14 @@ export class Viewport extends Disposable implements IViewport { } // If the buffer position doesn't match last scroll top - if (this._lastScrollTop !== this._activeBuffer.ydisp * this._currentRowHeight) { + const newScrollTop = this._bufferService.buffer.ydisp * this._currentRowHeight; + if (this._lastScrollTop !== newScrollTop) { this._refresh(immediate); return; } // If row height changed - if (this._renderDimensions.scaledCellHeight !== this._currentScaledCellHeight) { + if (this._renderService.dimensions.scaledCellHeight / window.devicePixelRatio !== this._currentRowHeight) { this._refresh(immediate); return; } From 5a4e88dc51dc92c5a1dddb6c9ecde41c696a58d3 Mon Sep 17 00:00:00 2001 From: Eugene Pankov Date: Sun, 31 Oct 2021 12:27:41 +0100 Subject: [PATCH 10/58] input: prevent duplicate IME input on Linux - fixes #3533 --- src/browser/Terminal.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index d28be5bf..0312ca4b 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -1182,7 +1182,7 @@ export class Terminal extends CoreTerminal implements ITerminal { protected _inputEvent(ev: InputEvent): boolean { // Only support emoji IMEs when screen reader mode is disabled as the event must bubble up to // support reading out character input which can doubling up input characters - if (ev.data && ev.inputType === 'insertText' && !this.optionsService.options.screenReaderMode) { + if (ev.data && ev.inputType === 'insertText' && !ev.composed && !this.optionsService.options.screenReaderMode) { if (this._keyPressHandled) { return false; } From bec4f6d5c7fa4a824cbc83630b1381494d1ffea5 Mon Sep 17 00:00:00 2001 From: Simon Lamon Date: Mon, 1 Nov 2021 15:09:25 +0000 Subject: [PATCH 11/58] clear isWrapped in eraseBufferLine --- src/common/InputHandler.test.ts | 50 +++++++++++++++++++++++++++++++++ src/common/InputHandler.ts | 28 +++++++++--------- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index e25c3df1..a0930c51 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -386,6 +386,56 @@ describe('InputHandler', () => { assert.equal(bufferService.buffer.lines.get(2)!.translateToString(false), Array(bufferService.cols + 1).join(' ')); }); + it('eraseInLine reflow', async () => { + const bufferService = new MockBufferService(80, 30); + const inputHandler = new TestInputHandler( + bufferService, + new MockCharsetService(), + new MockCoreService(), + new MockDirtyRowService(), + new MockLogService(), + new MockOptionsService(), + new MockCoreMouseService(), + new MockUnicodeService() + ); + + const resetToBaseState = async (): Promise => { + // reset and add a wrapped line + bufferService.buffer.y = 0; + bufferService.buffer.x = 0; + await inputHandler.parseP(Array(bufferService.cols + 1).join('a')); // line 0 + await inputHandler.parseP(Array(bufferService.cols + 10).join('a')); // line 1 and 2 + for (let i = 3; i < bufferService.rows; ++i) await inputHandler.parseP(Array(bufferService.cols + 1).join('a')); + + // confirm precondition that line 2 is wrapped + assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, true); + }; + + // params[0] - erase from the cursor through the end of the row. + await resetToBaseState(); + bufferService.buffer.y = 2; + bufferService.buffer.x = 40; + inputHandler.eraseInLine(Params.fromArray([0])); + assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, true); + bufferService.buffer.y = 2; + bufferService.buffer.x = 0; + inputHandler.eraseInLine(Params.fromArray([0])); + assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, false); + + // params[1] - erase from the beginning of the line through the cursor + await resetToBaseState(); + bufferService.buffer.y = 2; + bufferService.buffer.x = 40; + inputHandler.eraseInLine(Params.fromArray([1])); + assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, true); + + // params[2] - erase complete line + await resetToBaseState(); + bufferService.buffer.y = 2; + bufferService.buffer.x = 40; + inputHandler.eraseInDisplay(Params.fromArray([2])); + assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, false); + }); it('eraseInDisplay', async () => { const bufferService = new MockBufferService(80, 7); const inputHandler = new TestInputHandler( diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 9371e5f5..89089947 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -25,7 +25,7 @@ import { IBuffer } from 'common/buffer/Types'; /** * Map collect to glevel. Used in `selectCharset`. */ -const GLEVEL: {[key: string]: number} = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 }; +const GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 }; /** * VT commands done by the parser - FIXME: move this to the parser? @@ -167,7 +167,7 @@ class DECRQSS implements IDcsHandler { break; case 'r': // DECSTBM const pt = '' + (this._bufferService.buffer.scrollTop + 1) + - ';' + (this._bufferService.buffer.scrollBottom + 1) + 'r'; + ';' + (this._bufferService.buffer.scrollBottom + 1) + 'r'; this._coreService.triggerDataEvent(`${C0.ESC}P1$r${pt}${C0.ESC}\\`); break; case 'm': // SGR @@ -175,7 +175,7 @@ class DECRQSS implements IDcsHandler { this._coreService.triggerDataEvent(`${C0.ESC}P1$r0m${C0.ESC}\\`); break; case ' q': // DECSCUSR - const STYLES: {[key: string]: number} = { 'block': 2, 'underline': 4, 'bar': 6 }; + const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 }; let style = STYLES[this._optionsService.options.cursorStyle]; style -= this._optionsService.options.cursorBlink ? 1 : 0; this._coreService.triggerDataEvent(`${C0.ESC}P1$r${style} q${C0.ESC}\\`); @@ -855,10 +855,9 @@ export class InputHandler extends Disposable implements IInputHandler { * - any cursor movement sequence keeps working as expected */ if (this._activeBuffer.x === 0 - && this._activeBuffer.y > this._activeBuffer.scrollTop - && this._activeBuffer.y <= this._activeBuffer.scrollBottom - && this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) - { + && this._activeBuffer.y > this._activeBuffer.scrollTop + && this._activeBuffer.y <= this._activeBuffer.scrollBottom + && this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) { this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false; this._activeBuffer.y--; this._activeBuffer.x = this._bufferService.cols - 1; @@ -1195,6 +1194,7 @@ export class InputHandler extends Disposable implements IInputHandler { * @param y row index * @param start first cell index to be erased * @param end end - 1 is last erased cell + * @param cleanWrap clear the isWrapped flag */ private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false): void { const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!; @@ -1320,13 +1320,13 @@ export class InputHandler extends Disposable implements IInputHandler { this._restrictCursor(this._bufferService.cols); switch (params.params[0]) { case 0: - this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols); + this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0); break; case 1: - this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1); + this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1, false); break; case 2: - this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols); + this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols, true); break; } this._dirtyRowService.markDirty(this._activeBuffer.y); @@ -1977,7 +1977,7 @@ export class InputHandler extends Disposable implements IInputHandler { break; case 1049: // alt screen buffer cursor this.saveCursor(); - // FALL-THROUGH + // FALL-THROUGH case 47: // alt screen buffer case 1047: // alt screen buffer this._bufferService.buffers.activateAltBuffer(this._eraseAttrData()); @@ -2197,7 +2197,7 @@ export class InputHandler extends Disposable implements IInputHandler { this.restoreCursor(); break; case 1049: // alt screen buffer cursor - // FALL-THROUGH + // FALL-THROUGH case 47: // normal screen buffer case 1047: // normal screen buffer - clearing it first // Ensure the selection manager has the correct buffer @@ -2264,7 +2264,7 @@ export class InputHandler extends Disposable implements IInputHandler { } // exit early if can decide color mode with semicolons if ((accu[1] === 5 && advance + cSpace >= 2) - || (accu[1] === 2 && advance + cSpace >= 5)) { + || (accu[1] === 2 && advance + cSpace >= 5)) { break; } // offset colorSpace slot for semicolon mode @@ -2683,7 +2683,7 @@ export class InputHandler extends Disposable implements IInputHandler { const top = params.params[0] || 1; let bottom: number; - if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) { + if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) { bottom = this._bufferService.rows; } From 086ac39095aa1dc21f24fde627e7194ebd737d26 Mon Sep 17 00:00:00 2001 From: Simon Lamon Date: Mon, 1 Nov 2021 15:23:10 +0000 Subject: [PATCH 12/58] Add whitespaces --- src/common/InputHandler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 89089947..870ecf01 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -1977,7 +1977,7 @@ export class InputHandler extends Disposable implements IInputHandler { break; case 1049: // alt screen buffer cursor this.saveCursor(); - // FALL-THROUGH + // FALL-THROUGH case 47: // alt screen buffer case 1047: // alt screen buffer this._bufferService.buffers.activateAltBuffer(this._eraseAttrData()); @@ -2197,7 +2197,7 @@ export class InputHandler extends Disposable implements IInputHandler { this.restoreCursor(); break; case 1049: // alt screen buffer cursor - // FALL-THROUGH + // FALL-THROUGH case 47: // normal screen buffer case 1047: // normal screen buffer - clearing it first // Ensure the selection manager has the correct buffer From 47e53cbdaa8da47ddd66e920c322820af52730b8 Mon Sep 17 00:00:00 2001 From: Simon Lamon Date: Mon, 1 Nov 2021 15:42:01 +0000 Subject: [PATCH 13/58] Fix unit test calling eraseInDisplay instead of eraseInLine --- src/common/InputHandler.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index a0930c51..bff7cbe9 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -433,7 +433,7 @@ describe('InputHandler', () => { await resetToBaseState(); bufferService.buffer.y = 2; bufferService.buffer.x = 40; - inputHandler.eraseInDisplay(Params.fromArray([2])); + inputHandler.eraseInLine(Params.fromArray([2])); assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, false); }); it('eraseInDisplay', async () => { From b684929d1e4d0380ca9ed951634e73e7326097f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 1 Nov 2021 18:20:17 +0100 Subject: [PATCH 14/58] upgrade dev deps --- addons/xterm-addon-ligatures/src/font.ts | 4 +- package.json | 44 +- yarn.lock | 1973 ++++++++++------------ 3 files changed, 895 insertions(+), 1126 deletions(-) diff --git a/addons/xterm-addon-ligatures/src/font.ts b/addons/xterm-addon-ligatures/src/font.ts index abdbbc04..4075cc6c 100644 --- a/addons/xterm-addon-ligatures/src/font.ts +++ b/addons/xterm-addon-ligatures/src/font.ts @@ -43,7 +43,7 @@ export default async function load(fontFamily: string, cacheSize: number): Promi if (status && status.state !== 'granted') { throw new Error('Permission to access local fonts not granted.'); } - } catch (err) { + } catch (err: any) { // A `TypeError` indicates the 'local-fonts' // permission is not yet implemented, so // only `throw` if this is _not_ the problem. @@ -61,7 +61,7 @@ export default async function load(fontFamily: string, cacheSize: number): Promi fonts[metadata.family].push(metadata); } fontsPromise = Promise.resolve(fonts); - } catch (err) { + } catch (err: any) { console.error(err.name, err.message); } } diff --git a/package.json b/package.json index ad288f49..6e49fea2 100644 --- a/package.json +++ b/package.json @@ -37,39 +37,39 @@ "vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts" }, "devDependencies": { - "@types/chai": "^4.2.18", - "@types/debug": "^4.1.5", + "@types/chai": "^4.2.22", + "@types/debug": "^4.1.7", "@types/deep-equal": "^1.0.1", - "@types/glob": "^7.1.3", - "@types/jsdom": "^16.2.10", - "@types/mocha": "^8.2.2", + "@types/glob": "^7.2.0", + "@types/jsdom": "^16.2.13", + "@types/mocha": "^9.0.0", "@types/node": "^14.14.44", - "@types/utf8": "^2.1.6", + "@types/utf8": "^3.0.0", "@types/webpack": "^5.28.0", - "@types/ws": "^7.4.4", - "@typescript-eslint/eslint-plugin": "^4.23.0", - "@typescript-eslint/parser": "^4.23.0", + "@types/ws": "^8.2.0", + "@typescript-eslint/eslint-plugin": "^5.3.0", + "@typescript-eslint/parser": "^5.3.0", "chai": "^4.3.4", "cross-env": "^7.0.3", "deep-equal": "^2.0.5", - "eslint": "^7.26.0", + "eslint": "^8.1.0", "express": "^4.17.1", - "express-ws": "^4.0.0", - "glob": "^7.1.7", - "jsdom": "^16.5.3", - "mocha": "^8.4.0", + "express-ws": "^5.0.2", + "glob": "^7.2.0", + "jsdom": "^18.0.1", + "mocha": "^9.1.3", "mustache": "^4.2.0", "node-pty": "^0.10.1", "nyc": "^15.1.0", - "playwright": "^1.11.0", - "source-map-loader": "^2.0.1", - "source-map-support": "^0.5.19", + "playwright": "^1.16.2", + "source-map-loader": "^3.0.0", + "source-map-support": "^0.5.20", "ts-loader": "^9.1.2", - "typescript": "^4.2.4", + "typescript": "^4.4.4", "utf8": "^3.0.0", - "webpack": "^5.37.0", - "webpack-cli": "^4.7.0", - "ws": "^7.4.5", - "xterm-benchmark": "^0.2.1" + "webpack": "^5.61.0", + "webpack-cli": "^4.9.1", + "ws": "^8.2.3", + "xterm-benchmark": "^0.3.0" } } diff --git a/yarn.lock b/yarn.lock index cf92d8f7..0c536af5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,13 +2,6 @@ # yarn lockfile v1 -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" @@ -123,11 +116,6 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-validator-identifier@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" - integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== - "@babel/helper-validator-identifier@^7.9.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" @@ -142,15 +130,6 @@ "@babel/traverse" "^7.9.0" "@babel/types" "^7.9.0" -"@babel/highlight@^7.10.4": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" - integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.0" - chalk "^2.0.0" - js-tokens "^4.0.0" - "@babel/highlight@^7.8.3": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" @@ -198,35 +177,40 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@dabh/diagnostics@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" - integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q== - dependencies: - colorspace "1.1.x" - enabled "2.0.x" - kuler "^2.0.0" - "@discoveryjs/json-ext@^0.5.0": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752" - integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg== + version "0.5.5" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz#9283c9ce5b289a3c4f61c12757469e59377f81f3" + integrity sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA== -"@eslint/eslintrc@^0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14" - integrity sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ== +"@eslint/eslintrc@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.3.tgz#41f08c597025605f672251dcc4e8be66b5ed7366" + integrity sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg== dependencies: ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^12.1.0" + debug "^4.3.2" + espree "^9.0.0" + globals "^13.9.0" ignore "^4.0.6" import-fresh "^3.2.1" js-yaml "^3.13.1" minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@humanwhocodes/config-array@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.6.0.tgz#b5621fdb3b32309d2d16575456cbc277fa8f021a" + integrity sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" + integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b" @@ -242,48 +226,41 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@kwsites/file-exists@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99" - integrity sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: - debug "^4.1.1" - -"@kwsites/promise-deferred@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" - integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== - -"@nodelib/fs.scandir@2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" - integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== - dependencies: - "@nodelib/fs.stat" "2.0.4" + "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" - integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" - integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: - "@nodelib/fs.scandir" "2.1.4" + "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + "@types/app-root-path@^1.2.4": version "1.2.4" resolved "https://registry.yarnpkg.com/@types/app-root-path/-/app-root-path-1.2.4.tgz#a78b703282b32ac54de768f5512ecc3569919dc7" integrity sha1-p4twMoKzKsVN52j1US7MNWmRncc= -"@types/chai@^4.2.18": - version "4.2.18" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.18.tgz#0c8e298dbff8205e2266606c1ea5fbdba29b46e4" - integrity sha512-rS27+EkB/RE1Iz3u0XtVL5q36MGDWbgYe7zWiodyKNUnthxY0rukK5V36eiUCtCisB7NN8zKYH6DO2M37qxFEQ== +"@types/chai@^4.2.22": + version "4.2.22" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.22.tgz#47020d7e4cf19194d43b5202f35f75bd2ad35ce7" + integrity sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ== "@types/cli-table@^0.3.0": version "0.3.0" @@ -295,10 +272,12 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== -"@types/debug@^4.1.5": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" - integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ== +"@types/debug@^4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" + integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== + dependencies: + "@types/ms" "*" "@types/deep-equal@^1.0.1": version "1.0.1" @@ -326,31 +305,29 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4" integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg== -"@types/fs-extra@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.1.tgz#91c8fc4c51f6d5dbe44c2ca9ab09310bd00c7918" - integrity sha512-B42Sxuaz09MhC3DDeW5kubRcQ5by4iuVQ0cRRWM2lggLzAa/KVom0Aft/208NgMvNQQZ86s5rVcqDdn/SH0/mg== - dependencies: - "@types/node" "*" +"@types/estree@^0.0.50": + version "0.0.50" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" + integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== -"@types/glob@^7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" - integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== +"@types/glob@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== dependencies: "@types/minimatch" "*" "@types/node" "*" -"@types/jsdom@^16.2.10": - version "16.2.10" - resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-16.2.10.tgz#c05ea94682d035943ae2453b79d56178496b6653" - integrity sha512-q3aIjp3ehhVSXSbvNyuireAfvU2umRiZ2aLumyeZewCnoNaokrRDdTu5IvaeE9pzNtWHXrUnM9lb22Vl3W08EA== +"@types/jsdom@^16.2.13": + version "16.2.13" + resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-16.2.13.tgz#126c8b7441b159d6234610a48de77b6066f1823f" + integrity sha512-8JQCjdeAidptSsOcRWk2iTm9wCcwn9l+kRG6k5bzUacrnm1ezV4forq0kWjUih/tumAeoG+OspOvQEbbRucBTw== dependencies: "@types/node" "*" "@types/parse5" "*" "@types/tough-cookie" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.3": +"@types/json-schema@*": version "7.0.7" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== @@ -360,6 +337,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== +"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + "@types/mathjs@^6.0.11": version "6.0.12" resolved "https://registry.yarnpkg.com/@types/mathjs/-/mathjs-6.0.12.tgz#1c2a60352852676e10936ce150b9500d36555973" @@ -368,15 +350,25 @@ decimal.js "^10.0.0" "@types/minimatch@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== -"@types/mocha@^8.2.1", "@types/mocha@^8.2.2": +"@types/mocha@^8.2.1": version "8.2.2" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.2.tgz#91daa226eb8c2ff261e6a8cbf8c7304641e095e0" integrity sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw== +"@types/mocha@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.0.0.tgz#3205bcd15ada9bc681ac20bef64e9e6df88fd297" + integrity sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA== + +"@types/ms@*": + version "0.7.31" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + "@types/node@*": version "13.9.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.5.tgz#59738bf30b31aea1faa2df7f4a5f55613750cf00" @@ -393,9 +385,9 @@ integrity sha512-+gaugz6Oce6ZInfI/tK4Pq5wIIkJMEJUu92RB3Eu93mtj4wjjjz9EB5mLp5s1pSsLXdC/CPut/xF20ZzAQJbTA== "@types/parse5@*": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.0.tgz#38590dc2c3cf5717154064e3ee9b6947ee21b299" - integrity sha512-oPwPSj4a1wu9rsXTEGIJz91ISU725t0BmSnUhb57sI+M8XEmvUop84lzuiYdq0Y5M6xLY8DBPg0C2xEQKLyvBA== + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.2.tgz#99f6b72d82e34cea03a4d8f2ed72114d909c1c61" + integrity sha512-+hQX+WyJAOne7Fh3zF5CxPemILIbuhNcqHHodzK9caYOLnC8pD5efmPleRnw0z++LfKUC/sVNMwk0Gap+B0baA== "@types/puppeteer@^5.4.3": version "5.4.3" @@ -405,14 +397,14 @@ "@types/node" "*" "@types/tough-cookie@*": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" - integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40" + integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg== -"@types/utf8@^2.1.6": - version "2.1.6" - resolved "https://registry.yarnpkg.com/@types/utf8/-/utf8-2.1.6.tgz#430cabb71a42d0a3613cce5621324fe4f5a25753" - integrity sha512-pRs2gYF5yoKYrgSaira0DJqVg2tFuF+Qjp838xS7K+mJyY2jJzjsrl6y17GbIa4uMRogMbxs+ghNCvKg6XyNrA== +"@types/utf8@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/utf8/-/utf8-3.0.0.tgz#8f4875063d2ea966c57a34a25c11333520e83980" + integrity sha512-QrhvCktdm5wD48axAnjqSzPH9lOj0MiCYfMX6MSqGs2Jv+txwvdxviXiCEj8zSCWIEDU9SIJ7g9pU5KtxRgYSg== "@types/webpack@^5.28.0": version "5.28.0" @@ -423,89 +415,89 @@ tapable "^2.2.0" webpack "^5" -"@types/ws@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.4.tgz#93e1e00824c1de2608c30e6de4303ab3b4c0c9bc" - integrity sha512-d/7W23JAXPodQNbOZNXvl2K+bqAQrCMwlh/nuQsPSQk6Fq0opHoPrUw43aHsvSbIiQPr8Of2hkFbnz1XBFVyZQ== +"@types/ws@^8.2.0": + version "8.2.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.0.tgz#75faefbe2328f3b833cb8dc640658328990d04f3" + integrity sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg== dependencies: "@types/node" "*" "@types/yauzl@^2.9.1": - version "2.9.1" - resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.1.tgz#d10f69f9f522eef3cf98e30afb684a1e1ec923af" - integrity sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA== + version "2.9.2" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.2.tgz#c48e5d56aff1444409e39fa164b0b4d4552a7b7a" + integrity sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA== dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@^4.23.0": - version "4.23.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.23.0.tgz#29d3c9c81f6200b1fd6d8454cfb007ba176cde80" - integrity sha512-tGK1y3KIvdsQEEgq6xNn1DjiFJtl+wn8JJQiETtCbdQxw1vzjXyAaIkEmO2l6Nq24iy3uZBMFQjZ6ECf1QdgGw== +"@typescript-eslint/eslint-plugin@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.0.tgz#a55ae72d28ffeb6badd817fe4566c9cced1f5e29" + integrity sha512-ARUEJHJrq85aaiCqez7SANeahDsJTD3AEua34EoQN9pHS6S5Bq9emcIaGGySt/4X2zSi+vF5hAH52sEen7IO7g== dependencies: - "@typescript-eslint/experimental-utils" "4.23.0" - "@typescript-eslint/scope-manager" "4.23.0" - debug "^4.1.1" + "@typescript-eslint/experimental-utils" "5.3.0" + "@typescript-eslint/scope-manager" "5.3.0" + debug "^4.3.2" functional-red-black-tree "^1.0.1" - lodash "^4.17.15" - regexpp "^3.0.0" - semver "^7.3.2" - tsutils "^3.17.1" + ignore "^5.1.8" + regexpp "^3.2.0" + semver "^7.3.5" + tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.23.0": - version "4.23.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.23.0.tgz#f2059434cd6e5672bfeab2fb03b7c0a20622266f" - integrity sha512-WAFNiTDnQfrF3Z2fQ05nmCgPsO5o790vOhmWKXbbYQTO9erE1/YsFot5/LnOUizLzU2eeuz6+U/81KV5/hFTGA== +"@typescript-eslint/experimental-utils@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.0.tgz#ee56b4957547ed2b0fc7451205e41502e664f546" + integrity sha512-NFVxYTjKj69qB0FM+piah1x3G/63WB8vCBMnlnEHUsiLzXSTWb9FmFn36FD9Zb4APKBLY3xRArOGSMQkuzTF1w== dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.23.0" - "@typescript-eslint/types" "4.23.0" - "@typescript-eslint/typescript-estree" "4.23.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.3.0" + "@typescript-eslint/types" "5.3.0" + "@typescript-eslint/typescript-estree" "5.3.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" -"@typescript-eslint/parser@^4.23.0": - version "4.23.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.23.0.tgz#239315d38e42e852bef43a4b0b01bef78f78911c" - integrity sha512-wsvjksHBMOqySy/Pi2Q6UuIuHYbgAMwLczRl4YanEPKW5KVxI9ZzDYh3B5DtcZPQTGRWFJrfcbJ6L01Leybwug== +"@typescript-eslint/parser@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.3.0.tgz#7879f15e26d370ed3f653fb7dd06479531ed3ab9" + integrity sha512-rKu/yAReip7ovx8UwOAszJVO5MgBquo8WjIQcp1gx4pYQCwYzag+I5nVNHO4MqyMkAo0gWt2gWUi+36gWAVKcw== dependencies: - "@typescript-eslint/scope-manager" "4.23.0" - "@typescript-eslint/types" "4.23.0" - "@typescript-eslint/typescript-estree" "4.23.0" - debug "^4.1.1" + "@typescript-eslint/scope-manager" "5.3.0" + "@typescript-eslint/types" "5.3.0" + "@typescript-eslint/typescript-estree" "5.3.0" + debug "^4.3.2" -"@typescript-eslint/scope-manager@4.23.0": - version "4.23.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.23.0.tgz#8792ef7eacac122e2ec8fa2d30a59b8d9a1f1ce4" - integrity sha512-ZZ21PCFxPhI3n0wuqEJK9omkw51wi2bmeKJvlRZPH5YFkcawKOuRMQMnI8mH6Vo0/DoHSeZJnHiIx84LmVQY+w== +"@typescript-eslint/scope-manager@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.3.0.tgz#97d0ccc7c9158e89e202d5e24ce6ba49052d432e" + integrity sha512-22Uic9oRlTsPppy5Tcwfj+QET5RWEnZ5414Prby465XxQrQFZ6nnm5KnXgnsAJefG4hEgMnaxTB3kNEyjdjj6A== dependencies: - "@typescript-eslint/types" "4.23.0" - "@typescript-eslint/visitor-keys" "4.23.0" + "@typescript-eslint/types" "5.3.0" + "@typescript-eslint/visitor-keys" "5.3.0" -"@typescript-eslint/types@4.23.0": - version "4.23.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.23.0.tgz#da1654c8a5332f4d1645b2d9a1c64193cae3aa3b" - integrity sha512-oqkNWyG2SLS7uTWLZf6Sr7Dm02gA5yxiz1RP87tvsmDsguVATdpVguHr4HoGOcFOpCvx9vtCSCyQUGfzq28YCw== +"@typescript-eslint/types@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.3.0.tgz#af29fd53867c2df0028c57c36a655bd7e9e05416" + integrity sha512-fce5pG41/w8O6ahQEhXmMV+xuh4+GayzqEogN24EK+vECA3I6pUwKuLi5QbXO721EMitpQne5VKXofPonYlAQg== -"@typescript-eslint/typescript-estree@4.23.0": - version "4.23.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.23.0.tgz#0753b292097523852428a6f5a1aa8ccc1aae6cd9" - integrity sha512-5Sty6zPEVZF5fbvrZczfmLCOcby3sfrSPu30qKoY1U3mca5/jvU5cwsPb/CO6Q3ByRjixTMIVsDkqwIxCf/dMw== +"@typescript-eslint/typescript-estree@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.0.tgz#4f68ddd46dc2983182402d2ab21fb44ad94988cf" + integrity sha512-FJ0nqcaUOpn/6Z4Jwbtf+o0valjBLkqc3MWkMvrhA2TvzFXtcclIM8F4MBEmYa2kgcI8EZeSAzwoSrIC8JYkug== dependencies: - "@typescript-eslint/types" "4.23.0" - "@typescript-eslint/visitor-keys" "4.23.0" - debug "^4.1.1" - globby "^11.0.1" - is-glob "^4.0.1" - semver "^7.3.2" - tsutils "^3.17.1" + "@typescript-eslint/types" "5.3.0" + "@typescript-eslint/visitor-keys" "5.3.0" + debug "^4.3.2" + globby "^11.0.4" + is-glob "^4.0.3" + semver "^7.3.5" + tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.23.0": - version "4.23.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.23.0.tgz#7215cc977bd3b4ef22467b9023594e32f9e4e455" - integrity sha512-5PNe5cmX9pSifit0H+nPoQBXdbNzi5tOEec+3riK+ku4e3er37pKxMKDH5Ct5Y4fhWxcD4spnlYjxi9vXbSpwg== +"@typescript-eslint/visitor-keys@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.0.tgz#a6258790f3b7b2547f70ed8d4a1e0c3499994523" + integrity sha512-oVIAfIQuq0x2TFDNLVavUn548WL+7hdhxYn+9j3YdJJXB7mH9dAmZNJsPDa7Jc+B9WGqoiex7GUDbyMxV0a/aw== dependencies: - "@typescript-eslint/types" "4.23.0" - eslint-visitor-keys "^2.0.0" + "@typescript-eslint/types" "5.3.0" + eslint-visitor-keys "^3.0.0" "@ungap/promise-all-settled@1.1.2": version "1.1.2" @@ -520,21 +512,44 @@ "@webassemblyjs/helper-numbers" "1.11.0" "@webassemblyjs/helper-wasm-bytecode" "1.11.0" +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/floating-point-hex-parser@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz#34d62052f453cd43101d72eab4966a022587947c" integrity sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA== +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + "@webassemblyjs/helper-api-error@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz#aaea8fb3b923f4aaa9b512ff541b013ffb68d2d4" integrity sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w== +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + "@webassemblyjs/helper-buffer@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz#d026c25d175e388a7dbda9694e91e743cbe9b642" integrity sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA== +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + "@webassemblyjs/helper-numbers@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz#7ab04172d54e312cc6ea4286d7d9fa27c88cd4f9" @@ -544,11 +559,25 @@ "@webassemblyjs/helper-api-error" "1.11.0" "@xtuc/long" "4.2.2" +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + "@webassemblyjs/helper-wasm-bytecode@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz#85fdcda4129902fe86f81abf7e7236953ec5a4e1" integrity sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA== +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + "@webassemblyjs/helper-wasm-section@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz#9ce2cc89300262509c801b4af113d1ca25c1a75b" @@ -559,6 +588,16 @@ "@webassemblyjs/helper-wasm-bytecode" "1.11.0" "@webassemblyjs/wasm-gen" "1.11.0" +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ieee754@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz#46975d583f9828f5d094ac210e219441c4e6f5cf" @@ -566,6 +605,13 @@ dependencies: "@xtuc/ieee754" "^1.2.0" +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + "@webassemblyjs/leb128@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.0.tgz#f7353de1df38aa201cba9fb88b43f41f75ff403b" @@ -573,11 +619,23 @@ dependencies: "@xtuc/long" "4.2.2" +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + "@webassemblyjs/utf8@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.0.tgz#86e48f959cf49e0e5091f069a709b862f5a2cadf" integrity sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw== +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + "@webassemblyjs/wasm-edit@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz#ee4a5c9f677046a210542ae63897094c2027cb78" @@ -592,6 +650,20 @@ "@webassemblyjs/wasm-parser" "1.11.0" "@webassemblyjs/wast-printer" "1.11.0" +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + "@webassemblyjs/wasm-gen@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz#3cdb35e70082d42a35166988dda64f24ceb97abe" @@ -603,6 +675,17 @@ "@webassemblyjs/leb128" "1.11.0" "@webassemblyjs/utf8" "1.11.0" +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + "@webassemblyjs/wasm-opt@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz#1638ae188137f4bb031f568a413cd24d32f92978" @@ -613,6 +696,16 @@ "@webassemblyjs/wasm-gen" "1.11.0" "@webassemblyjs/wasm-parser" "1.11.0" +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wasm-parser@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz#3e680b8830d5b13d1ec86cc42f38f3d4a7700754" @@ -625,6 +718,18 @@ "@webassemblyjs/leb128" "1.11.0" "@webassemblyjs/utf8" "1.11.0" +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + "@webassemblyjs/wast-printer@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz#680d1f6a5365d6d401974a8e949e05474e1fab7e" @@ -633,22 +738,30 @@ "@webassemblyjs/ast" "1.11.0" "@xtuc/long" "4.2.2" -"@webpack-cli/configtest@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.0.3.tgz#204bcff87cda3ea4810881f7ea96e5f5321b87b9" - integrity sha512-WQs0ep98FXX2XBAfQpRbY0Ma6ADw8JR6xoIkaIiJIzClGOMqVRvPCWqndTxf28DgFopWan0EKtHtg/5W1h0Zkw== +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" -"@webpack-cli/info@^1.2.4": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.2.4.tgz#7381fd41c9577b2d8f6c2594fad397ef49ad5573" - integrity sha512-ogE2T4+pLhTTPS/8MM3IjHn0IYplKM4HbVNMCWA9N4NrdPzunwenpCsqKEXyejMfRu6K8mhauIPYf8ZxWG5O6g== +"@webpack-cli/configtest@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043" + integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg== + +"@webpack-cli/info@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223" + integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw== dependencies: envinfo "^7.7.3" -"@webpack-cli/serve@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.4.0.tgz#f84fd07bcacefe56ce762925798871092f0f228e" - integrity sha512-xgT/HqJ+uLWGX+Mzufusl3cgjAcnqYYskaB7o0vRcwOEfuu6hMzSILQpnIzFMGsTaeaX4Nnekl+6fadLbl1/Vg== +"@webpack-cli/serve@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2" + integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -681,32 +794,37 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + acorn-jsx@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.1.1, acorn@^7.4.0: +acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.1.0, acorn@^8.2.1: +acorn@^8.2.1: version "8.2.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0" integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg== -agent-base@5: - version "5.1.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c" - integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g== +acorn@^8.4.1, acorn@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" + integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== -agent-base@6: +agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -726,7 +844,7 @@ ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: +ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -746,16 +864,6 @@ ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1: - version "8.3.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.3.0.tgz#25ee7348e32cdc4a1dbb38256bf6bdc451dd577c" - integrity sha512-RYE7B5An83d7eWnDR8kbdaIFqmKCNsP16ay1hDbJEU+sa0e3H9SebskCt0Uufem6cfAVu7Col6ubcn/W+Sm8/Q== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - ansi-colors@4.1.1, ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -799,6 +907,14 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + app-root-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad" @@ -843,48 +959,16 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -async@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" - integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - available-typed-arrays@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" @@ -892,47 +976,16 @@ available-typed-arrays@^1.0.2: dependencies: array-filter "^1.0.0" -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - binary-extensions@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== -bl@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - body-parser@1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" @@ -995,14 +1048,6 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== -buffer@^5.2.1, buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1051,11 +1096,6 @@ caniuse-lite@^1.0.30001219: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - chai@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" @@ -1113,30 +1153,20 @@ chokidar@3.5.1: optionalDependencies: fsevents "~2.3.1" -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -chrome-devtools-frontend@1.0.445684: - version "1.0.445684" - resolved "https://registry.yarnpkg.com/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.445684.tgz#8540131836024df2b70fe90d0322af368931d762" - integrity sha1-hUATGDYCTfK3D+kNAyKvNokx12I= - -chrome-timeline@0.0.15: - version "0.0.15" - resolved "https://registry.yarnpkg.com/chrome-timeline/-/chrome-timeline-0.0.15.tgz#4fbc719d6abf08e0a0b1f0d5fea80ac461c4410b" - integrity sha512-6vc+MiyFsiOIAje+Z9MFurk9sDnKE5/WknPDpvPfApzApUxdhrml2ybTBRe2U3m2v0vYGis4VMLn9nuuoiofDA== +chokidar@3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== dependencies: - "@types/app-root-path" "^1.2.4" - "@types/fs-extra" "9.0.1" - "@types/puppeteer" "^5.4.3" - app-root-path "^3.0.0" - devtools-timeline-model "^1.4.0" - fs-extra "9.0.1" - puppeteer "^5.5.0" - simple-git "^2.37.0" - winston "^3.3.3" + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" chrome-trace-event@^1.0.2: version "1.0.3" @@ -1187,7 +1217,7 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= -color-convert@^1.9.0, color-convert@^1.9.1: +color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -1206,50 +1236,26 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@^1.0.0, color-name@~1.1.4: +color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.5.2: - version "1.5.5" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014" - integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" - integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - -colorette@^1.2.1, colorette@^1.2.2: +colorette@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== +colorette@^2.0.14: + version "2.0.16" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + colors@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= -colors@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -colorspace@1.1.x: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" - integrity sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ== - dependencies: - color "3.0.x" - text-hex "1.0.x" - columnify@^1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" @@ -1258,7 +1264,7 @@ columnify@^1.5.4: strip-ansi "^3.0.0" wcwidth "^1.0.0" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -1270,7 +1276,7 @@ commander@^2.12.1, commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^6.1.0, commander@^6.2.1: +commander@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== @@ -1280,6 +1286,11 @@ commander@^7.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +commander@^8.2.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1324,11 +1335,6 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - cross-env@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" @@ -1345,10 +1351,10 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -cssom@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== +cssom@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" + integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== cssom@~0.3.6: version "0.3.8" @@ -1362,21 +1368,14 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== +data-urls@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.1.tgz#597fc2ae30f8bc4dbcf731fcd1b1954353afc6f8" + integrity sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw== dependencies: abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^10.0.0" debug@2.6.9: version "2.6.9" @@ -1392,13 +1391,20 @@ debug@4, debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" -debug@4.3.1, debug@^4.0.1, debug@^4.3.1: +debug@4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" +debug@4.3.2, debug@^4.3.1, debug@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1414,6 +1420,11 @@ decimal.js@^10.0.0, decimal.js@^10.2.1: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== +decimal.js@^10.3.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + deep-eql@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" @@ -1443,9 +1454,9 @@ deep-equal@^2.0.5: which-typed-array "^1.1.2" deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== default-require-extensions@^3.0.0: version "3.0.0" @@ -1483,19 +1494,6 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -devtools-protocol@0.0.818844: - version "0.0.818844" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.818844.tgz#d1947278ec85b53e4c8ca598f607a28fa785ba9e" - integrity sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg== - -devtools-timeline-model@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/devtools-timeline-model/-/devtools-timeline-model-1.4.0.tgz#91f9624fb0313fa3ebeda7bf99865357bc66c726" - integrity sha512-zjC31eo4yhPaGC6NnjpksA9ejq9sKtWrQXW9i790RfACXQFrZ/Ba/qcGcU3sqWww/3iZsnZpVDEiTUniKs4CvQ== - dependencies: - chrome-devtools-frontend "1.0.445684" - resolve "1.1.7" - diff@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" @@ -1520,20 +1518,12 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -domexception@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" - integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== +domexception@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== dependencies: - webidl-conversions "^5.0.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" + webidl-conversions "^7.0.0" ee-first@1.1.1: version "1.1.1" @@ -1550,24 +1540,27 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -enabled@2.0.x: - version "2.0.0" - resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" - integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== - encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -end-of-stream@^1.1.0, end-of-stream@^1.4.1: +end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.0: +enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" + integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +enhanced-resolve@^5.8.0: version "5.8.2" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b" integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA== @@ -1628,6 +1621,11 @@ es-module-lexer@^0.4.0: resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.4.1.tgz#dda8c6a14d8f340a24e34331e0fab0cb50438e0e" integrity sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA== +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -1657,7 +1655,7 @@ escape-latex@^1.2.0: resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.2.0.tgz#07c03818cf7dac250cce517f4fda1b001ef2bca1" integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw== -escape-string-regexp@4.0.0: +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== @@ -1684,7 +1682,7 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-scope@^5.0.0, eslint-scope@^5.1.1: +eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -1692,74 +1690,83 @@ eslint-scope@^5.0.0, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^2.0.0, eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== +eslint-scope@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-6.0.0.tgz#9cf45b13c5ac8f3d4c50f46a5121f61b3e318978" + integrity sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA== dependencies: - eslint-visitor-keys "^1.1.0" + esrecurse "^4.3.0" + estraverse "^5.2.0" -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" eslint-visitor-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint@^7.26.0: - version "7.26.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.26.0.tgz#d416fdcdcb3236cd8f282065312813f8c13982f6" - integrity sha512-4R1ieRf52/izcZE7AlLy56uIHHDLT74Yzz2Iv2l6kDaYvEu9x+wMB5dZArVL8SYGXSYV2YAg70FcW5Y5nGGNIg== +eslint-visitor-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186" + integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q== + +eslint@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.1.0.tgz#00f1f7dbf4134f26588e6c9f2efe970760f64664" + integrity sha512-JZvNneArGSUsluHWJ8g8MMs3CfIEzwaLx9KyH4tZ2i+R2/rPWzL8c0zg3rHdwYVpN/1sB9gqnjHwz9HoeJpGHw== dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.1" + "@eslint/eslintrc" "^1.0.3" + "@humanwhocodes/config-array" "^0.6.0" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" - debug "^4.0.1" + debug "^4.3.2" doctrine "^3.0.0" enquirer "^2.3.5" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" + escape-string-regexp "^4.0.0" + eslint-scope "^6.0.0" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.0.0" + espree "^9.0.0" esquery "^1.4.0" esutils "^2.0.2" + fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" + glob-parent "^6.0.1" globals "^13.6.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" - lodash "^4.17.21" + lodash.merge "^4.6.2" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" progress "^2.0.0" - regexpp "^3.1.0" + regexpp "^3.2.0" semver "^7.2.1" strip-ansi "^6.0.0" strip-json-comments "^3.1.0" - table "^6.0.4" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== +espree@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.0.0.tgz#e90a2965698228502e771c7a58489b1a9d107090" + integrity sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ== dependencies: - acorn "^7.4.0" + acorn "^8.5.0" acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" + eslint-visitor-keys "^3.0.0" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" @@ -1785,7 +1792,12 @@ estraverse@^4.1.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.1.0, estraverse@^5.2.0: +estraverse@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +estraverse@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== @@ -1806,9 +1818,9 @@ events@^3.2.0: integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== execa@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" - integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" get-stream "^6.0.0" @@ -1820,12 +1832,12 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -express-ws@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/express-ws/-/express-ws-4.0.0.tgz#dabd8dc974516418902a41fe6e30ed949b4d36c4" - integrity sha512-KEyUw8AwRET2iFjFsI1EJQrJ/fHeGiJtgpYgEWG3yDv4l/To/m3a2GaYfeGyB3lsWdvbesjF5XCMx+SVBgAAYw== +express-ws@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/express-ws/-/express-ws-5.0.2.tgz#5b02d41b937d05199c6c266d7cc931c823bda8eb" + integrity sha512-0uvmuk61O9HXgLhGl3QhNSEtRsQevtmbL94/eILaliEADZBHZOQUAiHFrGPrgsjikohyrmSG5g+sCfASTt0lkQ== dependencies: - ws "^5.2.0" + ws "^7.4.6" express@^4.17.1: version "4.17.1" @@ -1863,12 +1875,7 @@ express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extract-zip@^2.0.0, extract-zip@^2.0.1: +extract-zip@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== @@ -1879,32 +1886,26 @@ extract-zip@^2.0.0, extract-zip@^2.0.1: optionalDependencies: "@types/yauzl" "^2.9.1" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - fast-deep-equal@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== +fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + fast-glob@^3.1.1: - version "3.2.5" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" - integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" + glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" + micromatch "^4.0.4" fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -1916,20 +1917,15 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fast-safe-stringify@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" - integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== - fastest-levenshtein@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== fastq@^1.6.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" - integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify "^1.0.4" @@ -1940,11 +1936,6 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -fecha@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" - integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -2011,14 +2002,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flatted@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" - integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== - -fn.name@1.x.x: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" - integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== + version "3.2.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561" + integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== foreach@^2.0.5: version "2.0.5" @@ -2033,18 +2019,13 @@ foreground-child@^2.0.0: cross-spawn "^7.0.0" signal-exit "^3.0.2" -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" forwarded@~0.1.2: @@ -2067,27 +2048,12 @@ fromentries@^1.2.0: resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.2.0.tgz#e6aa06f240d6267f913cea422075ef88b63e7897" integrity sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ== -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" - integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^1.0.0" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.3.1: +fsevents@~2.3.1, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -2143,20 +2109,20 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: +glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" @@ -2174,7 +2140,7 @@ glob@7.1.6, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.1, glob@^7.1.7: +glob@7.1.7, glob@^7.1.1: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -2186,29 +2152,34 @@ glob@^7.1.1, glob@^7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - -globals@^13.6.0: - version "13.8.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.8.0.tgz#3e20f504810ce87a8d72e55aecf8435b50f4c1b3" - integrity sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q== +globals@^13.6.0, globals@^13.9.0: + version "13.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" + integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg== dependencies: type-fest "^0.20.2" -globby@^11.0.1: - version "11.0.3" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" - integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== +globby@^11.0.4: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" @@ -2222,7 +2193,7 @@ graceful-fs@^4.1.15, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== -graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: +graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== @@ -2232,19 +2203,6 @@ growl@1.10.5: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" @@ -2285,12 +2243,12 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -html-encoding-sniffer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" - integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== +html-encoding-sniffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" + integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== dependencies: - whatwg-encoding "^1.0.5" + whatwg-encoding "^2.0.0" html-escaper@^2.0.0: version "2.0.2" @@ -2319,21 +2277,13 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-proxy-agent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b" - integrity sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg== - dependencies: - agent-base "5" + "@tootallnate/once" "2" + agent-base "6" debug "4" https-proxy-agent@^5.0.0: @@ -2356,24 +2306,19 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" - integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== +iconv-lite@0.6.3, iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.4: +ignore@^5.1.4, ignore@^5.1.8: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== @@ -2387,9 +2332,9 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: resolve-from "^4.0.0" import-local@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" - integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + version "3.0.3" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0" + integrity sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA== dependencies: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" @@ -2412,7 +2357,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2427,6 +2372,11 @@ interpret@^2.2.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -2439,11 +2389,6 @@ is-arguments@^1.0.4, is-arguments@^1.1.0: dependencies: call-bind "^1.0.0" -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - is-bigint@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" @@ -2469,9 +2414,9 @@ is-callable@^1.1.4, is-callable@^1.2.3: integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== is-core-module@^2.2.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" - integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== + version "2.8.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== dependencies: has "^1.0.3" @@ -2495,7 +2440,14 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: +is-glob@^4.0.0, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -2534,7 +2486,7 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-potential-custom-element-name@^1.0.0: +is-potential-custom-element-name@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== @@ -2580,11 +2532,16 @@ is-typed-array@^1.1.3: foreach "^2.0.5" has-symbols "^1.0.1" -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + is-weakmap@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" @@ -2605,11 +2562,6 @@ isarray@^2.0.5: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2620,11 +2572,6 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" @@ -2703,6 +2650,15 @@ jest-worker@^26.6.2: merge-stream "^2.0.0" supports-color "^7.0.0" +jest-worker@^27.0.6: + version "27.3.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.3.1.tgz#0def7feae5b8042be38479799aeb7b5facac24b2" + integrity sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jpeg-js@^0.4.2: version "0.4.3" resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b" @@ -2720,6 +2676,13 @@ js-yaml@4.0.0: dependencies: argparse "^2.0.1" +js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + js-yaml@^3.13.1: version "3.14.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" @@ -2728,42 +2691,38 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsdom@^16.5.3: - version "16.5.3" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.3.tgz#13a755b3950eb938b4482c407238ddf16f0d2136" - integrity sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA== +jsdom@^18.0.1: + version "18.0.1" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-18.0.1.tgz#7317c91be425f31ff25814ad427eed8a2a310b61" + integrity sha512-mgVzrYP4IJiJKVqXkAdBn+jg+nQgPusBxTJulz3m1Y/1RIrkk8aDoNaQE5BNbHwe72WwiwE7k3Av2THXDpvzPQ== dependencies: abab "^2.0.5" - acorn "^8.1.0" + acorn "^8.5.0" acorn-globals "^6.0.0" - cssom "^0.4.4" + cssom "^0.5.0" cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" + data-urls "^3.0.1" + decimal.js "^10.3.1" + domexception "^4.0.0" escodegen "^2.0.0" - html-encoding-sniffer "^2.0.1" - is-potential-custom-element-name "^1.0.0" + form-data "^4.0.0" + html-encoding-sniffer "^3.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" nwsapi "^2.2.0" parse5 "6.0.1" - request "^2.88.2" - request-promise-native "^1.0.9" saxes "^5.0.1" symbol-tree "^3.2.4" tough-cookie "^4.0.0" w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.4" - xml-name-validator "^3.0.0" + w3c-xmlserializer "^3.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^10.0.0" + ws "^8.2.3" + xml-name-validator "^4.0.0" jsesc@^2.5.1: version "2.5.2" @@ -2780,26 +2739,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - json5@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.2.tgz#43ef1f0af9835dd624751a6b7fa48874fb2d608e" @@ -2807,35 +2751,11 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -kuler@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" - integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== - levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -2871,22 +2791,17 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - lodash.flattendeep@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0: +lodash@^4.17.13: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -2898,16 +2813,13 @@ log-symbols@4.0.0: dependencies: chalk "^4.0.0" -logform@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2" - integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg== +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: - colors "^1.2.1" - fast-safe-stringify "^2.0.4" - fecha "^4.2.0" - ms "^2.1.1" - triple-beam "^1.3.0" + chalk "^4.1.0" + is-unicode-supported "^0.1.0" lru-cache@^6.0.0: version "6.0.0" @@ -2962,7 +2874,7 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^4.0.0, micromatch@^4.0.2: +micromatch@^4.0.0, micromatch@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== @@ -2980,7 +2892,19 @@ mime-db@1.47.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19: +mime-db@1.50.0: + version "1.50.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" + integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== + +mime-types@^2.1.12: + version "2.1.33" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" + integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g== + dependencies: + mime-db "1.50.0" + +mime-types@^2.1.27: version "2.1.30" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== @@ -3021,11 +2945,6 @@ minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -mkdirp-classic@^0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - mkdirp@^0.5.3: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -3033,7 +2952,7 @@ mkdirp@^0.5.3: dependencies: minimist "^1.2.5" -mocha@^8.3.2, mocha@^8.4.0: +mocha@^8.3.2: version "8.4.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.4.0.tgz#677be88bf15980a3cae03a73e10a0fc3997f0cff" integrity sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ== @@ -3064,6 +2983,36 @@ mocha@^8.3.2, mocha@^8.4.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" +mocha@^9.1.3: + version "9.1.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.3.tgz#8a623be6b323810493d8c8f6f7667440fa469fdb" + integrity sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.2" + debug "4.3.2" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.1.7" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.1.25" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.1.5" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -3079,7 +3028,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.1.1: +ms@2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -3099,6 +3048,11 @@ nanoid@3.1.20: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== +nanoid@3.1.25: + version "3.1.25" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" + integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -3114,11 +3068,6 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-fetch@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - node-preload@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" @@ -3188,11 +3137,6 @@ nyc@^15.1.0: test-exclude "^6.0.0" yargs "^15.0.2" -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - object-inspect@^1.9.0: version "1.10.3" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" @@ -3235,13 +3179,6 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -one-time@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" - integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== - dependencies: - fn.name "1.x.x" - onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" @@ -3387,11 +3324,6 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -3409,12 +3341,12 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -playwright@^1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.11.0.tgz#0796cf08f4756e8187e01c705315d8e1fb48e25f" - integrity sha512-s3FQBRpu/pW/vZ/lFYhG/Q3WBUbT2rvMgrgy1PHDA7QtPN910C2rj9Ovd6A/m8yxuLnltd/OKqvlAGevWISHKw== +playwright-core@=1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.16.2.tgz#13c4c352a41e431ba167dbadb80e8c628e1e1b79" + integrity sha512-8WkoP5OfZAYrRxtW/PCVACn9bNgqrTxVVPlc+MoxvJ48knNsZ+skrPjfno/XF3SgTUY9DyYX0g5fVOB7lkPtGg== dependencies: - commander "^6.1.0" + commander "^8.2.0" debug "^4.1.1" extract-zip "^2.0.1" https-proxy-agent "^5.0.0" @@ -3425,10 +3357,19 @@ playwright@^1.11.0: proper-lockfile "^4.1.1" proxy-from-env "^1.1.0" rimraf "^3.0.2" + socks-proxy-agent "^6.1.0" stack-utils "^2.0.3" - ws "^7.3.1" + ws "^7.4.6" + yauzl "^2.10.0" yazl "^2.5.1" +playwright@^1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.16.2.tgz#92e1c48a74cab778970facca4094ce79fb57cae4" + integrity sha512-lqndwy5rDIp3tOLex5lnLSrltomqxgVkRkRi547rXoTl2qy7PY2rtHbUouQl7KY2XoVSeSeECYVq/bLJ+bbJNg== + dependencies: + playwright-core "=1.16.2" + pngjs@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" @@ -3444,11 +3385,6 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - process-on-spawn@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/process-on-spawn/-/process-on-spawn-1.0.0.tgz#95b05a23073d30a17acfdc92a440efd2baefdc93" @@ -3456,7 +3392,7 @@ process-on-spawn@^1.0.0: dependencies: fromentries "^1.2.0" -progress@^2.0.0, progress@^2.0.1, progress@^2.0.3: +progress@^2.0.0, progress@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -3478,12 +3414,12 @@ proxy-addr@~2.0.5: forwarded "~0.1.2" ipaddr.js "1.9.1" -proxy-from-env@^1.0.0, proxy-from-env@^1.1.0: +proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -3501,34 +3437,11 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -puppeteer@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-5.5.0.tgz#331a7edd212ca06b4a556156435f58cbae08af00" - integrity sha512-OM8ZvTXAhfgFA7wBIIGlPQzvyEETzDjeRa4mZRCRHxYL+GNH5WAuYUQdja3rpWZvkX/JKqmuVgbsxDNsDFjMEg== - dependencies: - debug "^4.1.0" - devtools-protocol "0.0.818844" - extract-zip "^2.0.0" - https-proxy-agent "^4.0.0" - node-fetch "^2.6.1" - pkg-dir "^4.2.0" - progress "^2.0.1" - proxy-from-env "^1.0.0" - rimraf "^3.0.2" - tar-fs "^2.0.0" - unbzip2-stream "^1.3.3" - ws "^7.2.3" - qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -3556,28 +3469,6 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" -readable-stream@^2.3.7: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.1.1, readable-stream@^3.4.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readdirp@~3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" @@ -3585,10 +3476,17 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + rechoir@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca" - integrity sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q== + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== dependencies: resolve "^1.9.0" @@ -3600,10 +3498,10 @@ regexp.prototype.flags@^1.3.0: call-bind "^1.0.2" define-properties "^1.1.3" -regexpp@^3.0.0, regexpp@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== +regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== release-zalgo@^1.0.0: version "1.0.0" @@ -3612,58 +3510,11 @@ release-zalgo@^1.0.0: dependencies: es6-error "^4.0.1" -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" @@ -3686,11 +3537,6 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= - resolve@^1.3.2: version "1.15.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" @@ -3730,22 +3576,17 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-buffer@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -3766,6 +3607,15 @@ schema-utils@^3.0.0: ajv "^6.12.5" ajv-keywords "^3.5.2" +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + seedrandom@^3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" @@ -3781,7 +3631,7 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1, semver@^7.3.2, semver@^7.3.4: +semver@^7.2.1, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -3814,6 +3664,13 @@ serialize-javascript@5.0.1, serialize-javascript@^5.0.1: dependencies: randombytes "^2.1.0" +serialize-javascript@6.0.0, serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + serve-static@1.14.1: version "1.14.1" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" @@ -3862,40 +3719,42 @@ side-channel@^1.0.3: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.2, signal-exit@^3.0.3: +signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== -simple-git@^2.37.0: - version "2.38.1" - resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.38.1.tgz#6c3ce211777a65482598f4bd93c66443465228c0" - integrity sha512-SeMgUEA6Cmk7Ta57ZzMbkBcAfh8A+DZ6ACZ2onfCp/9UklC9yMJgvcH+GGI3QDTv0lTDIbWtl5LSbBk1UtEfeg== - dependencies: - "@kwsites/file-exists" "^1.1.1" - "@kwsites/promise-deferred" "^1.1.1" - debug "^4.3.1" - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" +signal-exit@^3.0.3: + version "3.0.5" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" + integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== +smart-buffer@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socks-proxy-agent@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.0.tgz#869cf2d7bd10fea96c7ad3111e81726855e285c3" + integrity sha512-57e7lwCN4Tzt3mXz25VxOErJKXlPfXmkMLnk310v/jwW20jWRVcgsOit+xNkN3eIEdB47GwnfAEBLacZ/wVIKg== dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" + agent-base "^6.0.2" + debug "^4.3.1" + socks "^2.6.1" + +socks@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" + integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== + dependencies: + ip "^1.1.5" + smart-buffer "^4.1.0" source-list-map@^2.0.1: version "2.0.1" @@ -3907,16 +3766,24 @@ source-map-js@^0.6.2: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== -source-map-loader@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-2.0.1.tgz#b4fd0ae7fa7e7d3954300f383f2d6fcc230a4261" - integrity sha512-UzOTTQhoNPeTNzOxwFw220RSRzdGSyH4lpNyWjR7Qm34P4/N0W669YSUFdH07+YNeN75h765XLHmNsF/bm97RQ== +source-map-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.0.tgz#f2a04ee2808ad01c774dea6b7d2639839f3b3049" + integrity sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw== dependencies: abab "^2.0.5" iconv-lite "^0.6.2" source-map-js "^0.6.2" -source-map-support@^0.5.19, source-map-support@~0.5.19: +source-map-support@^0.5.20, source-map-support@~0.5.20: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@~0.5.19: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -3956,30 +3823,10 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stack-trace@0.0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - stack-utils@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" - integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== dependencies: escape-string-regexp "^2.0.0" @@ -3988,11 +3835,6 @@ stack-utils@^2.0.3: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - "string-width@^1.0.2 || 2": version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -4026,20 +3868,6 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - strip-ansi@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -4076,7 +3904,7 @@ strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1. resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@8.1.1: +supports-color@8.1.1, supports-color@^8.0.0: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -4102,44 +3930,11 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -table@^6.0.4: - version "6.7.0" - resolved "https://registry.yarnpkg.com/table/-/table-6.7.0.tgz#26274751f0ee099c547f6cb91d3eff0d61d155b2" - integrity sha512-SAM+5p6V99gYiiy2gT5ArdzgM1dLDed0nkrWmG6Fry/bUS/m9x83BwpJUOf1Qj/x2qJd+thL6IkIx7qPGRxqBw== - dependencies: - ajv "^8.0.1" - lodash.clonedeep "^4.5.0" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" - tapable@^2.1.1, tapable@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== -tar-fs@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^2.1.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - terser-webpack-plugin@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz#7effadee06f7ecfa093dbbd3e9ab23f5f3ed8673" @@ -4152,6 +3947,18 @@ terser-webpack-plugin@^5.1.1: source-map "^0.6.1" terser "^5.5.1" +terser-webpack-plugin@^5.1.3: + version "5.2.4" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz#ad1be7639b1cbe3ea49fab995cbe7224b31747a1" + integrity sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA== + dependencies: + jest-worker "^27.0.6" + p-limit "^3.1.0" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + terser "^5.7.2" + terser@^5.5.1: version "5.7.0" resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693" @@ -4161,6 +3968,15 @@ terser@^5.5.1: source-map "~0.7.2" source-map-support "~0.5.19" +terser@^5.7.2: + version "5.9.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.9.0.tgz#47d6e629a522963240f2b55fcaa3c99083d2c351" + integrity sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.20" + test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -4170,21 +3986,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" -text-hex@1.0.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" - integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== - text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -through@^2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - tiny-emitter@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" @@ -4207,14 +4013,6 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== -tough-cookie@^2.3.3, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -4224,22 +4022,17 @@ tough-cookie@^4.0.0: punycode "^2.1.1" universalify "^0.1.2" -tr46@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" - integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== +tr46@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" + integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== dependencies: punycode "^2.1.1" -triple-beam@^1.2.0, triple-beam@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" - integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== - ts-loader@^9.1.2: - version "9.1.2" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.1.2.tgz#ba9b9abb05a514e8ff825791a3f6fcf793272728" - integrity sha512-ryMgATvLLl+z8zQvdlm6Pep0slmwxFWIEnq/5VdiLVjqQXnFJgO+qNLGIIP+d2N2jsFZ9MibZCVDb2bSp7OmEA== + version "9.2.6" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74" + integrity sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" @@ -4282,25 +4075,13 @@ tsutils@^2.29.0: dependencies: tslib "^1.8.1" -tsutils@^3.17.1: +tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -4325,7 +4106,7 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -type-fest@^0.8.0, type-fest@^0.8.1: +type-fest@^0.8.0: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== @@ -4350,11 +4131,16 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^4.2.3, typescript@^4.2.4: +typescript@^4.2.3: version "4.2.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== +typescript@^4.4.4: + version "4.4.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c" + integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA== + unbox-primitive@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" @@ -4365,29 +4151,11 @@ unbox-primitive@^1.0.0: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" -unbzip2-stream@^1.3.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" - integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== - dependencies: - buffer "^5.2.1" - through "^2.3.8" - universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== -universalify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" - integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -4405,22 +4173,17 @@ utf8@^3.0.0: resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.3.2, uuid@^3.3.3: +uuid@^3.3.3: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -v8-compile-cache@^2.0.3, v8-compile-cache@^2.2.0: +v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== @@ -4430,15 +4193,6 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" @@ -4446,12 +4200,12 @@ w3c-hr-time@^1.0.2: dependencies: browser-process-hrtime "^1.0.0" -w3c-xmlserializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" - integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== +w3c-xmlserializer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923" + integrity sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg== dependencies: - xml-name-validator "^3.0.0" + xml-name-validator "^4.0.0" watchpack@^2.0.0: version "2.1.1" @@ -4461,6 +4215,14 @@ watchpack@^2.0.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +watchpack@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce" + integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + wcwidth@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -4468,39 +4230,33 @@ wcwidth@^1.0.0: dependencies: defaults "^1.0.3" -webidl-conversions@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" - integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== -webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - -webpack-cli@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.7.0.tgz#3195a777f1f802ecda732f6c95d24c0004bc5a35" - integrity sha512-7bKr9182/sGfjFm+xdZSwgQuFjgEcy0iCTIBxRUeteJ2Kr8/Wz0qNJX+jw60LU36jApt4nmMkep6+W5AKhok6g== +webpack-cli@^4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" + integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ== dependencies: "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.0.3" - "@webpack-cli/info" "^1.2.4" - "@webpack-cli/serve" "^1.4.0" - colorette "^1.2.1" + "@webpack-cli/configtest" "^1.1.0" + "@webpack-cli/info" "^1.4.0" + "@webpack-cli/serve" "^1.6.0" + colorette "^2.0.14" commander "^7.0.0" execa "^5.0.0" fastest-levenshtein "^1.0.12" import-local "^3.0.2" interpret "^2.2.0" rechoir "^0.7.0" - v8-compile-cache "^2.2.0" webpack-merge "^5.7.3" webpack-merge@^5.7.3: - version "5.7.3" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.7.3.tgz#2a0754e1877a25a8bbab3d2475ca70a052708213" - integrity sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA== + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== dependencies: clone-deep "^4.0.1" wildcard "^2.0.0" @@ -4513,7 +4269,12 @@ webpack-sources@^2.1.1: source-list-map "^2.0.1" source-map "^0.6.1" -webpack@^5, webpack@^5.37.0: +webpack-sources@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.1.tgz#251a7d9720d75ada1469ca07dbb62f3641a05b6d" + integrity sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA== + +webpack@^5: version "5.37.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.37.0.tgz#2ab00f613faf494504eb2beef278dab7493cc39d" integrity sha512-yvdhgcI6QkQkDe1hINBAJ1UNevqNGTVaCkD2SSJcB8rcrNNl922RI8i2DXUAuNfANoxwsiXXEA4ZPZI9q2oGLA== @@ -4542,26 +4303,55 @@ webpack@^5, webpack@^5.37.0: watchpack "^2.0.0" webpack-sources "^2.1.1" -whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== +webpack@^5.61.0: + version "5.61.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.61.0.tgz#fa827f0ee9bdfd141dd73c3e891e955ebd52fe7f" + integrity sha512-fPdTuaYZ/GMGFm4WrPi2KRCqS1vDp773kj9S0iI5Uc//5cszsFEDgHNaX4Rj1vobUiU1dFIV3mA9k1eHeluFpw== dependencies: - iconv-lite "0.4.24" + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.2.0" + webpack-sources "^3.2.0" -whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - -whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" - integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== +whatwg-encoding@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== dependencies: - lodash "^4.7.0" - tr46 "^2.0.2" - webidl-conversions "^6.1.0" + iconv-lite "0.6.3" + +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== + +whatwg-url@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-10.0.0.tgz#37264f720b575b4a311bd4094ed8c760caaa05da" + integrity sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" which-boxed-primitive@^1.0.1, which-boxed-primitive@^1.0.2: version "1.0.2" @@ -4621,29 +4411,6 @@ wildcard@^2.0.0: resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== -winston-transport@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" - integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== - dependencies: - readable-stream "^2.3.7" - triple-beam "^1.2.0" - -winston@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" - integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== - dependencies: - "@dabh/diagnostics" "^2.0.2" - async "^3.1.0" - is-stream "^2.0.0" - logform "^2.2.0" - one-time "^1.0.0" - readable-stream "^3.4.0" - stack-trace "0.0.x" - triple-beam "^1.3.0" - winston-transport "^4.4.0" - word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -4654,6 +4421,11 @@ workerpool@6.1.0: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== +workerpool@6.1.5: + version "6.1.5" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" + integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -4687,32 +4459,30 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" +ws@^7.4.6: + version "7.5.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" + integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== -ws@^7.2.3, ws@^7.3.1, ws@^7.4.4, ws@^7.4.5: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@^8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xml-name-validator@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" + integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xterm-benchmark@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/xterm-benchmark/-/xterm-benchmark-0.2.1.tgz#f7741127aa8eceaffbb0cbbca93d374075e44d64" - integrity sha512-QtfTIlCrjPlzmdjaxRXC0JeE1Dwk25WjNzHR1bTKRqSSQToVw+rcp53o5V5I9AaVWef8vCdJ7lVxXuuX4sphew== +xterm-benchmark@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/xterm-benchmark/-/xterm-benchmark-0.3.0.tgz#8702ae41672ff1e656423336f4e54699a3ab74e8" + integrity sha512-JTC1NjaqAWRHA3vPwbAocOJvz42ysYelrq7z2PS9egly8Hi5W7zfJIZlpkzEsZ8dXo0fcEm/6azmoYFy+TMjig== dependencies: "@types/app-root-path" "^1.2.4" "@types/cli-table" "^0.3.0" @@ -4721,7 +4491,6 @@ xterm-benchmark@^0.2.1: "@types/node" "^12.12.37" "@types/puppeteer" "^5.4.3" app-root-path "^3.0.0" - chrome-timeline "0.0.15" cli-table "^0.3.6" columnify "^1.5.4" commander "^6.2.1" From b29d7d2c8d08dcc89d9cbf290f854678e8219f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 1 Nov 2021 18:39:48 +0100 Subject: [PATCH 15/58] update to windows-2019 on azure --- azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b66c301e..f4c9d7c9 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -59,7 +59,7 @@ jobs: - job: Windows pool: - vmImage: 'vs2017-win2016' + vmImage: 'windows-2019' steps: - task: NodeTool@0 inputs: @@ -124,7 +124,7 @@ jobs: - job: Windows_IntegrationTests pool: - vmImage: 'vs2017-win2016' + vmImage: 'windows-2019' steps: - task: NodeTool@0 inputs: From 32cb95c7fb871a01fdd72be4e439947a1ae9636f Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 5 Nov 2021 08:53:48 -0700 Subject: [PATCH 16/58] Add warning to IBufferLine.length --- typings/xterm.d.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index ba2be988..1b08cc39 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -1343,7 +1343,9 @@ declare module 'xterm' { /** * The length of the line, all call to getCell beyond the length will result - * in `undefined`. + * in `undefined`. Note that this may exceed columns as the line array may + * not be trimmed after a resize, compare against {@link Terminal.cols} to + * get the actual maximum length of a line. */ readonly length: number; From b7e5f0903bb4dab59a79ad2ffe0bbebbe113981a Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Fri, 5 Nov 2021 11:07:03 -0700 Subject: [PATCH 17/58] bump versions --- addons/xterm-addon-serialize/package.json | 2 +- addons/xterm-addon-webgl/package.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/xterm-addon-serialize/package.json b/addons/xterm-addon-serialize/package.json index 77a54dbf..22f308f0 100644 --- a/addons/xterm-addon-serialize/package.json +++ b/addons/xterm-addon-serialize/package.json @@ -1,6 +1,6 @@ { "name": "xterm-addon-serialize", - "version": "0.6.0", + "version": "0.6.1", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" diff --git a/addons/xterm-addon-webgl/package.json b/addons/xterm-addon-webgl/package.json index 226f34ba..32603840 100644 --- a/addons/xterm-addon-webgl/package.json +++ b/addons/xterm-addon-webgl/package.json @@ -1,6 +1,6 @@ { "name": "xterm-addon-webgl", - "version": "0.11.2", + "version": "0.11.3", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" diff --git a/package.json b/package.json index ad288f49..1d413899 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xterm", "description": "Full xterm terminal, in your browser", - "version": "4.14.1", + "version": "4.15.0", "main": "lib/xterm.js", "style": "css/xterm.css", "types": "typings/xterm.d.ts", From 16641a5bb1e012d8c7d6f17ab249c4eec7c30644 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Fri, 5 Nov 2021 11:08:23 -0700 Subject: [PATCH 18/58] Revert "Revert "Avoid property use and float->number conversion"" This reverts commit b627f003e3c8c62e14500bf2adc6f4d210491070. --- src/browser/Viewport.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/browser/Viewport.ts b/src/browser/Viewport.ts index d8df4efa..3c9bea4c 100644 --- a/src/browser/Viewport.ts +++ b/src/browser/Viewport.ts @@ -8,6 +8,8 @@ import { addDisposableDomListener } from 'browser/Lifecycle'; import { IColorSet, IViewport } from 'browser/Types'; import { ICharSizeService, IRenderService } from 'browser/services/Services'; import { IBufferService, IOptionsService } from 'common/services/Services'; +import { IBuffer } from 'common/buffer/Types'; +import { IRenderDimensions } from 'browser/renderer/Types'; const FALLBACK_SCROLL_BAR_WIDTH = 15; @@ -18,12 +20,15 @@ const FALLBACK_SCROLL_BAR_WIDTH = 15; export class Viewport extends Disposable implements IViewport { public scrollBarWidth: number = 0; private _currentRowHeight: number = 0; + private _currentScaledCellHeight: number = 0; private _lastRecordedBufferLength: number = 0; private _lastRecordedViewportHeight: number = 0; private _lastRecordedBufferHeight: number = 0; private _lastTouchY: number = 0; private _lastScrollTop: number = 0; private _lastHadScrollBar: boolean = false; + private _activeBuffer: IBuffer; + private _renderDimensions: IRenderDimensions; // Stores a partial line amount when scrolling, this is used to keep track of how much of a line // is scrolled so we can "scroll" over partial lines and feel natural on touchpads. This is a @@ -51,6 +56,12 @@ export class Viewport extends Disposable implements IViewport { this._lastHadScrollBar = true; this.register(addDisposableDomListener(this._viewportElement, 'scroll', this._onScroll.bind(this))); + // Track properties used in performance critical code manually to avoid using slow getters + this._activeBuffer = this._bufferService.buffer; + this.register(this._bufferService.buffers.onBufferActivate(e => this._activeBuffer = e.activeBuffer)); + this._renderDimensions = this._renderService.dimensions; + this.register(this._renderService.onDimensionsChange(e => this._renderDimensions = e)); + // Perform this async to ensure the ICharSizeService is ready. setTimeout(() => this.syncScrollArea(), 0); } @@ -79,6 +90,7 @@ export class Viewport extends Disposable implements IViewport { private _innerRefresh(): void { if (this._charSizeService.height > 0) { this._currentRowHeight = this._renderService.dimensions.scaledCellHeight / window.devicePixelRatio; + this._currentScaledCellHeight = this._renderService.dimensions.scaledCellHeight; this._lastRecordedViewportHeight = this._viewportElement.offsetHeight; const newBufferHeight = Math.round(this._currentRowHeight * this._lastRecordedBufferLength) + (this._lastRecordedViewportHeight - this._renderService.dimensions.canvasHeight); if (this._lastRecordedBufferHeight !== newBufferHeight) { @@ -126,14 +138,13 @@ export class Viewport extends Disposable implements IViewport { } // If the buffer position doesn't match last scroll top - const newScrollTop = this._bufferService.buffer.ydisp * this._currentRowHeight; - if (this._lastScrollTop !== newScrollTop) { + if (this._lastScrollTop !== this._activeBuffer.ydisp * this._currentRowHeight) { this._refresh(immediate); return; } // If row height changed - if (this._renderService.dimensions.scaledCellHeight / window.devicePixelRatio !== this._currentRowHeight) { + if (this._renderDimensions.scaledCellHeight !== this._currentScaledCellHeight) { this._refresh(immediate); return; } From 82f8e06ff683ebcac305ac14cd40321f358e304f Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 5 Nov 2021 21:34:37 +0200 Subject: [PATCH 19/58] chore: lint using putout --- bin/extract_vtfeatures.js | 6 +++--- bin/publish.js | 8 ++++---- bin/test_api.js | 4 ++-- src/browser/input/MoveToCell.ts | 6 +++--- src/browser/renderer/BaseRenderLayer.ts | 7 +------ src/browser/services/SelectionService.ts | 4 ++-- src/common/input/Keyboard.ts | 2 +- src/common/input/UnicodeV6.test.ts | 2 +- src/common/parser/Params.ts | 5 +++-- test/api/TestUtils.ts | 6 +++--- 10 files changed, 23 insertions(+), 27 deletions(-) diff --git a/bin/extract_vtfeatures.js b/bin/extract_vtfeatures.js index 62ad9ff9..9b5ab898 100644 --- a/bin/extract_vtfeatures.js +++ b/bin/extract_vtfeatures.js @@ -11,13 +11,13 @@ const Mustache = require('mustache'); * regexp to fetch all comments * Fetches all multiline comments and single lines containing '// @vt:'. */ -const REX_COMMENTS = /^\s*?[/][*][*]([\s\S]*?)[*][/]|^\s*?\/\/ ([@]vt[:].*?)$/mug; +const REX_COMMENTS = /^\s*?\/\*\*([\S\s]*?)\*\/|^\s*?\/\/ (@vt:.*?)$/mug; /** * regexp to parse the @vt line * expected data - "@vt: "" "" "" */ -const REX_VT_LINE = /^[@]vt\:\s*(\w+|#\w+|#\w+\[.*?\])\s*(\w+)\s*(\w+)\s*"(.*?)"\s*"(.*?)"\s*"(.*?)".*$/; +const REX_VT_LINE = /^@vt:\s*(\w+|#\w+|#\w+\[.*?\])\s*(\w+)\s*(\w+)\s*"(.*?)"\s*"(.*?)"\s*"(.*?)".*$/; // known vt command types const TYPES = [ @@ -362,7 +362,7 @@ function* parseMultiLineGen(filename, s) { if (!s.includes('@vt:')) { return; } - const lines = s.split('\n').map(el => el.trim().replace(/[*]/, '').replace(/\s/, '')); + const lines = s.split('\n').map(el => el.trim().replace(/\*/, '').replace(/\s/, '')); let grabLine = false; let longDescription = []; let feature = undefined; diff --git a/bin/publish.js b/bin/publish.js index 3c729f6c..75de4b68 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -92,7 +92,7 @@ function checkAndPublishPackage(packageDir) { } function getNextBetaVersion(packageJson) { - if (!/^[0-9]+\.[0-9]+\.[0-9]+$/.exec(packageJson.version)) { + if (!/^\d+\.\d+\.\d+$/.exec(packageJson.version)) { console.error('The package.json version must be of the form x.y.z'); process.exit(1); } @@ -104,11 +104,11 @@ function getNextBetaVersion(packageJson) { return `${nextStableVersion}-${tag}.1`; } const latestPublishedVersion = publishedVersions.sort((a, b) => { - const aVersion = parseInt(a.substr(a.search(/[0-9]+$/))); - const bVersion = parseInt(b.substr(b.search(/[0-9]+$/))); + const aVersion = parseInt(a.substr(a.search(/\d+$/))); + const bVersion = parseInt(b.substr(b.search(/\d+$/))); return aVersion > bVersion ? -1 : 1; })[0]; - const latestTagVersion = parseInt(latestPublishedVersion.substr(latestPublishedVersion.search(/[0-9]+$/)), 10); + const latestTagVersion = parseInt(latestPublishedVersion.substr(latestPublishedVersion.search(/\d+$/)), 10); return `${nextStableVersion}-${tag}.${latestTagVersion + 1}`; } diff --git a/bin/test_api.js b/bin/test_api.js index f173b417..ff166727 100644 --- a/bin/test_api.js +++ b/bin/test_api.js @@ -21,7 +21,7 @@ let flagArgs = []; if (process.argv.length > 2) { const args = process.argv.slice(2); - flagArgs = args.filter(e => e.startsWith('--')).map(arg => arg.split('=')).reduce((arr, val) => arr.concat([...val], [])); + flagArgs = args.filter(e => e.startsWith('--')).map(arg => arg.split('=')).reduce((arr, val) => arr.concat(val.slice(), [])); console.info(flagArgs); // ability to inject particular test files via // yarn test [testFileA testFileB ...] @@ -44,7 +44,7 @@ const server = cp.spawn('node', ['demo/start'], { server.stdout.on('data', (data) => { // await for the server to fully start - if (data.indexOf("successfully") !== -1) { + if (data.includes("successfully")) { const run = cp.spawnSync( npmBinScript('mocha'), [...testFiles, ...flagArgs], { diff --git a/src/browser/input/MoveToCell.ts b/src/browser/input/MoveToCell.ts index 25e1844d..82e767cd 100644 --- a/src/browser/input/MoveToCell.ts +++ b/src/browser/input/MoveToCell.ts @@ -121,7 +121,7 @@ function wrappedRowsCount(startY: number, targetY: number, bufferService: IBuffe for (let i = 0; i < Math.abs(startRow - endRow); i++) { const direction = verticalDirection(startY, targetY) === Direction.UP ? -1 : 1; const line = bufferService.buffer.lines.get(startRow + (direction * i)); - if (line && line.isWrapped) { + if (line?.isWrapped) { wrappedRows++; } } @@ -136,12 +136,12 @@ function wrappedRowsCount(startY: number, targetY: number, bufferService: IBuffe function wrappedRowsForRow(bufferService: IBufferService, currentRow: number): number { let rowCount = 0; let line = bufferService.buffer.lines.get(currentRow); - let lineWraps = line && line.isWrapped; + let lineWraps = line?.isWrapped; while (lineWraps && currentRow >= 0 && currentRow < bufferService.rows) { rowCount++; line = bufferService.buffer.lines.get(--currentRow); - lineWraps = line && line.isWrapped; + lineWraps = line?.isWrapped; } return rowCount; diff --git a/src/browser/renderer/BaseRenderLayer.ts b/src/browser/renderer/BaseRenderLayer.ts index 40b6e3f9..343ebfe2 100644 --- a/src/browser/renderer/BaseRenderLayer.ts +++ b/src/browser/renderer/BaseRenderLayer.ts @@ -325,12 +325,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._currentGlyphIdentifier.bold = !!cell.isBold(); this._currentGlyphIdentifier.dim = !!cell.isDim(); this._currentGlyphIdentifier.italic = !!cell.isItalic(); - const atlasDidDraw = this._charAtlas && this._charAtlas.draw( - this._ctx, - this._currentGlyphIdentifier, - x * this._scaledCellWidth + this._scaledCharLeft, - y * this._scaledCellHeight + this._scaledCharTop - ); + const atlasDidDraw = this._charAtlas?.draw(this._ctx, this._currentGlyphIdentifier, x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop); if (!atlasDidDraw) { this._drawUncachedChars(cell, x, y); diff --git a/src/browser/services/SelectionService.ts b/src/browser/services/SelectionService.ts index c0547755..fce53ecd 100644 --- a/src/browser/services/SelectionService.ts +++ b/src/browser/services/SelectionService.ts @@ -220,7 +220,7 @@ export class SelectionService extends Disposable implements ISelectionService { for (let i = start[1] + 1; i <= end[1] - 1; i++) { const bufferLine = buffer.lines.get(i); const lineText = buffer.translateBufferLineToString(i, true); - if (bufferLine && bufferLine.isWrapped) { + if (bufferLine?.isWrapped) { result[result.length - 1] += lineText; } else { result.push(lineText); @@ -924,7 +924,7 @@ export class SelectionService extends Disposable implements ISelectionService { if (followWrappedLinesBelow) { if (start + length === this._bufferService.cols && bufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) { const nextBufferLine = buffer.lines.get(coords[1] + 1); - if (nextBufferLine && nextBufferLine.isWrapped && nextBufferLine.getCodePoint(0) !== 32 /* ' ' */) { + if (nextBufferLine?.isWrapped && nextBufferLine.getCodePoint(0) !== 32 /* ' ' */) { const nextLineWordPosition = this._getWordAt([0, coords[1] + 1], false, false, true); if (nextLineWordPosition) { length += nextLineWordPosition.length; diff --git a/src/common/input/Keyboard.ts b/src/common/input/Keyboard.ts index 20a28f61..b4b3dce4 100644 --- a/src/common/input/Keyboard.ts +++ b/src/common/input/Keyboard.ts @@ -349,7 +349,7 @@ export function evaluateKeyboardEvent( } else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) { // On macOS this is a third level shift when !macOptionIsMeta. Use instead. const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode]; - const key = keyMapping && keyMapping[!ev.shiftKey ? 0 : 1]; + const key = keyMapping?.[!ev.shiftKey ? 0 : 1]; if (key) { result.key = C0.ESC + key; } else if (ev.keyCode >= 65 && ev.keyCode <= 90) { diff --git a/src/common/input/UnicodeV6.test.ts b/src/common/input/UnicodeV6.test.ts index 9a7fe805..9f89048c 100644 --- a/src/common/input/UnicodeV6.test.ts +++ b/src/common/input/UnicodeV6.test.ts @@ -162,7 +162,7 @@ it('wcwidth should match all values from the old implementation', function(): vo // we are only interested in 2 LSBs, cut off higher bits // ==> n = n & 3 e.g. 000000000000000000000000000000XX return (num: number): number => { - num = num | 0; // get asm.js like optimization under V8 + num |= 0; // get asm.js like optimization under V8 if (num < 32) { return control | 0; } diff --git a/src/common/parser/Params.ts b/src/common/parser/Params.ts index 47ee129d..ce315cf5 100644 --- a/src/common/parser/Params.ts +++ b/src/common/parser/Params.ts @@ -9,6 +9,7 @@ const MAX_VALUE = 0x7FFFFFFF; // max allowed subparams for a single sequence (hardcoded limitation) const MAX_SUBPARAMS = 256; + /** * Params storage class. * This type is used by the parser to accumulate sequence parameters and sub parameters @@ -52,9 +53,9 @@ export class Params implements IParams { return params; } // skip leading sub params - for (let i = (values[0] instanceof Array) ? 1 : 0; i < values.length; ++i) { + for (let i = (Array.isArray(values[0])) ? 1 : 0; i < values.length; ++i) { const value = values[i]; - if (value instanceof Array) { + if (Array.isArray(value)) { for (let k = 0; k < value.length; ++k) { params.addSubParam(value[k]); } diff --git a/test/api/TestUtils.ts b/test/api/TestUtils.ts index 4fa98d43..2acc4d09 100644 --- a/test/api/TestUtils.ts +++ b/test/api/TestUtils.ts @@ -71,11 +71,11 @@ export function getBrowserType(): playwright.BrowserType = { - headless: process.argv.includes('--headless'), - } + headless: process.argv.includes('--headless') + }; const index = process.argv.indexOf('--executablePath'); - if(index > 0 && process.argv.length > index + 1 && typeof process.argv[index + 1] === 'string') { + if (index > 0 && process.argv.length > index + 1 && typeof process.argv[index + 1] === 'string') { options.executablePath = process.argv[index + 1]; } From 01b35ae4eb2910f0992742cf42fc008e99eabb0a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 5 Nov 2021 21:37:50 +0200 Subject: [PATCH 20/58] Update src/common/parser/Params.ts --- src/common/parser/Params.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/parser/Params.ts b/src/common/parser/Params.ts index ce315cf5..7071453d 100644 --- a/src/common/parser/Params.ts +++ b/src/common/parser/Params.ts @@ -9,7 +9,6 @@ const MAX_VALUE = 0x7FFFFFFF; // max allowed subparams for a single sequence (hardcoded limitation) const MAX_SUBPARAMS = 256; - /** * Params storage class. * This type is used by the parser to accumulate sequence parameters and sub parameters From 3582c00a6176fe705d68265bc7ea4bc6cd6c5f31 Mon Sep 17 00:00:00 2001 From: Simon Lamon Date: Sat, 6 Nov 2021 14:36:40 +0000 Subject: [PATCH 21/58] Allow setting multiple options through term.options --- src/browser/Terminal.ts | 4 ---- src/browser/Types.d.ts | 1 - src/browser/public/Terminal.ts | 3 +++ src/common/CoreTerminal.ts | 9 +++++++-- src/common/TestUtils.test.ts | 6 ++++++ src/common/services/Services.ts | 18 ++++++++++-------- typings/xterm.d.ts | 2 +- 7 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 24dc7af9..b0506850 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -52,7 +52,6 @@ import { MouseService } from 'browser/services/MouseService'; import { Linkifier2 } from 'browser/Linkifier2'; import { CoreBrowserService } from 'browser/services/CoreBrowserService'; import { CoreTerminal } from 'common/CoreTerminal'; -import { ITerminalOptions as IInitializedTerminalOptions } from 'common/services/Services'; import { rgba } from 'browser/Color'; import { CharacterJoinerService } from 'browser/services/CharacterJoinerService'; @@ -74,9 +73,6 @@ export class Terminal extends CoreTerminal implements ITerminal { public browser: IBrowser = Browser as any; - // TODO: We should remove options once components adopt optionsService - public get options(): IInitializedTerminalOptions { return this.optionsService.options; } - private _customKeyEventHandler: CustomKeyEventHandler | undefined; // browser services diff --git a/src/browser/Types.d.ts b/src/browser/Types.d.ts index bafeff77..a6165840 100644 --- a/src/browser/Types.d.ts +++ b/src/browser/Types.d.ts @@ -16,7 +16,6 @@ export interface ITerminal extends IPublicTerminal, ICoreTerminal { browser: IBrowser; buffer: IBuffer; viewport: IViewport | undefined; - // TODO: We should remove options once components adopt optionsService options: ITerminalOptions; linkifier: ILinkifier; linkifier2: ILinkifier2; diff --git a/src/browser/public/Terminal.ts b/src/browser/public/Terminal.ts index 087fde94..a5536855 100644 --- a/src/browser/public/Terminal.ts +++ b/src/browser/public/Terminal.ts @@ -92,6 +92,9 @@ export class Terminal implements ITerminalApi { public get options(): ITerminalOptions { return this._core.options; } + public set options(options: ITerminalOptions) { + this._core.options = options; + } public blur(): void { this._core.blur(); } diff --git a/src/common/CoreTerminal.ts b/src/common/CoreTerminal.ts index a5f78f66..6ef9011a 100644 --- a/src/common/CoreTerminal.ts +++ b/src/common/CoreTerminal.ts @@ -22,12 +22,12 @@ */ import { Disposable } from 'common/Lifecycle'; -import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, ICoreMouseService, IUnicodeService, IDirtyRowService, LogLevelEnum } from 'common/services/Services'; +import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, ICoreMouseService, IUnicodeService, IDirtyRowService, LogLevelEnum, ITerminalOptions } from 'common/services/Services'; import { InstantiationService } from 'common/services/InstantiationService'; import { LogService } from 'common/services/LogService'; import { BufferService, MINIMUM_COLS, MINIMUM_ROWS } from 'common/services/BufferService'; import { OptionsService } from 'common/services/OptionsService'; -import { ITerminalOptions, IDisposable, IBufferLine, IAttributeData, ICoreTerminal, IKeyboardEvent, IScrollEvent, ScrollSource } from 'common/Types'; +import { IDisposable, IBufferLine, IAttributeData, ICoreTerminal, IKeyboardEvent, IScrollEvent, ScrollSource } from 'common/Types'; import { CoreService } from 'common/services/CoreService'; import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter'; import { CoreMouseService } from 'common/services/CoreMouseService'; @@ -87,6 +87,11 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal { public get rows(): number { return this._bufferService.rows; } public get buffers(): IBufferSet { return this._bufferService.buffers; } public get options(): ITerminalOptions { return this.optionsService.publicOptions; } + public set options(options: ITerminalOptions) { + for (const key in options) { + this.optionsService.publicOptions[key] = options[key]; + } + } constructor( options: Partial diff --git a/src/common/TestUtils.test.ts b/src/common/TestUtils.test.ts index 014142ac..00aedff6 100644 --- a/src/common/TestUtils.test.ts +++ b/src/common/TestUtils.test.ts @@ -131,6 +131,12 @@ export class MockOptionsService implements IOptionsService { } } } + public setOptions(options: ITerminalOptions): void { + for (const key of Object.keys(options)) { + this.options[key] = options[key]; + this.publicOptions[key] = options[key]; + } + } public setOption(key: string, value: T): void { throw new Error('Method not implemented.'); } diff --git a/src/common/services/Services.ts b/src/common/services/Services.ts index 56b10f73..ed909723 100644 --- a/src/common/services/Services.ts +++ b/src/common/services/Services.ts @@ -164,6 +164,14 @@ export interface IInstantiationService { createInstance any, R extends InstanceType>(t: Ctor, ...args: GetLeadingNonServiceArgs>): R; } +export enum LogLevelEnum { + DEBUG = 0, + INFO = 1, + WARN = 2, + ERROR = 3, + OFF = 4 +} + export const ILogService = createDecorator('LogService'); export interface ILogService { serviceBrand: undefined; @@ -191,13 +199,7 @@ export interface IOptionsService { export type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | number; export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'off'; -export enum LogLevelEnum { - DEBUG = 0, - INFO = 1, - WARN = 2, - ERROR = 3, - OFF = 4 -} + export type RendererType = 'dom' | 'canvas'; export interface ITerminalOptions { @@ -207,6 +209,7 @@ export interface ITerminalOptions { bellSound: string; bellStyle: 'none' | 'sound' /* | 'visual' | 'both' */; cols: number; + convertEol: boolean; cursorBlink: boolean; cursorStyle: 'block' | 'underline' | 'bar'; cursorWidth: number; @@ -240,7 +243,6 @@ export interface ITerminalOptions { [key: string]: any; cancelEvents: boolean; - convertEol: boolean; termName: string; } diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index f67e3a16..39f2bfb0 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -638,7 +638,7 @@ declare module 'xterm' { /** * Get the terminal options */ - readonly options: ITerminalOptions; + options: ITerminalOptions; /** * Natural language strings that can be localized. From b7560be2b5c65ceb418b8540bcf8f338f119477b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 8 Nov 2021 14:03:36 +0100 Subject: [PATCH 22/58] remove named colors --- fixtures/x11-colornames/README.md | 14 - fixtures/x11-colornames/create_module.js | 447 -------------- fixtures/x11-colornames/rgb.txt | 754 ----------------------- src/common/InputHandler.test.ts | 2 +- src/common/InputHandler.ts | 4 +- src/common/data/ColorNames.ts | 91 --- 6 files changed, 2 insertions(+), 1310 deletions(-) delete mode 100644 fixtures/x11-colornames/README.md delete mode 100644 fixtures/x11-colornames/create_module.js delete mode 100644 fixtures/x11-colornames/rgb.txt delete mode 100644 src/common/data/ColorNames.ts diff --git a/fixtures/x11-colornames/README.md b/fixtures/x11-colornames/README.md deleted file mode 100644 index ee6d7b6d..00000000 --- a/fixtures/x11-colornames/README.md +++ /dev/null @@ -1,14 +0,0 @@ -### Fixture for 11 color names - -`rgb.txt` contains X11's defined color names, copied over from `/etc/X11/rgb.txt` on Ubuntu 18. - -Run `create_module.js` to create a TS module containing the color definitions. The script performs these steps: -- extract color definitions from `rgb.txt` -- remove gray definitions (re-added programmatically later) -- create a perfect hash function -- calculate crc10 for basic collision prevention -- run several collision tests -- compress table and color data -- write data with loading shim to `ColorNames.ts` - -The final file is meant to be copied over to `../../src/common/data/`. diff --git a/fixtures/x11-colornames/create_module.js b/fixtures/x11-colornames/create_module.js deleted file mode 100644 index edc1f314..00000000 --- a/fixtures/x11-colornames/create_module.js +++ /dev/null @@ -1,447 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -/** - * For decoder side: - * - reconstruct grays with f = lambda x: (x * 256 - x + 50) / 100 (needs value rounding check) - * - apply nameFilter - * - build lookup & extract functions (runtime decoding?) - * - transfer hashtable and color table - */ - -// match color entry in rgb.txt -const rexFile = /^\s*(\d+)\s*(\d+)\s*(\d+)\s*?[\t]+(.*)$/; -// match greyXX|grayXX names -const rexGrey = /^gr[ae]y\d+/; -// name match -const rexName = /^\w?[A-Za-z0-9 ]+\w/; - -function parseX11Colors(filename) { - const fileData = fs.readFileSync(filename, {encoding: 'utf8'}); - const colors = []; - for (const line of fileData.split('\n')) { - const m = rexFile.exec(line); - if (m) { - colors.push({ - color: [parseInt(m[1]), parseInt(m[2]), parseInt(m[3])], - name: m[4] - }); - } - } - return colors; -} - -// Use the FNV algorithm from http://isthe.com/chongo/tech/comp/fnv/ -function hash(d, name) { - if (!d) d = 0x01000193; - for (const c of name) { - d = ( (d * 0x01000193) ^ c.charCodeAt(0) ) & 0xffffffff; - } - return d >>> 0; -} - -// inspired from http://stevehanov.ca/blog/?id=119 -function createMinimalPerfectHash(nameList) { - const nameMap = Object.create(null); - for (const [idx, name] of nameList.entries()) { - nameMap[name] = idx; - } - const size = nameList.length; - - const buckets = []; - for (let i = 0; i < size; ++i) buckets.push([]); - const g = new Array(size).fill(0); - const v = new Array(size).fill(null); - - for (const key of nameList) { - buckets[hash(0, key) % size].push(key); - } - - buckets.sort((a, b) => b.length - a.length); - let breakIdx = 0; - for (let i = 0; i < size; ++i) { - const bucket = buckets[i]; - if (bucket.length <= 1) { - breakIdx = i; - break; - } - let d = 1; - let item = 0; - let slots = []; - - while (item < bucket.length) { - const slot = hash(d, bucket[item]) % size; - if (v[slot] !== null || slots.includes(slot)) { - d++; - item = 0; - slots = []; - } else { - slots.push(slot); - item++; - } - } - - g[hash(0, bucket[0]) % size] = d; - for (let k = 0; k < bucket.length; ++k) { - v[slots[k]] = nameMap[bucket[k]]; - } - } - - const freeList = []; - for (let i = 0; i < size; ++i) { - if (v[i] === null) freeList.push(i); - } - - for (let i = breakIdx; i < size; ++i) { - const bucket = buckets[i]; - if (!bucket.length) break; - const slot = freeList.pop(); - g[hash(0, bucket[0]) % size] = -slot - 1; - v[slot] = nameMap[bucket[0]]; - } - - return [g, v]; -} - -function lookupPerfectHash(g, v, key) { - const d = g[hash(0, key) % g.length]; - if (d < 0) return v[-d - 1]; - return v[hash(d, key) % v.length]; -} - -function checkPerfectHashTables(g, v, nameList) { - let allPassed = true; - for (const [idx, name] of nameList.entries()) { - const lookup = lookupPerfectHash(g, v, name); - if (lookup !== idx) { - console.log(`\x1b[33mmismatch: '${name}' returns ${lookup} (orig: ${idx})\x1b[m`); - allPassed = false; - } - } - return allPassed; -} - -function crc10atm(name, crc) { - if (!crc) crc = 0; - for (const c of name) { - const v = c.charCodeAt(0); - crc ^= v << 2; - for (let k = 0; k < 8; k++) { - crc = crc & 0x200 ? (crc << 1) ^ 0x233 : crc << 1; - } - } - crc &= 0x3ff; - return crc >>> 0; -} - -function checkColorList(g, v, crc, colorNames) { - let match = []; - for (const word of colorNames) { - if (!nameFilter(word)) continue; - const idx = lookupPerfectHash(g, v, word); - const crc10 = crc10atm(word); - if (crc[idx] === crc10) { - match.push({idx, word, colorName: colorNames[idx]}); - } - } - return {tested: colorNames.length, match}; -} - -function checkWordlists(g, v, crc, colorNames, filename) { - const fileData = fs.readFileSync(filename, {encoding: 'utf8'}); - const words = fileData.split('\n').filter(el => lookupPerfectHash.length !== 0); - let collisions = []; - for (const word of words) { - if (!nameFilter(word)) continue; - const idx = lookupPerfectHash(g, v, word); - const crc10 = crc10atm(word); - if (crc[idx] === crc10 && word !== colorNames[idx]) { - collisions.push({idx, word, colorName: colorNames[idx]}); - } - } - return {tested: words.length, collisions}; -} - -function nameFilter(name) { - // length 3 - 22 - if (name.length < 3 || name.length > 22) return; - // chars only in [A-Za-z0-9 ] - if (!rexName.exec(name)) return; - return name; -} - -function compressTables(g, v, crc, al) { - // g | v | crc: all in 10 bit (<1024) - // --> 30 bit - // --> fits into 5 bytes of a 64-bit char alphabet - - // g needs an offset for proper zero alignment - const gOffset = -Math.min(...g); - g = g.map(el => el + gOffset); - - // assert we are in 0..2^10 - if (Math.min(...g) < 0 || Math.min(...v) < 0 || Math.min(...crc) < 0 - || Math.max(...g) > 1023 || Math.max(...v) > 1023 || Math.max(...crc) > 1023 - ) { - console.log('\x1b[31mTables out of compressible range, manual fix needed.\x1b[m'); - process.exit(1); - } - - // assert we have same length - if (g.length !== v.length || g.length !== crc.length) { - console.log('\x1b[31mTables length mismatch, manual fix needed.\x1b[m'); - process.exit(1); - } - - // construct compressed data string - let result = ''; - const length = g.length; - for (let i = 0; i < length; ++i) { - let value = (g[i] << 20) | (v[i] << 10) | crc[i]; - let bucket = ''; - for (let k = 0; k < 5; ++k) { - bucket += al[value % al.length]; - value = Math.floor(value / al.length); - } - result += bucket.split('').reverse().join(''); - } - - return [result, length, gOffset]; -} - -function compressColors(colors, al) { - let result = ''; - for (const color of colors) { - let value = (color[0] << 16) | (color[1] << 8) | color[2]; - let bucket = ''; - for (let k = 0; k < 4; ++k) { - bucket += al[value % al.length]; - value = Math.floor(value / al.length); - } - result += bucket.split('').reverse().join(''); - } - return result; -} - -function loadData(bucket, al) { - let value = 0; - for (const c of bucket) { - value *= al.length; - value += al.indexOf(c); - } - return [value >>> 20, (value >> 10) & 0x3FF, value & 0x3FF]; -} - -function loadColor(al, data, idx) { - // color buckets are hardcoded to 4 chars - let value = 0; - for (let i = idx * 4; i < idx * 4 + 4; ++i) { - value *= al.length; - value += al.indexOf(data[i]); - } - return [value >>> 16, (value >> 8) & 0xFF, value & 0xFF]; -} - -function lookupIdx(al, data, length, gOffset, name) { - const bl = data.length / length; - let offset = (hash(0, name) % length) * bl; - let [g, v, crc] = loadData(data.slice(offset, offset + bl), al); - offset = g < gOffset - ? (-(g - gOffset) - 1) * bl - : (hash(g - gOffset, name) % length) * bl; - [_, v, _] = loadData(data.slice(offset, offset + bl), al); - offset = v * bl; - [_, _, crc] = loadData(data.slice(offset, offset + bl), al); - return crc10atm(name) === crc ? v : -1; -} - -function lookup(al, data, colorData, length, gOffset, name) { - const idx = lookupIdx(al, data, length, gOffset, name); - if (idx === -1) return; - return loadColor(al, colorData, idx); -} - -function createModule(tableData, colorData, alphabet, gOffset, length) { - const TMPL = `/** - * Copyright (c) 2021 The xterm.js authors. All rights reserved. - * @license MIT - */ - -/** - * This module enables X11 color name lookups with the help of a perfect hash function - * to not penalize the package size too much. - * saving: ~70% (from 17kB down to 5kB) - */ - -// Note: module and table data created with fixtures/x11-colornames/create_module.js -const TABLE = '${tableData}'; -const COLORS = '${colorData}'; -const ALPHABET = '${alphabet}'; -const OFFSET = ${gOffset}; -const LENGTH = ${length}; -const BUCKET_LENGTH = TABLE.length / LENGTH; - -// match greyXX|grayXX names -const rexGrey = /^gr[ae]y(\\d+)/; -// name match -const rexName = /^\\w?[A-Za-z0-9 ]+\\w/; - -function gray(n: number): [number, number, number] | undefined { - if (0 <= n && n <= 100) { - const v = Math.floor((n * 256 - n + 50) / 100); - return [v, v, v]; - } - return; -} - -function hash(d: number, name: string): number { - if (!d) d = 0x01000193; - for (const c of name) { - d = ((d * 0x01000193) ^ c.charCodeAt(0)) & 0xffffffff; - } - return d >>> 0; -} - -function crc10(name: string, crc?: number): number { - if (!crc) crc = 0; - for (const c of name) { - crc ^= c.charCodeAt(0) << 2; - for (let k = 0; k < 8; k++) { - crc = crc & 0x200 ? (crc << 1) ^ 0x233 : crc << 1; - } - } - crc &= 0x3ff; - return crc >>> 0; -} - -function loadData(idx: number): [number, number, number] { - let value = 0; - for (let i = idx * BUCKET_LENGTH; i < idx * BUCKET_LENGTH + BUCKET_LENGTH; ++i) { - value *= ALPHABET.length; - value += ALPHABET.indexOf(TABLE[i]); - } - return [value >>> 20, (value >> 10) & 0x3FF, value & 0x3FF]; -} - -function loadColor(idx: number): [number, number, number] { - // color buckets are hardcoded to 4 chars - let v = 0; - for (let i = idx * 4; i < idx * 4 + 4; ++i) { - v *= ALPHABET.length; - v += ALPHABET.indexOf(COLORS[i]); - } - return [v >>> 16, (v >> 8) & 0xFF, v & 0xFF]; -} - -function lookupIdx(name: string): number { - let b = loadData(hash(0, name) % LENGTH); - b = loadData(b[0] < OFFSET ? (-(b[0] - OFFSET) - 1) : hash(b[0] - OFFSET, name) % LENGTH); - const [ , , crc] = loadData(b[1]); - return crc10(name) === crc ? b[1] : -1; -} - -export function getColorFromName(name: string): [number, number, number] | undefined { - // basic name filtering - if (name.length < 3 || name.length > 22 || !rexName.exec(name)) return; - - // handle grays special - const m = rexGrey.exec(name); - if (m) return gray(parseInt(m[1])); - - // grab crc checked idx from PHF - const idx = lookupIdx(name); - if (idx === -1) return; - return loadColor(idx); -} -`; - return TMPL; -} - - -function main() { - // parse definitions from X11 file - const colorList = parseX11Colors(path.join(__dirname, '/rgb.txt')) - .filter(el => !rexGrey.exec(el.name)); // remove greys, as we can reconstruct them later - const nameList = colorList.map(el => el.name); - - // PHF creation and test - const [g, v] = createMinimalPerfectHash(nameList); - if (!checkPerfectHashTables(g, v, nameList)) { - console.error('\x1b[31mPHF creation failed.\x1b[m'); - process.exit(1); - } else { - console.log('\x1b[32mPHF creation successful.\x1b[m'); - } - - // calc 10-bit CRCs to rule to avoid collisions at ~1:1024 - const crc = nameList.map(el => crc10atm(el)); - - // collision check against colorNames - must all collide - console.log('Self collision test:') - const collSelf = checkColorList(g, v, crc, nameList); - console.log('self:', { - entries: collSelf.tested, - matches: collSelf.match.length, - rate: collSelf.tested / collSelf.match.length - }); - if (collSelf.match.length !== collSelf.tested) { - console.error('\x1b[31mSelf collision tested failed.\x1b[m'); - process.exit(1); - } - - // basic collision checks against dictionaries (rates should be greater than 900:1) - console.log('Dictionary collision test:') - const collEnglish = checkWordlists(g, v, crc, nameList, '/usr/share/dict/words'); - console.log('english:', { - entries: collEnglish.tested, - collisions: collEnglish.collisions.length, - rate: collEnglish.tested / collEnglish.collisions.length - }); - //console.log(collEnglish.collisions); - const collnGerman = checkWordlists(g, v, crc, nameList, '/usr/share/dict/ngerman'); - console.log('ngerman:', { - entries: collnGerman.tested, - collisions: collnGerman.collisions.length, - rate: collnGerman.tested / collnGerman.collisions.length - }); - const colloGerman = checkWordlists(g, v, crc, nameList, '/usr/share/dict/ogerman'); - console.log('ogerman:', { - entries: colloGerman.tested, - collisions: colloGerman.collisions.length, - rate: colloGerman.tested / colloGerman.collisions.length - }); - - // compression with custom alphabet - const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?'; - const [tableData, length, gOffset] = compressTables(g, v, crc, ALPHABET); - const colorData = compressColors(colorList.map(el => el.color), ALPHABET); - - // test loading of compressed table data - let failed = false; - for (const name of nameList) { - const orig = lookupPerfectHash(g, v, name); - const idx = lookupIdx(ALPHABET, tableData, length, gOffset, name); - if (idx !== orig) { - console.log('\x1b[31mcompressed loading failed for:\x1b[m', {name, idx, orig}); - failed = true; - } - } - if (failed) process.exit(1); - - // test full color decoding - for (const color of colorList) { - const loaded = lookup(ALPHABET, tableData, colorData, length, gOffset, color.name); - if (loaded[0] !== color.color[0] || loaded[1] !== color.color[1] || loaded[2] !== color.color[2]) { - console.log('\x1b[31mcolor loading failed for:\x1b[m', {color, loaded}); - failed = true; - } - } - if (failed) process.exit(1); - - // if we made it up to here, create decoding boilerplate - const moduleData = createModule(tableData, colorData, ALPHABET, gOffset, length); - fs.writeFileSync(path.join(__dirname, '/ColorNames.ts'), moduleData); - console.log(`${moduleData.length} bytes written to ${path.join(__dirname, '/ColorNames.ts')}`); -} - -main(); diff --git a/fixtures/x11-colornames/rgb.txt b/fixtures/x11-colornames/rgb.txt deleted file mode 100644 index b9e56c60..00000000 --- a/fixtures/x11-colornames/rgb.txt +++ /dev/null @@ -1,754 +0,0 @@ -! $Xorg: rgb.txt,v 1.3 2000/08/17 19:54:00 cpqbld Exp $ -255 250 250 snow -248 248 255 ghost white -248 248 255 GhostWhite -245 245 245 white smoke -245 245 245 WhiteSmoke -220 220 220 gainsboro -255 250 240 floral white -255 250 240 FloralWhite -253 245 230 old lace -253 245 230 OldLace -250 240 230 linen -250 235 215 antique white -250 235 215 AntiqueWhite -255 239 213 papaya whip -255 239 213 PapayaWhip -255 235 205 blanched almond -255 235 205 BlanchedAlmond -255 228 196 bisque -255 218 185 peach puff -255 218 185 PeachPuff -255 222 173 navajo white -255 222 173 NavajoWhite -255 228 181 moccasin -255 248 220 cornsilk -255 255 240 ivory -255 250 205 lemon chiffon -255 250 205 LemonChiffon -255 245 238 seashell -240 255 240 honeydew -245 255 250 mint cream -245 255 250 MintCream -240 255 255 azure -240 248 255 alice blue -240 248 255 AliceBlue -230 230 250 lavender -255 240 245 lavender blush -255 240 245 LavenderBlush -255 228 225 misty rose -255 228 225 MistyRose -255 255 255 white - 0 0 0 black - 47 79 79 dark slate gray - 47 79 79 DarkSlateGray - 47 79 79 dark slate grey - 47 79 79 DarkSlateGrey -105 105 105 dim gray -105 105 105 DimGray -105 105 105 dim grey -105 105 105 DimGrey -112 128 144 slate gray -112 128 144 SlateGray -112 128 144 slate grey -112 128 144 SlateGrey -119 136 153 light slate gray -119 136 153 LightSlateGray -119 136 153 light slate grey -119 136 153 LightSlateGrey -190 190 190 gray -190 190 190 grey -211 211 211 light grey -211 211 211 LightGrey -211 211 211 light gray -211 211 211 LightGray - 25 25 112 midnight blue - 25 25 112 MidnightBlue - 0 0 128 navy - 0 0 128 navy blue - 0 0 128 NavyBlue -100 149 237 cornflower blue -100 149 237 CornflowerBlue - 72 61 139 dark slate blue - 72 61 139 DarkSlateBlue -106 90 205 slate blue -106 90 205 SlateBlue -123 104 238 medium slate blue -123 104 238 MediumSlateBlue -132 112 255 light slate blue -132 112 255 LightSlateBlue - 0 0 205 medium blue - 0 0 205 MediumBlue - 65 105 225 royal blue - 65 105 225 RoyalBlue - 0 0 255 blue - 30 144 255 dodger blue - 30 144 255 DodgerBlue - 0 191 255 deep sky blue - 0 191 255 DeepSkyBlue -135 206 235 sky blue -135 206 235 SkyBlue -135 206 250 light sky blue -135 206 250 LightSkyBlue - 70 130 180 steel blue - 70 130 180 SteelBlue -176 196 222 light steel blue -176 196 222 LightSteelBlue -173 216 230 light blue -173 216 230 LightBlue -176 224 230 powder blue -176 224 230 PowderBlue -175 238 238 pale turquoise -175 238 238 PaleTurquoise - 0 206 209 dark turquoise - 0 206 209 DarkTurquoise - 72 209 204 medium turquoise - 72 209 204 MediumTurquoise - 64 224 208 turquoise - 0 255 255 cyan -224 255 255 light cyan -224 255 255 LightCyan - 95 158 160 cadet blue - 95 158 160 CadetBlue -102 205 170 medium aquamarine -102 205 170 MediumAquamarine -127 255 212 aquamarine - 0 100 0 dark green - 0 100 0 DarkGreen - 85 107 47 dark olive green - 85 107 47 DarkOliveGreen -143 188 143 dark sea green -143 188 143 DarkSeaGreen - 46 139 87 sea green - 46 139 87 SeaGreen - 60 179 113 medium sea green - 60 179 113 MediumSeaGreen - 32 178 170 light sea green - 32 178 170 LightSeaGreen -152 251 152 pale green -152 251 152 PaleGreen - 0 255 127 spring green - 0 255 127 SpringGreen -124 252 0 lawn green -124 252 0 LawnGreen - 0 255 0 green -127 255 0 chartreuse - 0 250 154 medium spring green - 0 250 154 MediumSpringGreen -173 255 47 green yellow -173 255 47 GreenYellow - 50 205 50 lime green - 50 205 50 LimeGreen -154 205 50 yellow green -154 205 50 YellowGreen - 34 139 34 forest green - 34 139 34 ForestGreen -107 142 35 olive drab -107 142 35 OliveDrab -189 183 107 dark khaki -189 183 107 DarkKhaki -240 230 140 khaki -238 232 170 pale goldenrod -238 232 170 PaleGoldenrod -250 250 210 light goldenrod yellow -250 250 210 LightGoldenrodYellow -255 255 224 light yellow -255 255 224 LightYellow -255 255 0 yellow -255 215 0 gold -238 221 130 light goldenrod -238 221 130 LightGoldenrod -218 165 32 goldenrod -184 134 11 dark goldenrod -184 134 11 DarkGoldenrod -188 143 143 rosy brown -188 143 143 RosyBrown -205 92 92 indian red -205 92 92 IndianRed -139 69 19 saddle brown -139 69 19 SaddleBrown -160 82 45 sienna -205 133 63 peru -222 184 135 burlywood -245 245 220 beige -245 222 179 wheat -244 164 96 sandy brown -244 164 96 SandyBrown -210 180 140 tan -210 105 30 chocolate -178 34 34 firebrick -165 42 42 brown -233 150 122 dark salmon -233 150 122 DarkSalmon -250 128 114 salmon -255 160 122 light salmon -255 160 122 LightSalmon -255 165 0 orange -255 140 0 dark orange -255 140 0 DarkOrange -255 127 80 coral -240 128 128 light coral -240 128 128 LightCoral -255 99 71 tomato -255 69 0 orange red -255 69 0 OrangeRed -255 0 0 red -255 105 180 hot pink -255 105 180 HotPink -255 20 147 deep pink -255 20 147 DeepPink -255 192 203 pink -255 182 193 light pink -255 182 193 LightPink -219 112 147 pale violet red -219 112 147 PaleVioletRed -176 48 96 maroon -199 21 133 medium violet red -199 21 133 MediumVioletRed -208 32 144 violet red -208 32 144 VioletRed -255 0 255 magenta -238 130 238 violet -221 160 221 plum -218 112 214 orchid -186 85 211 medium orchid -186 85 211 MediumOrchid -153 50 204 dark orchid -153 50 204 DarkOrchid -148 0 211 dark violet -148 0 211 DarkViolet -138 43 226 blue violet -138 43 226 BlueViolet -160 32 240 purple -147 112 219 medium purple -147 112 219 MediumPurple -216 191 216 thistle -255 250 250 snow1 -238 233 233 snow2 -205 201 201 snow3 -139 137 137 snow4 -255 245 238 seashell1 -238 229 222 seashell2 -205 197 191 seashell3 -139 134 130 seashell4 -255 239 219 AntiqueWhite1 -238 223 204 AntiqueWhite2 -205 192 176 AntiqueWhite3 -139 131 120 AntiqueWhite4 -255 228 196 bisque1 -238 213 183 bisque2 -205 183 158 bisque3 -139 125 107 bisque4 -255 218 185 PeachPuff1 -238 203 173 PeachPuff2 -205 175 149 PeachPuff3 -139 119 101 PeachPuff4 -255 222 173 NavajoWhite1 -238 207 161 NavajoWhite2 -205 179 139 NavajoWhite3 -139 121 94 NavajoWhite4 -255 250 205 LemonChiffon1 -238 233 191 LemonChiffon2 -205 201 165 LemonChiffon3 -139 137 112 LemonChiffon4 -255 248 220 cornsilk1 -238 232 205 cornsilk2 -205 200 177 cornsilk3 -139 136 120 cornsilk4 -255 255 240 ivory1 -238 238 224 ivory2 -205 205 193 ivory3 -139 139 131 ivory4 -240 255 240 honeydew1 -224 238 224 honeydew2 -193 205 193 honeydew3 -131 139 131 honeydew4 -255 240 245 LavenderBlush1 -238 224 229 LavenderBlush2 -205 193 197 LavenderBlush3 -139 131 134 LavenderBlush4 -255 228 225 MistyRose1 -238 213 210 MistyRose2 -205 183 181 MistyRose3 -139 125 123 MistyRose4 -240 255 255 azure1 -224 238 238 azure2 -193 205 205 azure3 -131 139 139 azure4 -131 111 255 SlateBlue1 -122 103 238 SlateBlue2 -105 89 205 SlateBlue3 - 71 60 139 SlateBlue4 - 72 118 255 RoyalBlue1 - 67 110 238 RoyalBlue2 - 58 95 205 RoyalBlue3 - 39 64 139 RoyalBlue4 - 0 0 255 blue1 - 0 0 238 blue2 - 0 0 205 blue3 - 0 0 139 blue4 - 30 144 255 DodgerBlue1 - 28 134 238 DodgerBlue2 - 24 116 205 DodgerBlue3 - 16 78 139 DodgerBlue4 - 99 184 255 SteelBlue1 - 92 172 238 SteelBlue2 - 79 148 205 SteelBlue3 - 54 100 139 SteelBlue4 - 0 191 255 DeepSkyBlue1 - 0 178 238 DeepSkyBlue2 - 0 154 205 DeepSkyBlue3 - 0 104 139 DeepSkyBlue4 -135 206 255 SkyBlue1 -126 192 238 SkyBlue2 -108 166 205 SkyBlue3 - 74 112 139 SkyBlue4 -176 226 255 LightSkyBlue1 -164 211 238 LightSkyBlue2 -141 182 205 LightSkyBlue3 - 96 123 139 LightSkyBlue4 -198 226 255 SlateGray1 -185 211 238 SlateGray2 -159 182 205 SlateGray3 -108 123 139 SlateGray4 -202 225 255 LightSteelBlue1 -188 210 238 LightSteelBlue2 -162 181 205 LightSteelBlue3 -110 123 139 LightSteelBlue4 -191 239 255 LightBlue1 -178 223 238 LightBlue2 -154 192 205 LightBlue3 -104 131 139 LightBlue4 -224 255 255 LightCyan1 -209 238 238 LightCyan2 -180 205 205 LightCyan3 -122 139 139 LightCyan4 -187 255 255 PaleTurquoise1 -174 238 238 PaleTurquoise2 -150 205 205 PaleTurquoise3 -102 139 139 PaleTurquoise4 -152 245 255 CadetBlue1 -142 229 238 CadetBlue2 -122 197 205 CadetBlue3 - 83 134 139 CadetBlue4 - 0 245 255 turquoise1 - 0 229 238 turquoise2 - 0 197 205 turquoise3 - 0 134 139 turquoise4 - 0 255 255 cyan1 - 0 238 238 cyan2 - 0 205 205 cyan3 - 0 139 139 cyan4 -151 255 255 DarkSlateGray1 -141 238 238 DarkSlateGray2 -121 205 205 DarkSlateGray3 - 82 139 139 DarkSlateGray4 -127 255 212 aquamarine1 -118 238 198 aquamarine2 -102 205 170 aquamarine3 - 69 139 116 aquamarine4 -193 255 193 DarkSeaGreen1 -180 238 180 DarkSeaGreen2 -155 205 155 DarkSeaGreen3 -105 139 105 DarkSeaGreen4 - 84 255 159 SeaGreen1 - 78 238 148 SeaGreen2 - 67 205 128 SeaGreen3 - 46 139 87 SeaGreen4 -154 255 154 PaleGreen1 -144 238 144 PaleGreen2 -124 205 124 PaleGreen3 - 84 139 84 PaleGreen4 - 0 255 127 SpringGreen1 - 0 238 118 SpringGreen2 - 0 205 102 SpringGreen3 - 0 139 69 SpringGreen4 - 0 255 0 green1 - 0 238 0 green2 - 0 205 0 green3 - 0 139 0 green4 -127 255 0 chartreuse1 -118 238 0 chartreuse2 -102 205 0 chartreuse3 - 69 139 0 chartreuse4 -192 255 62 OliveDrab1 -179 238 58 OliveDrab2 -154 205 50 OliveDrab3 -105 139 34 OliveDrab4 -202 255 112 DarkOliveGreen1 -188 238 104 DarkOliveGreen2 -162 205 90 DarkOliveGreen3 -110 139 61 DarkOliveGreen4 -255 246 143 khaki1 -238 230 133 khaki2 -205 198 115 khaki3 -139 134 78 khaki4 -255 236 139 LightGoldenrod1 -238 220 130 LightGoldenrod2 -205 190 112 LightGoldenrod3 -139 129 76 LightGoldenrod4 -255 255 224 LightYellow1 -238 238 209 LightYellow2 -205 205 180 LightYellow3 -139 139 122 LightYellow4 -255 255 0 yellow1 -238 238 0 yellow2 -205 205 0 yellow3 -139 139 0 yellow4 -255 215 0 gold1 -238 201 0 gold2 -205 173 0 gold3 -139 117 0 gold4 -255 193 37 goldenrod1 -238 180 34 goldenrod2 -205 155 29 goldenrod3 -139 105 20 goldenrod4 -255 185 15 DarkGoldenrod1 -238 173 14 DarkGoldenrod2 -205 149 12 DarkGoldenrod3 -139 101 8 DarkGoldenrod4 -255 193 193 RosyBrown1 -238 180 180 RosyBrown2 -205 155 155 RosyBrown3 -139 105 105 RosyBrown4 -255 106 106 IndianRed1 -238 99 99 IndianRed2 -205 85 85 IndianRed3 -139 58 58 IndianRed4 -255 130 71 sienna1 -238 121 66 sienna2 -205 104 57 sienna3 -139 71 38 sienna4 -255 211 155 burlywood1 -238 197 145 burlywood2 -205 170 125 burlywood3 -139 115 85 burlywood4 -255 231 186 wheat1 -238 216 174 wheat2 -205 186 150 wheat3 -139 126 102 wheat4 -255 165 79 tan1 -238 154 73 tan2 -205 133 63 tan3 -139 90 43 tan4 -255 127 36 chocolate1 -238 118 33 chocolate2 -205 102 29 chocolate3 -139 69 19 chocolate4 -255 48 48 firebrick1 -238 44 44 firebrick2 -205 38 38 firebrick3 -139 26 26 firebrick4 -255 64 64 brown1 -238 59 59 brown2 -205 51 51 brown3 -139 35 35 brown4 -255 140 105 salmon1 -238 130 98 salmon2 -205 112 84 salmon3 -139 76 57 salmon4 -255 160 122 LightSalmon1 -238 149 114 LightSalmon2 -205 129 98 LightSalmon3 -139 87 66 LightSalmon4 -255 165 0 orange1 -238 154 0 orange2 -205 133 0 orange3 -139 90 0 orange4 -255 127 0 DarkOrange1 -238 118 0 DarkOrange2 -205 102 0 DarkOrange3 -139 69 0 DarkOrange4 -255 114 86 coral1 -238 106 80 coral2 -205 91 69 coral3 -139 62 47 coral4 -255 99 71 tomato1 -238 92 66 tomato2 -205 79 57 tomato3 -139 54 38 tomato4 -255 69 0 OrangeRed1 -238 64 0 OrangeRed2 -205 55 0 OrangeRed3 -139 37 0 OrangeRed4 -255 0 0 red1 -238 0 0 red2 -205 0 0 red3 -139 0 0 red4 -215 7 81 DebianRed -255 20 147 DeepPink1 -238 18 137 DeepPink2 -205 16 118 DeepPink3 -139 10 80 DeepPink4 -255 110 180 HotPink1 -238 106 167 HotPink2 -205 96 144 HotPink3 -139 58 98 HotPink4 -255 181 197 pink1 -238 169 184 pink2 -205 145 158 pink3 -139 99 108 pink4 -255 174 185 LightPink1 -238 162 173 LightPink2 -205 140 149 LightPink3 -139 95 101 LightPink4 -255 130 171 PaleVioletRed1 -238 121 159 PaleVioletRed2 -205 104 137 PaleVioletRed3 -139 71 93 PaleVioletRed4 -255 52 179 maroon1 -238 48 167 maroon2 -205 41 144 maroon3 -139 28 98 maroon4 -255 62 150 VioletRed1 -238 58 140 VioletRed2 -205 50 120 VioletRed3 -139 34 82 VioletRed4 -255 0 255 magenta1 -238 0 238 magenta2 -205 0 205 magenta3 -139 0 139 magenta4 -255 131 250 orchid1 -238 122 233 orchid2 -205 105 201 orchid3 -139 71 137 orchid4 -255 187 255 plum1 -238 174 238 plum2 -205 150 205 plum3 -139 102 139 plum4 -224 102 255 MediumOrchid1 -209 95 238 MediumOrchid2 -180 82 205 MediumOrchid3 -122 55 139 MediumOrchid4 -191 62 255 DarkOrchid1 -178 58 238 DarkOrchid2 -154 50 205 DarkOrchid3 -104 34 139 DarkOrchid4 -155 48 255 purple1 -145 44 238 purple2 -125 38 205 purple3 - 85 26 139 purple4 -171 130 255 MediumPurple1 -159 121 238 MediumPurple2 -137 104 205 MediumPurple3 - 93 71 139 MediumPurple4 -255 225 255 thistle1 -238 210 238 thistle2 -205 181 205 thistle3 -139 123 139 thistle4 - 0 0 0 gray0 - 0 0 0 grey0 - 3 3 3 gray1 - 3 3 3 grey1 - 5 5 5 gray2 - 5 5 5 grey2 - 8 8 8 gray3 - 8 8 8 grey3 - 10 10 10 gray4 - 10 10 10 grey4 - 13 13 13 gray5 - 13 13 13 grey5 - 15 15 15 gray6 - 15 15 15 grey6 - 18 18 18 gray7 - 18 18 18 grey7 - 20 20 20 gray8 - 20 20 20 grey8 - 23 23 23 gray9 - 23 23 23 grey9 - 26 26 26 gray10 - 26 26 26 grey10 - 28 28 28 gray11 - 28 28 28 grey11 - 31 31 31 gray12 - 31 31 31 grey12 - 33 33 33 gray13 - 33 33 33 grey13 - 36 36 36 gray14 - 36 36 36 grey14 - 38 38 38 gray15 - 38 38 38 grey15 - 41 41 41 gray16 - 41 41 41 grey16 - 43 43 43 gray17 - 43 43 43 grey17 - 46 46 46 gray18 - 46 46 46 grey18 - 48 48 48 gray19 - 48 48 48 grey19 - 51 51 51 gray20 - 51 51 51 grey20 - 54 54 54 gray21 - 54 54 54 grey21 - 56 56 56 gray22 - 56 56 56 grey22 - 59 59 59 gray23 - 59 59 59 grey23 - 61 61 61 gray24 - 61 61 61 grey24 - 64 64 64 gray25 - 64 64 64 grey25 - 66 66 66 gray26 - 66 66 66 grey26 - 69 69 69 gray27 - 69 69 69 grey27 - 71 71 71 gray28 - 71 71 71 grey28 - 74 74 74 gray29 - 74 74 74 grey29 - 77 77 77 gray30 - 77 77 77 grey30 - 79 79 79 gray31 - 79 79 79 grey31 - 82 82 82 gray32 - 82 82 82 grey32 - 84 84 84 gray33 - 84 84 84 grey33 - 87 87 87 gray34 - 87 87 87 grey34 - 89 89 89 gray35 - 89 89 89 grey35 - 92 92 92 gray36 - 92 92 92 grey36 - 94 94 94 gray37 - 94 94 94 grey37 - 97 97 97 gray38 - 97 97 97 grey38 - 99 99 99 gray39 - 99 99 99 grey39 -102 102 102 gray40 -102 102 102 grey40 -105 105 105 gray41 -105 105 105 grey41 -107 107 107 gray42 -107 107 107 grey42 -110 110 110 gray43 -110 110 110 grey43 -112 112 112 gray44 -112 112 112 grey44 -115 115 115 gray45 -115 115 115 grey45 -117 117 117 gray46 -117 117 117 grey46 -120 120 120 gray47 -120 120 120 grey47 -122 122 122 gray48 -122 122 122 grey48 -125 125 125 gray49 -125 125 125 grey49 -127 127 127 gray50 -127 127 127 grey50 -130 130 130 gray51 -130 130 130 grey51 -133 133 133 gray52 -133 133 133 grey52 -135 135 135 gray53 -135 135 135 grey53 -138 138 138 gray54 -138 138 138 grey54 -140 140 140 gray55 -140 140 140 grey55 -143 143 143 gray56 -143 143 143 grey56 -145 145 145 gray57 -145 145 145 grey57 -148 148 148 gray58 -148 148 148 grey58 -150 150 150 gray59 -150 150 150 grey59 -153 153 153 gray60 -153 153 153 grey60 -156 156 156 gray61 -156 156 156 grey61 -158 158 158 gray62 -158 158 158 grey62 -161 161 161 gray63 -161 161 161 grey63 -163 163 163 gray64 -163 163 163 grey64 -166 166 166 gray65 -166 166 166 grey65 -168 168 168 gray66 -168 168 168 grey66 -171 171 171 gray67 -171 171 171 grey67 -173 173 173 gray68 -173 173 173 grey68 -176 176 176 gray69 -176 176 176 grey69 -179 179 179 gray70 -179 179 179 grey70 -181 181 181 gray71 -181 181 181 grey71 -184 184 184 gray72 -184 184 184 grey72 -186 186 186 gray73 -186 186 186 grey73 -189 189 189 gray74 -189 189 189 grey74 -191 191 191 gray75 -191 191 191 grey75 -194 194 194 gray76 -194 194 194 grey76 -196 196 196 gray77 -196 196 196 grey77 -199 199 199 gray78 -199 199 199 grey78 -201 201 201 gray79 -201 201 201 grey79 -204 204 204 gray80 -204 204 204 grey80 -207 207 207 gray81 -207 207 207 grey81 -209 209 209 gray82 -209 209 209 grey82 -212 212 212 gray83 -212 212 212 grey83 -214 214 214 gray84 -214 214 214 grey84 -217 217 217 gray85 -217 217 217 grey85 -219 219 219 gray86 -219 219 219 grey86 -222 222 222 gray87 -222 222 222 grey87 -224 224 224 gray88 -224 224 224 grey88 -227 227 227 gray89 -227 227 227 grey89 -229 229 229 gray90 -229 229 229 grey90 -232 232 232 gray91 -232 232 232 grey91 -235 235 235 gray92 -235 235 235 grey92 -237 237 237 gray93 -237 237 237 grey93 -240 240 240 gray94 -240 240 240 grey94 -242 242 242 gray95 -242 242 242 grey95 -245 245 245 gray96 -245 245 245 grey96 -247 247 247 gray97 -247 247 247 grey97 -250 250 250 gray98 -250 250 250 grey98 -252 252 252 gray99 -252 252 252 grey99 -255 255 255 gray100 -255 255 255 grey100 -169 169 169 dark grey -169 169 169 DarkGrey -169 169 169 dark gray -169 169 169 DarkGray -0 0 139 dark blue -0 0 139 DarkBlue -0 139 139 dark cyan -0 139 139 DarkCyan -139 0 139 dark magenta -139 0 139 DarkMagenta -139 0 0 dark red -139 0 0 DarkRed -144 238 144 light green -144 238 144 LightGreen diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index ff1879bc..e8c4c8bf 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -55,7 +55,7 @@ class TestInputHandler extends InputHandler { } } - public parseColorSpec(data: string): void | [number, number, number] { + public parseColorSpec(data: string): undefined | [number, number, number] { return this._parseColorSpec(data); } } diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 9a56de6f..5384bf8d 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -21,7 +21,6 @@ import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowSe import { OscHandler } from 'common/parser/OscParser'; import { DcsHandler } from 'common/parser/DcsParser'; import { IBuffer } from 'common/buffer/Types'; -import { getColorFromName } from 'common/data/ColorNames'; /** * Map collect to glevel. Used in `selectCharset`. @@ -2877,7 +2876,7 @@ export class InputHandler extends Disposable implements IInputHandler { * All other formats like rgbi: or device-independent string specifications * with float numbering are not supported. */ - protected _parseColorSpec(data: string): [number, number, number] | void { + protected _parseColorSpec(data: string): [number, number, number] | undefined { if (!data) return; // also handle uppercases let low = data.toLowerCase(); @@ -2908,7 +2907,6 @@ export class InputHandler extends Disposable implements IInputHandler { return result; } } - return getColorFromName(data); } /** diff --git a/src/common/data/ColorNames.ts b/src/common/data/ColorNames.ts deleted file mode 100644 index 68dd06b6..00000000 --- a/src/common/data/ColorNames.ts +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (c) 2021 The xterm.js authors. All rights reserved. - * @license MIT - */ - -/** - * This module enables X11 color name lookups with the help of a perfect hash function - * to not penalize the package size too much. - * saving: ~70% (from 17kB down to 5kB) - */ - -// Note: module and table data created with fixtures/x11-colornames/create_module.js -const TABLE = 'AB!!!id!jsih!ZYigHp3AkceNiiImVihW3Uih?DFihrenihDEQiwgziieGJvAoMnsidOM3idOtQiciazAsFrtieFZyidKSgAx8odip818ieFiXieF97ic34eihOxpA4UPNidz51A8znjBAX?uBU9ynitOZdigRMNBYgIEBcaXPBk9LVB0xlOB9mcFihmlWCRq0yidmG7idqsHid7RmCV7pCClqRAimG5kCpsb4ipt78CtqLeig17aigJb7ioC4rihzLdigmoNigEDTihzZKCwIz1C4j5sih4QQihlg2igwsHDBFTuDESshDJFzIig1cbihZ3wipZphigiKcihZUxihZLODRm7RilG1Cid3tmDVGffDYJsPDc1JrixgxGidDn3Dli9uDsOl0imDQPiyDhbimDyZihU00icbZSEJs6VieEzpicF2YEqB?PicemNiduxiihEL9ieBjnEuI53icdLPiqBYWiduYFExunsFB3JqFEXPuihnyvFQkNAFVVjlic8SLicIeOFYvurFwrh5icQ4RicHUgidVbJidVA3idN3LGECqgGJiKSGRl8UidT9qipssVGZHNyidy3widTu8idgHsidgcgGdggRGkODXihH!8ilyhpihWj0ihWcailWHjGwO?OilD4BG888ZHJzmGHZtoyicqlkiwWfkicEbdHg3uEHtMkRH0TgkH5MBRIQE9VIUh5VIYeSyieFFgIlC6Qidvc5idv65icprGicNfhItjoJI4N3mJRFpIicLVGJgMY7J2GebKAPoGKyITuidFGWic2olicYLfLFuJDidnoticCc!icx2bieAcuLIv3UicoYuic594LRQ86LZc3NidcphicnOVic09yisjDiitRyFLc7NTicTaFicFbvic6jPLk3JtigqSiL1QJUjJQZpidQvJicUVVidYVsidNOjidNQfidNnLicyCAicHGeidY17icL3cL8DSKMcPzVMgc8dicEg6ig61OMwImmM06KXM6Hl!M96LNicQEbicUjBNAt2Aid4Hwix3w0Ndba5Nt5pqNwuVljBbJaicYjeigAxGN1b!LOEvTnisIIoORf1cOVV!TiczJbiddd5iddgpiclyxidfd8idfuEieACwid?zWih2rlOp2waid?r2OtUKQOxMyjihUpcigKWQO4y32PNAPFidAU6PZAhBPhjAni0PYUiceDridjwXPqEBxPsZ5Cicoi9icBWoieHXOP0B?9QF50CigWlyQJBkUQMs8nici3YQQ?MXidedxicjVCidhu9icqIFidhZjidhBQid0avicmIYQZLp!QdLBNQwFKyipSwfikPB5Q1SZKipSC1idL08Q44Vaic4tpikVWWQ9x5KikK4sig4Afit?bgihvhKRA?wsidxIfidGjgikw?ORRruoRYQWbRh2dkRk!EPRo!Vpig!taR92Glicf4gicxZGSCIB1jED6KSF0tyid0MUieEUnidLfYSRRoKSUk5sSczRfih06gSkpOgikVvGio5X1icp8Kio5NFik0sjix9EQSp8Pvide28icanaidyPpidekWSx71CTANkkicssXTE1nojEbGQTJp32ic?fFTcYU6icuDuicNCIT1B67T4DhEice8dihBd7ismVIUIRe3UVJeiUZBPEVNXn3idXcIj0jici5yT6VgGbJVlXA2idcRxicfAXicT4kicRjbVpnXZieEm?V4feMigLlzV95OGip4?git4nTWF3csicyWQWJGH2ikH?FWMo06ieCn5WSC2fieDOsWUm1Tidor2WZoaQidoCjicz5cWlxroicTKOW4dS9ido5CidnBwic0AWXJX4lXNdDaicS!nXkWPBXotnyYAgsNicrXhicnmHidHe0idHlLicaNvicG8Jida06YMOfFidTV!icY0YidDcrYRiXUYZivaigDO8ig8GPigGNwi88iCikuzkiharXicoAoihJPbihae9ihJmOihJ9xigV9UiwsMyidaEBichf!ic9ZEYk9oiigCARY9kLuidkWPidknpidk?aihh0likBkKZEJFsidjdfieJmgZIU5dieH47isgQIZNxb3ZQn7hidI6HZVIi0il9ZLix9nYih92!ihCeNZZClyZhISFi1IDjid6bQicwQvZl66Eid6riZoGjRicpYuieBC5ic5jfZwlrsicKATimA?cZ8ZO6icxGJieAt2iculVaA40zidYsAacin?aglNzalwMVi9d0mictfZascgqicbxMbABJ?ignSAjYM8?bIhNZigd1qig7eVieJNPbQq8pikKkaigVPligW!fjgR?5bWCHKidCM1bcrI5idppfidpRsi5P6TbkXgIbo2xucEAZdihvCiidPJXidPYxicAACcIXb9isr67cMtDzcgfiVctsKmc8khZigZjTilrC1ihpKGjQhh5dJr30igymSjKJehihMVeig3VrigwENipRc!idKnBdRRFodhKEOdxEc9idEnCidE8zic!9VidK1md18eZit!FHieGkhicJ8SieCXticlSNidbjridA7YeIdgneNtbMeVlKqeZlSZicbpmixtEVesAlzfU2dAfdwW?fsSYbf5w59gB1xOicMKxgN1q8icZbagZPjpidSoWid1Y0ic2JSid1Bhgo7qeidcLjilYKFiw6S2isa5Jgxwl9g00UbicSMohA73XhELGKhUQqNi8cGshgsaridfCIhkkePhtUeth0vCqileCnit5YaiE?plieHKPiJTPmiN7Kt'; -const COLORS = '??r6!Pj?!Pj?9fX19fX13Nzc??rw??rw?fXm?fXm!vDm!uvX!uvX?!?V?!?V?!vN?!vN?!TE?9q5?9q5?96t?96t?!S1??jc???w??rN??rN??Xu8P?w9f?69f?68P??8Pj?8Pj?5ub6??D1??D1?!Th?!Th????AAAAL09PL09PL09PL09PaWlpaWlpaWlpaWlpcICQcICQcICQcICQd4iZd4iZd4iZd4iZvr6!vr6!09PT09PT09PT09PTGRlwGRlwAACAAACAAACAZJXtZJXtSD2LSD2LalrNalrNe2jue2juhHD?hHD?AADNAADNQWnhQWnhAAD?HpD?HpD?AL??AL??h87rh87rh876h876RoK0RoK0sMTesMTerdjmrdjmsODmsODmr!7ur!7uAM7RAM7RSNHMSNHMQODQAP??4P??4P??X56gX56gZs2qZs2qf??UAGQAAGQAVWsvVWsvj7yPj7yPLotXLotXPLNxPLNxILKqILKqmPuYmPuYAP9?AP9?fPwAfPwAAP8Af?8AAPqaAPqarf8vrf8vMs0yMs0yms0yms0yIosiIosia44ja44jvbdrvbdr8OaM7uiq7uiq!vrS!vrS???g???g??8A?9cA7t2C7t2C2qUguIYLuIYLvI!PvI!PzVxczVxci0UTi0UToFItzYU?3riH9fXc9d6z9KRg9KRg0rSM0mkesiIipSoq6ZZ66ZZ6!oBy?6B6?6B6?6UA?4wA?4wA?39Q8ICA8ICA?2NH?0UA?0UA?wAA?2m0?2m0?xST?xST?8DL?7bB?7bB23CT23CTsDBgxxWFxxWF0CCQ0CCQ?wD?7oLu3aDd2nDWulXTulXTmTLMmTLMlADTlADTiiviiivioCDwk3Dbk3Db2L?Y??r67unpzcnJi4mJ??Xu7uXezcW?i4aC?!?b7t?MzcCwi4N4?!TE7tW3zbeei31r?9q57sutza!Vi3dl?96t7s!hzbOLi3le??rN7um?zcmli4lw??jc7ujNzcixi4h4???w7u7gzc3Bi4uD8P?w4O7gwc3Bg4uD??D17uDlzcHFi4OG?!Th7tXSzbe1i3178P??4O7uwc3Ng4uLg2??emfuaVnNRzyLSHb?Q27uOl?NJ0CLAAD?AADuAADNAACLHpD?HIbuGHTNEE6LY7j?XKzuT5TNNmSLAL??ALLuAJrNAGiLh87?fsDubKbNSnCLsOL?pNPujbbNYHuLxuL?udPun7bNbHuLyuH?vNLuorXNbnuLv!??st?umsDNaIOL4P??0e7utM3NeouLu???ru7uls3NZouLmPX?juXuesXNU4aLAPX?AOXuAMXNAIaLAP??AO7uAM3NAIuLl???je7uec3NUouLf??Udu7GZs2qRYt0wf?BtO60m82baYtpVP!fTu6UQ82ALotXmv!akO6QfM18VItUAP9?AO52AM1mAItFAP8AAO4AAM0AAIsAf?8Adu4AZs0ARYsAwP8!s!46ms0yaYsiyv9wvO5oos1abos9??aP7uaFzcZzi4ZO?!yL7tyCzb5wi4FM???g7u7Rzc20i4t6??8A7u4Azc0Ai4sA?9cA7skAza0Ai3UA?8El7rQizZsdi2kU?7kP7q0OzZUMi2UI?8HB7rS0zZubi2lp?2pq7mNjzVVVizo6?4JH7nlCzWg5i0cm?9Ob7sWRzap9i3NV?!e67tiuzbqWi35m?6VP7ppJzYU?i1or?38k7nYhzWYdi0UT?zAw7iwszSYmixoa?0BA7js7zTMziyMj?4xp7oJizXBUi0w5?6B67pVyzYFii1dC?6UA7poAzYUAi1oA?38A7nYAzWYAi0UA?3JW7mpQzVtFiz4v?2NH7lxCzU85izYm?0UA7kAAzTcAiyUA?wAA7gAAzQAAiwAA1wdR?xST7hKJzRB2iwpQ?2607mqnzWCQizpi?7XF7qm4zZGei2Ns?6657qKtzYyVi19l?4Kr7nmfzWiJi0dd?zSz7jCnzSmQixxi?z6W7jqMzTJ4iyJS?wD?7gDuzQDNiwCL?4P67nrpzWnJi0eJ?7v?7q7uzZbNi2aL4Gb?0V?utFLNejeLvz7?sjrumjLNaCKLmzD?kSzufSbNVRqLq4L?n3nuiWjNXUeL?!H?7tLuzbXNi3uLqampqampqampqampAACLAACLAIuLAIuLiwCLiwCLiwAAiwAAkO6QkO6Q'; -const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?'; -const OFFSET = 551; -const LENGTH = 551; -const BUCKET_LENGTH = TABLE.length / LENGTH; - -// match greyXX|grayXX names -const rexGrey = /^gr[ae]y(\d+)/; -// name match -const rexName = /^\w?[A-Za-z0-9 ]+\w/; - -function gray(n: number): [number, number, number] | undefined { - if (0 <= n && n <= 100) { - const v = Math.floor((n * 256 - n + 50) / 100); - return [v, v, v]; - } - return; -} - -function hash(d: number, name: string): number { - if (!d) d = 0x01000193; - for (const c of name) { - d = ((d * 0x01000193) ^ c.charCodeAt(0)) & 0xffffffff; - } - return d >>> 0; -} - -function crc10(name: string, crc?: number): number { - if (!crc) crc = 0; - for (const c of name) { - crc ^= c.charCodeAt(0) << 2; - for (let k = 0; k < 8; k++) { - crc = crc & 0x200 ? (crc << 1) ^ 0x233 : crc << 1; - } - } - crc &= 0x3ff; - return crc >>> 0; -} - -function loadData(idx: number): [number, number, number] { - let value = 0; - for (let i = idx * BUCKET_LENGTH; i < idx * BUCKET_LENGTH + BUCKET_LENGTH; ++i) { - value *= ALPHABET.length; - value += ALPHABET.indexOf(TABLE[i]); - } - return [value >>> 20, (value >> 10) & 0x3FF, value & 0x3FF]; -} - -function loadColor(idx: number): [number, number, number] { - // color buckets are hardcoded to 4 chars - let v = 0; - for (let i = idx * 4; i < idx * 4 + 4; ++i) { - v *= ALPHABET.length; - v += ALPHABET.indexOf(COLORS[i]); - } - return [v >>> 16, (v >> 8) & 0xFF, v & 0xFF]; -} - -function lookupIdx(name: string): number { - let b = loadData(hash(0, name) % LENGTH); - b = loadData(b[0] < OFFSET ? (-(b[0] - OFFSET) - 1) : hash(b[0] - OFFSET, name) % LENGTH); - const [ , , crc] = loadData(b[1]); - return crc10(name) === crc ? b[1] : -1; -} - -export function getColorFromName(name: string): [number, number, number] | undefined { - // basic name filtering - if (name.length < 3 || name.length > 22 || !rexName.exec(name)) return; - - // handle grays special - const m = rexGrey.exec(name); - if (m) return gray(parseInt(m[1])); - - // grab crc checked idx from PHF - const idx = lookupIdx(name); - if (idx === -1) return; - return loadColor(idx); -} From 54375713bc2b049648f03540e611f9c3abd58561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 8 Nov 2021 17:17:39 +0100 Subject: [PATCH 23/58] simplify color events --- src/browser/Color.ts | 6 +- src/browser/Terminal.ts | 71 ++++--------- src/common/InputHandler.test.ts | 144 ++++++++++++--------------- src/common/InputHandler.ts | 96 +++++------------- src/common/Types.d.ts | 21 ++-- src/common/input/XParseColor.test.ts | 93 +++++++++++++++++ src/common/input/XParseColor.ts | 77 ++++++++++++++ 7 files changed, 291 insertions(+), 217 deletions(-) create mode 100644 src/common/input/XParseColor.test.ts create mode 100644 src/common/input/XParseColor.ts diff --git a/src/browser/Color.ts b/src/browser/Color.ts index 2e71c9e6..6a9dff94 100644 --- a/src/browser/Color.ts +++ b/src/browser/Color.ts @@ -4,6 +4,7 @@ */ import { IColor } from 'browser/Types'; +import { IColorRGB } from 'common/Types'; // FIXME: Move Color.ts lib to common? @@ -86,9 +87,8 @@ export namespace color { }; } - export function toXColorName(color: IColor): string { - const [r, g, b] = rgba.toChannels(color.rgba); - return `rgb:${toPaddedHex(r)}${toPaddedHex(r)}/${toPaddedHex(g)}${toPaddedHex(g)}/${toPaddedHex(b)}${toPaddedHex(b)}`; + export function toColorRGB(color: IColor): IColorRGB { + return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF]; } } diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index e8aee572..0602f604 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -39,7 +39,7 @@ import { MouseZoneManager } from 'browser/MouseZoneManager'; import { AccessibilityManager } from './AccessibilityManager'; import { ITheme, IMarker, IDisposable, ISelectionPosition, ILinkProvider } from 'xterm'; import { DomRenderer } from 'browser/renderer/dom/DomRenderer'; -import { IKeyboardEvent, KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IColorEvent } from 'common/Types'; +import { IKeyboardEvent, KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IColorEvent, ColorIndex, IColorRGB } from 'common/Types'; import { evaluateKeyboardEvent } from 'common/input/Keyboard'; import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; @@ -55,6 +55,7 @@ import { CoreTerminal } from 'common/CoreTerminal'; import { ITerminalOptions as IInitializedTerminalOptions } from 'common/services/Services'; import { color, rgba } from 'browser/Color'; import { CharacterJoinerService } from 'browser/services/CharacterJoinerService'; +import { toRgbString } from 'common/input/XParseColor'; // Let it work inside Node.js for automated testing purposes. const document: Document = (typeof window !== 'undefined') ? window.document : null as any; @@ -178,58 +179,26 @@ export class Terminal extends CoreTerminal implements ITerminal { } private _handleColorEvent(event: IColorEvent): void { - if (!this._colorManager) { return; } - - let hasSet = false; - const query: string[] = []; - for (const req of event.requests) { - if (req.color === '?') { - // query color - let ident = ''; - let c: IColor; - switch (req.index) { - case 256: - ident = '10'; - c = this._colorManager.colors.foreground; - break; - case 257: - ident = '11'; - c = this._colorManager.colors.background; - break; - default: - if (0 <= req.index && req.index < 256) { - ident = '4;' + req.index; - c = this._colorManager.colors.ansi[req.index]; - } - } - if (ident) { - query.push(`${C0.ESC}]${ident};${color.toXColorName(c!)}${C0.BEL}`); - } - } else { - // set color - hasSet = true; - switch (req.index) { - case 256: - this._colorManager.colors.foreground = rgba.toColor(...req.color); - break; - case 257: - this._colorManager.colors.background = rgba.toColor(...req.color); - break; - default: - if (0 <= req.index && req.index < 256) { - this._colorManager.colors.ansi[req.index] = rgba.toColor(...req.color); - } - } + if (!this._colorManager) return; + for (const req of event) { + switch (req.index) { + case ColorIndex.FOREGROUND: // OSC 10 + if (req.color) this._colorManager.colors.foreground = rgba.toColor(...req.color); + else this.coreService.triggerDataEvent(`${C0.ESC}]10;${toRgbString(color.toColorRGB(this._colorManager.colors.foreground))}${C0.BEL}`); + break; + case ColorIndex.BACKGROUND: // OSC 11 + if (req.color) this._colorManager.colors.background = rgba.toColor(...req.color); + else this.coreService.triggerDataEvent(`${C0.ESC}]11;${toRgbString(color.toColorRGB(this._colorManager.colors.background))}${C0.BEL}`); + break; + default: // OSC 4 + if (0 <= req.index && req.index < 256) { + if (req.color) this._colorManager.colors.ansi[req.index] = rgba.toColor(...req.color); + else this.coreService.triggerDataEvent(`${C0.ESC}]4;${req.index};${toRgbString(color.toColorRGB(this._colorManager.colors.ansi[req.index]))}${C0.BEL}`); + } } } - - if (query.length) { - this.coreService.triggerDataEvent(query.join('')); - } - if (hasSet) { - this._renderService?.setColors(this._colorManager.colors); - this.viewport?.onThemeChange(this._colorManager.colors); - } + this._renderService?.setColors(this._colorManager.colors); + this.viewport?.onThemeChange(this._colorManager.colors); } public dispose(): void { diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index e8c4c8bf..cc963809 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -5,7 +5,7 @@ import { assert } from 'chai'; import { InputHandler } from 'common/InputHandler'; -import { IBufferLine, IAttributeData, IColorEvent } from 'common/Types'; +import { IBufferLine, IAttributeData, IColorEvent, ColorIndex } from 'common/Types'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; import { CellData } from 'common/buffer/CellData'; import { Attributes, UnderlineStyle } from 'common/buffer/Constants'; @@ -41,7 +41,7 @@ class TestInputHandler extends InputHandler { public get curAttrData(): IAttributeData { return (this as any)._curAttrData; } public get windowTitleStack(): string[] { return this._windowTitleStack; } public get iconNameStack(): string[] { return this._iconNameStack; } - public parseAnsiColorChange(data: string): IColorEvent | null { return this._parseAnsiColorChange(data); } + public parseAnsiColorChange(data: string): IColorEvent{ return this._parseAnsiColorChange(data); } /** * Promise based parse call to await the full resolve of given input data. @@ -54,10 +54,6 @@ class TestInputHandler extends InputHandler { prev = await result; } } - - public parseColorSpec(data: string): undefined | [number, number, number] { - return this._parseColorSpec(data); - } } describe('InputHandler', () => { @@ -1869,114 +1865,98 @@ describe('InputHandler', () => { }); }); describe('OSC', () => { - describe('parse xcolor names', () => { - it('rgb:// scheme in 4/8/12/16 bit', () => { - // 4 bit - assert.deepEqual(inputHandler.parseColorSpec('rgb:0/0/0'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseColorSpec('rgb:f/f/f'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseColorSpec('rgb:1/2/3'), [17, 34, 51]); - // 8 bit - assert.deepEqual(inputHandler.parseColorSpec('rgb:00/00/00'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseColorSpec('rgb:ff/ff/ff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseColorSpec('rgb:11/22/33'), [17, 34, 51]); - // 12 bit - assert.deepEqual(inputHandler.parseColorSpec('rgb:000/000/000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseColorSpec('rgb:fff/fff/fff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseColorSpec('rgb:111/222/333'), [17, 34, 51]); - // 16 bit - assert.deepEqual(inputHandler.parseColorSpec('rgb:0000/0000/0000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseColorSpec('rgb:ffff/ffff/ffff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseColorSpec('rgb:1111/2222/3333'), [17, 34, 51]); - }); - it('#RGB scheme in 4/8/12/16 bit', () => { - // 4 bit - assert.deepEqual(inputHandler.parseColorSpec('#000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseColorSpec('#fff'), [240, 240, 240]); - assert.deepEqual(inputHandler.parseColorSpec('#123'), [16, 32, 48]); - // 8 bit - assert.deepEqual(inputHandler.parseColorSpec('#000000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseColorSpec('#ffffff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseColorSpec('#112233'), [17, 34, 51]); - // 12 bit - assert.deepEqual(inputHandler.parseColorSpec('#000000000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseColorSpec('#fffffffff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseColorSpec('#111222333'), [17, 34, 51]); - // 16 bit - assert.deepEqual(inputHandler.parseColorSpec('#000000000000'), [0, 0, 0]); - assert.deepEqual(inputHandler.parseColorSpec('#ffffffffffff'), [255, 255, 255]); - assert.deepEqual(inputHandler.parseColorSpec('#111122223333'), [17, 34, 51]); - }); - it('supports upper case', () => { - assert.deepEqual(inputHandler.parseColorSpec('RGB:0/A/F'), [0, 170, 255]); - assert.deepEqual(inputHandler.parseColorSpec('#FFF'), [240, 240, 240]); - }); - it('does not parse illegal combinations', () => { - // shifting bit width - assert.equal(inputHandler.parseColorSpec('rgb:0/11/222'), undefined); - // unsupported scheme - assert.equal(inputHandler.parseColorSpec('rgbi:00/11/22'), undefined); - // broken # specifier - assert.equal(inputHandler.parseColorSpec('#aabbbcc'), undefined); - // out of range - assert.equal(inputHandler.parseColorSpec('#aabbgg'), undefined); - assert.equal(inputHandler.parseColorSpec('rgb:aa/bb/gg'), undefined); - }); - }); - - it('4: should parse correct Ansi color change data', () => { // this is testing a private method const event = inputHandler.parseAnsiColorChange('19;rgb:a1/b2/c3'); assert.isNotNull(event); - assert.deepEqual(event!.requests[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); + assert.deepEqual(event![0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); }); - it('4: should ignore incorrect Ansi color change data', () => { // this is testing a private method - assert.isNull(inputHandler.parseAnsiColorChange('17;rgb:a/b/c')); - assert.isNull(inputHandler.parseAnsiColorChange('17;rgb:#aabbcc')); - assert.isNull(inputHandler.parseAnsiColorChange('17;rgba:aa/bb/cc')); - assert.isNull(inputHandler.parseAnsiColorChange('rgb:aa/bb/cc')); + assert.equal(inputHandler.parseAnsiColorChange('17;rgb:a/b/c').length, 0); + assert.equal(inputHandler.parseAnsiColorChange('17;rgb:#aabbcc').length, 0); + assert.equal(inputHandler.parseAnsiColorChange('17;rgba:aa/bb/cc').length, 0); + assert.equal(inputHandler.parseAnsiColorChange('rgb:aa/bb/cc').length, 0); }); - it('4: should parse a list of Ansi color changes', () => { // this is testing a private method const event = inputHandler.parseAnsiColorChange('19;rgb:a1/b2/c3;17;rgb:00/11/22;255;rgb:01/ef/2d'); - assert.isNotNull(event); - assert.equal(event!.requests.length, 3); - assert.deepEqual(event!.requests[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); - assert.deepEqual(event!.requests[1], { index: 17, color: [0x00, 0x11, 0x22] }); - assert.deepEqual(event!.requests[2], { index: 255, color: [0x01, 0xef, 0x2d] }); + assert.equal(event.length, 3); + assert.deepEqual(event[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); + assert.deepEqual(event[1], { index: 17, color: [0x00, 0x11, 0x22] }); + assert.deepEqual(event[2], { index: 255, color: [0x01, 0xef, 0x2d] }); }); it('4: should ignore incorrect colors in a list of Ansi color changes', () => { // this is testing a private method const event = inputHandler.parseAnsiColorChange('19;rgb:a1/b2/c3;17;rgb:WR/ON/G;255;rgb:01/ef/2d'); - assert.equal(event!.requests.length, 2); - assert.deepEqual(event!.requests[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); - assert.deepEqual(event!.requests[1], { index: 255, color: [0x01, 0xef, 0x2d] }); + assert.equal(event.length, 2); + assert.deepEqual(event[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); + assert.deepEqual(event[1], { index: 255, color: [0x01, 0xef, 0x2d] }); }); it('4: should be case insensitive when parsing Ansi color changes', () => { // this is testing a private method const event = inputHandler.parseAnsiColorChange('19;rGb:A1/b2/C3'); - assert.equal(event!.requests.length, 1); - assert.deepEqual(event!.requests[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); + assert.equal(event.length, 1); + assert.deepEqual(event[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); }); it('4: should fire event on Ansi color change', async () => { return new Promise(async r => { inputHandler.onColor(e => { - assert.isNotNull(e); - assert.isNotNull(e!.requests); - assert.deepEqual(e!.requests[0], { index: 17, color: [0x1a, 0x2b, 0x3c] }); - assert.deepEqual(e!.requests[1], { index: 12, color: [0x11, 0x22, 0x33] }); + assert.deepEqual(e[0], { index: 17, color: [0x1a, 0x2b, 0x3c] }); + assert.deepEqual(e[1], { index: 12, color: [0x11, 0x22, 0x33] }); r(); }); await inputHandler.parseP('\x1b]4;17;rgb:1a/2b/3c;12;rgb:11/22/33\x1b\\'); }); }); + + it('10: should create appropriate events', async () => { + const stack: IColorEvent[] = []; + inputHandler.onColor(ev => stack.push(ev)); + // single foreground query --> color undefined + await inputHandler.parseP('\x1b]10;?\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND }]]); + stack.length = 0; + // OSC with multiple values maps to OSC 10 & OSC 11 + await inputHandler.parseP('\x1b]10;?;?;?;?\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND }], [{ index: ColorIndex.BACKGROUND }]]); + stack.length = 0; + // set foreground color events + await inputHandler.parseP('\x1b]10;rgb:01/02/03\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND, color: [1, 2, 3] }]]); + stack.length = 0; + await inputHandler.parseP('\x1b]10;#aabbcc\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND, color: [170, 187, 204] }]]); + stack.length = 0; + // set FG and BG at once + await inputHandler.parseP('\x1b]10;rgb:aa/bb/cc;#001122\x07'); + assert.deepEqual(stack, [ + [{ index: ColorIndex.FOREGROUND, color: [170, 187, 204] }], + [{ index: ColorIndex.BACKGROUND, color: [0, 17, 34] }], + ]); + }); + it('11: should create appropriate events', async () => { + const stack: IColorEvent[] = []; + inputHandler.onColor(ev => stack.push(ev)); + // single foreground query --> color undefined + await inputHandler.parseP('\x1b]11;?\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND }]]); + stack.length = 0; + // OSC 11 with multiple values creates only one BG event + await inputHandler.parseP('\x1b]11;?;?;?;?\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND }]]); + stack.length = 0; + // set background color events + await inputHandler.parseP('\x1b]11;rgb:01/02/03\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND, color: [1, 2, 3] }]]); + stack.length = 0; + await inputHandler.parseP('\x1b]11;#aabbcc\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND, color: [170, 187, 204] }]]); + }); }); // issue #3362 and #2979 diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 5384bf8d..a8d15db1 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -4,7 +4,7 @@ * @license MIT */ -import { IInputHandler, IAttributeData, IDisposable, IWindowOptions, IColorEvent, IParseStack } from 'common/Types'; +import { IInputHandler, IAttributeData, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex } from 'common/Types'; import { C0, C1 } from 'common/data/EscapeSequences'; import { CHARSETS, DEFAULT_CHARSET } from 'common/data/Charsets'; import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser'; @@ -21,6 +21,7 @@ import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowSe import { OscHandler } from 'common/parser/OscParser'; import { DcsHandler } from 'common/parser/DcsParser'; import { IBuffer } from 'common/buffer/Types'; +import { parseColor } from 'common/input/XParseColor'; /** * Map collect to glevel. Used in `selectCharset`. @@ -403,9 +404,9 @@ export class InputHandler extends Disposable implements IInputHandler { // 6 - Enable/disable Special Color Number c // 7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939) // 10 - Change VT100 text foreground color to Pt. - this._parser.registerOscHandler(10, new OscHandler(data => this.queryOrSetFgColor(data))); + this._parser.registerOscHandler(10, new OscHandler(data => this.setOrReportFgColor(data))); // 11 - Change VT100 text background color to Pt. - this._parser.registerOscHandler(11, new OscHandler(data => this.queryOrSetBgColor(data))); + this._parser.registerOscHandler(11, new OscHandler(data => this.setOrReportBgColor(data))); // 12 - Change text cursor color to Pt. // 13 - Change mouse foreground color to Pt. // 14 - Change mouse background color to Pt. @@ -2841,14 +2842,13 @@ export class InputHandler extends Disposable implements IInputHandler { return true; } - protected _parseAnsiColorChange(data: string): IColorEvent | null { - const result: IColorEvent = { requests: [] }; + protected _parseAnsiColorChange(data: string): IColorEvent { + const result: IColorEvent = []; // example data: 5;rgb:aa/bb/cc const regex = /(\d+);rgb:([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})/gi; let match; - while ((match = regex.exec(data)) !== null) { - result.requests.push({ + result.push({ index: parseInt(match[1]), color: [ parseInt(match[2], 16), @@ -2857,58 +2857,9 @@ export class InputHandler extends Disposable implements IInputHandler { ] }); } - - if (result.requests.length === 0) { - return null; - } - return result; } - /** - * Parse color spec to RGB values (8 bit per channel). - * See `man xparsecolor` for details about certain format specifications. - * - * Supported formats: - * - rgb:// with , , in h | hh | hhh | hhhh - * - #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB - * - * All other formats like rgbi: or device-independent string specifications - * with float numbering are not supported. - */ - protected _parseColorSpec(data: string): [number, number, number] | undefined { - if (!data) return; - // also handle uppercases - let low = data.toLowerCase(); - if (low.indexOf('rgb:') === 0) { - // 'rgb:' specifier - low = low.slice(4); - const rex = /^([\da-f]{1})\/([\da-f]{1})\/([\da-f]{1})$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$/; - const m = rex.exec(low); - if (m) { - const base = m[1] ? 15 : m[4] ? 255 : m[7] ? 4095 : 65535; - return [ - Math.round(parseInt(m[1] || m[4] || m[7] || m[10], 16) / base * 255), - Math.round(parseInt(m[2] || m[5] || m[8] || m[11], 16) / base * 255), - Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255) - ]; - } - } else if (low.indexOf('#') === 0) { - // '#' specifier - low = low.slice(1); - const rex = /^[\da-f]+$/; - if (rex.exec(low) && [3, 6, 9, 12].includes(low.length)) { - const adv = low.length / 3; - const result: [number, number, number] = [0, 0, 0]; - for (let i = 0; i < 3; ++i) { - const c = parseInt(low.slice(adv * i, adv * i + adv), 16); - result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8; - } - return result; - } - } - } - /** * OSC 4; ; ST (set ANSI color to ) * @@ -2918,7 +2869,7 @@ export class InputHandler extends Disposable implements IInputHandler { */ public setAnsiColor(data: string): boolean { const event = this._parseAnsiColorChange(data); - if (event) { + if (event.length) { this._onColor.fire(event); } else { @@ -2940,6 +2891,8 @@ export class InputHandler extends Disposable implements IInputHandler { * - `#RRRGGGBBB` - 12 bits per channel, truncated to `#RRGGBB` * - `#RRRRGGGGBBBB` - 16 bits per channel, truncated to `#RRGGBB` * + * **Note:** X11 named colors are currently unsupported. + * * If `Pt` contains `?` instead of a color specification, the terminal * returns a sequence with the current default foreground color * (use that sequence to restore the color after changes). @@ -2947,21 +2900,20 @@ export class InputHandler extends Disposable implements IInputHandler { * **Note:** Other than xterm, xterm.js does not support OSC 12 - 19. * Therefore stacking multiple `Pt` separated by `;` only works for the first two entries. */ - public queryOrSetFgColor(data: string): boolean { - // note: data may contain multiple ? or color names separated with ; - // Multiple values will map through to OSC 10 - 19, but we only support 10 and 11 currently, - // thus truncate to max. 2 entries. - const slots = data.split(';').slice(0, 2); + public setOrReportFgColor(data: string): boolean { + // Note: data may contain multiple values separated with ; mapping to OSC 10 - 19 + const slots = data.split(';'); if (slots[0] === '?') { - this._onColor.fire({ requests: [{ index: 256, color: '?' }] }); + this._onColor.fire([{ index: ColorIndex.FOREGROUND }]); } else { - const color = this._parseColorSpec(slots[0]); + const color = parseColor(slots[0]); if (color) { - this._onColor.fire({ requests: [{ index: 256, color }] }); + this._onColor.fire([{ index: ColorIndex.FOREGROUND, color }]); } } - if (slots.length === 2) { - this.queryOrSetBgColor(slots[1]); + // forward second slot to OSC 11 (higher slots are not supported) + if (slots.length > 1) { + this.setOrReportBgColor(slots[1]); } return true; } @@ -2971,14 +2923,14 @@ export class InputHandler extends Disposable implements IInputHandler { * * @vt: #Y OSC 11 "Set or query default background color" "OSC 11 ; Pt BEL" "Same as OSC 10, but for default background." */ - public queryOrSetBgColor(data: string): boolean { - const slots = data.split(';').slice(0, 1); + public setOrReportBgColor(data: string): boolean { + const slots = data.split(';'); if (slots[0] === '?') { - this._onColor.fire({ requests: [{ index: 257, color: '?' }] }); + this._onColor.fire([{ index: ColorIndex.BACKGROUND }]); } else { - const color = this._parseColorSpec(slots[0]); + const color = parseColor(slots[0]); if (color) { - this._onColor.fire({ requests: [{ index: 257, color }] }); + this._onColor.fire([{ index: ColorIndex.BACKGROUND, color }]); } } return true; diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index 9cc6dbe7..b38a0643 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -348,17 +348,20 @@ export interface IWindowOptions { setWinLines?: boolean; } -export interface IColorEventColor { - index: number; - color: [number, number, number] | '?'; +// color events from common, used for OSC 4/10/11 +export const enum ColorIndex { + FOREGROUND = 256, + BACKGROUND = 257 } +export interface IColorReportRequest { + index: ColorIndex; + color?: IColorRGB; +} +export interface IColorSetRequest extends IColorReportRequest { + color: IColorRGB; +} +export type IColorEvent = (IColorReportRequest | IColorSetRequest)[]; -/** - * Event fired for OSC 4 command - to change ANSI color based on its index. - */ -export interface IColorEvent { - requests: IColorEventColor[]; -} /** * Calls the parser and handles actions generated by the parser. diff --git a/src/common/input/XParseColor.test.ts b/src/common/input/XParseColor.test.ts new file mode 100644 index 00000000..4a73cdbb --- /dev/null +++ b/src/common/input/XParseColor.test.ts @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2021 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import { parseColor, toRgbString } from 'common/input/XParseColor'; + +describe('XParseColor', () => { + describe('parseColor', () => { + it('rgb:// scheme in 4/8/12/16 bit', () => { + // 4 bit + assert.deepEqual(parseColor('rgb:0/0/0'), [0, 0, 0]); + assert.deepEqual(parseColor('rgb:f/f/f'), [255, 255, 255]); + assert.deepEqual(parseColor('rgb:1/2/3'), [17, 34, 51]); + // 8 bit + assert.deepEqual(parseColor('rgb:00/00/00'), [0, 0, 0]); + assert.deepEqual(parseColor('rgb:ff/ff/ff'), [255, 255, 255]); + assert.deepEqual(parseColor('rgb:11/22/33'), [17, 34, 51]); + // 12 bit + assert.deepEqual(parseColor('rgb:000/000/000'), [0, 0, 0]); + assert.deepEqual(parseColor('rgb:fff/fff/fff'), [255, 255, 255]); + assert.deepEqual(parseColor('rgb:111/222/333'), [17, 34, 51]); + // 16 bit + assert.deepEqual(parseColor('rgb:0000/0000/0000'), [0, 0, 0]); + assert.deepEqual(parseColor('rgb:ffff/ffff/ffff'), [255, 255, 255]); + assert.deepEqual(parseColor('rgb:1111/2222/3333'), [17, 34, 51]); + }); + it('#RGB scheme in 4/8/12/16 bit', () => { + // 4 bit + assert.deepEqual(parseColor('#000'), [0, 0, 0]); + assert.deepEqual(parseColor('#fff'), [240, 240, 240]); + assert.deepEqual(parseColor('#123'), [16, 32, 48]); + // 8 bit + assert.deepEqual(parseColor('#000000'), [0, 0, 0]); + assert.deepEqual(parseColor('#ffffff'), [255, 255, 255]); + assert.deepEqual(parseColor('#112233'), [17, 34, 51]); + // 12 bit + assert.deepEqual(parseColor('#000000000'), [0, 0, 0]); + assert.deepEqual(parseColor('#fffffffff'), [255, 255, 255]); + assert.deepEqual(parseColor('#111222333'), [17, 34, 51]); + // 16 bit + assert.deepEqual(parseColor('#000000000000'), [0, 0, 0]); + assert.deepEqual(parseColor('#ffffffffffff'), [255, 255, 255]); + assert.deepEqual(parseColor('#111122223333'), [17, 34, 51]); + }); + it('supports upper case', () => { + assert.deepEqual(parseColor('RGB:0/A/F'), [0, 170, 255]); + assert.deepEqual(parseColor('#FFF'), [240, 240, 240]); + }); + it('does not parse illegal combinations', () => { + // shifting bit width + assert.equal(parseColor('rgb:0/11/222'), undefined); + // unsupported scheme + assert.equal(parseColor('rgbi:00/11/22'), undefined); + // broken # specifier + assert.equal(parseColor('#aabbbcc'), undefined); + // out of range + assert.equal(parseColor('#aabbgg'), undefined); + assert.equal(parseColor('rgb:aa/bb/gg'), undefined); + }); + }); + describe('toXColorRgb', () => { + it('rgb:// scheme in 4/8/12/16 bit', () => { + // 4 bit + assert.equal(toRgbString(parseColor('rgb:0/0/0')!, 4), 'rgb:0/0/0'); + assert.equal(toRgbString(parseColor('rgb:f/f/f')!, 4), 'rgb:f/f/f'); + assert.equal(toRgbString(parseColor('rgb:1/2/3')!, 4), 'rgb:1/2/3'); + // 8 bit + assert.equal(toRgbString(parseColor('rgb:00/00/00')!, 8), 'rgb:00/00/00'); + assert.equal(toRgbString(parseColor('rgb:ff/ff/ff')!, 8), 'rgb:ff/ff/ff'); + assert.equal(toRgbString(parseColor('rgb:11/22/33')!, 8), 'rgb:11/22/33'); + // 12 bit + assert.equal(toRgbString(parseColor('rgb:000/000/000')!, 12), 'rgb:000/000/000'); + assert.equal(toRgbString(parseColor('rgb:fff/fff/fff')!, 12), 'rgb:fff/fff/fff'); + assert.equal(toRgbString(parseColor('rgb:111/222/333')!, 12), 'rgb:111/222/333'); + // 16 bit + assert.equal(toRgbString(parseColor('rgb:0000/0000/0000')!, 16), 'rgb:0000/0000/0000'); + assert.equal(toRgbString(parseColor('rgb:ffff/ffff/ffff')!, 16), 'rgb:ffff/ffff/ffff'); + assert.equal(toRgbString(parseColor('rgb:1111/2222/3333')!, 16), 'rgb:1111/2222/3333'); + }); + it('defaults to 16 bit output', () => { + assert.equal(toRgbString(parseColor('rgb:1/2/3')!), 'rgb:1111/2222/3333'); + assert.equal(toRgbString(parseColor('rgb:11/22/33')!), 'rgb:1111/2222/3333'); + assert.equal(toRgbString(parseColor('rgb:111/222/333')!), 'rgb:1111/2222/3333'); + assert.equal(toRgbString(parseColor('rgb:123/123/123')!), 'rgb:1212/1212/1212'); + }); + it('reduces colors to 8 bit resolution', () => { + assert.equal(toRgbString(parseColor('rgb:123/123/123')!, 12), 'rgb:121/121/121'); + assert.equal(toRgbString(parseColor('rgb:1234/1234/1234')!, 16), 'rgb:1212/1212/1212'); + }); + }); +}); diff --git a/src/common/input/XParseColor.ts b/src/common/input/XParseColor.ts new file mode 100644 index 00000000..922bf8a9 --- /dev/null +++ b/src/common/input/XParseColor.ts @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2021 The xterm.js authors. All rights reserved. + * @license MIT + */ + + +// 'rgb:' rule - matching: r/g/b | rr/gg/bb | rrr/ggg/bbb | rrrr/gggg/bbbb (hex digits) +const RGB_REX = /^([\da-f]{1})\/([\da-f]{1})\/([\da-f]{1})$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$/; +// '#...' rule - matching any hex digits +const HASH_REX = /^[\da-f]+$/; + +/** + * Parse color spec to RGB values (8 bit per channel). + * See `man xparsecolor` for details about certain format specifications. + * + * Supported formats: + * - rgb:// with , , in h | hh | hhh | hhhh + * - #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB + * + * All other formats like rgbi: or device-independent string specifications + * with float numbering are not supported. + */ +export function parseColor(data: string): [number, number, number] | undefined { + if (!data) return; + // also handle uppercases + let low = data.toLowerCase(); + if (low.indexOf('rgb:') === 0) { + // 'rgb:' specifier + low = low.slice(4); + const m = RGB_REX.exec(low); + if (m) { + const base = m[1] ? 15 : m[4] ? 255 : m[7] ? 4095 : 65535; + return [ + Math.round(parseInt(m[1] || m[4] || m[7] || m[10], 16) / base * 255), + Math.round(parseInt(m[2] || m[5] || m[8] || m[11], 16) / base * 255), + Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255) + ]; + } + } else if (low.indexOf('#') === 0) { + // '#' specifier + low = low.slice(1); + if (HASH_REX.exec(low) && [3, 6, 9, 12].includes(low.length)) { + const adv = low.length / 3; + const result: [number, number, number] = [0, 0, 0]; + for (let i = 0; i < 3; ++i) { + const c = parseInt(low.slice(adv * i, adv * i + adv), 16); + result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8; + } + return result; + } + } + // FIXME: Once #3530 is resolved, implement named colors. +} + +// pad hex output to requested bit width +function pad(n: number, bits: number): string { + const s = n.toString(16); + const s2 = s.length < 2 ? '0' + s : s; + switch (bits) { + case 4: + return s[0]; + case 8: + return s2; + case 12: + return (s2 + s2).slice(0, 3); + default: + return s2 + s2; + } +} + +/** + * Convert a given color to rgb:../../.. string of `bits` depth. + */ +export function toRgbString(color: [number, number, number], bits: number = 16): string { + const [r, g, b] = color; + return `rgb:${pad(r, bits)}/${pad(g, bits)}/${pad(b, bits)}`; +} From 064f6837819a9894b161bf79630f6c2aaaae01a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 8 Nov 2021 17:23:34 +0100 Subject: [PATCH 24/58] make linter happy --- src/common/InputHandler.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index cc963809..e17b23fd 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -1936,7 +1936,7 @@ describe('InputHandler', () => { await inputHandler.parseP('\x1b]10;rgb:aa/bb/cc;#001122\x07'); assert.deepEqual(stack, [ [{ index: ColorIndex.FOREGROUND, color: [170, 187, 204] }], - [{ index: ColorIndex.BACKGROUND, color: [0, 17, 34] }], + [{ index: ColorIndex.BACKGROUND, color: [0, 17, 34] }] ]); }); it('11: should create appropriate events', async () => { From 56f0e69e1f63b875b8c94fb9a4c66fd5205ea3ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 8 Nov 2021 18:36:11 +0100 Subject: [PATCH 25/58] api tests for OSC 10 & 11 --- test/api/InputHandler.api.ts | 46 +++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/test/api/InputHandler.api.ts b/test/api/InputHandler.api.ts index 54ee6957..f236c6cb 100644 --- a/test/api/InputHandler.api.ts +++ b/test/api/InputHandler.api.ts @@ -4,7 +4,7 @@ */ import { assert } from 'chai'; -import { pollFor, openTerminal, getBrowserType, launchBrowser } from './TestUtils'; +import { pollFor, openTerminal, getBrowserType, launchBrowser, writeSync } from './TestUtils'; import { Browser, Page } from 'playwright'; import { IRenderDimensions } from 'browser/renderer/Types'; @@ -386,6 +386,50 @@ describe('InputHandler Integration Tests', function(): void { }); }); + describe('OSC', () => { + describe('OSC 10 & 11', () => { + before(async () => { + await page.evaluate('(() => {window._recordedData = []; window._h = term.onData(d => window._recordedData.push(d));})()'); + }); + after(async () => { + await page.evaluate('window._h.dispose()'); + }); + beforeEach(async () => { + await page.evaluate('window._recordedData.length = 0;'); + }); + it('query FG color', async () => { + await writeSync(page, '\x1b]10;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]10;rgb:ffff/ffff/ffff\x07']); + }); + it('query BG color', async () => { + await writeSync(page, '\x1b]11;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]11;rgb:0000/0000/0000\x07']); + }); + it('query FG & BG color in one call', async () => { + await writeSync(page, '\x1b]10;?;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]10;rgb:ffff/ffff/ffff\x07', '\x1b]11;rgb:0000/0000/0000\x07']); + }); + it('set & query FG', async () => { + await writeSync(page, '\x1b]10;rgb:1/2/3\x07\x1b]10;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]10;rgb:1111/2222/3333\x07']); + await writeSync(page, '\x1b]10;#ffffff\x07\x1b]10;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]10;rgb:1111/2222/3333\x07', '\x1b]10;rgb:ffff/ffff/ffff\x07']); + }); + it('set & query BG', async () => { + await writeSync(page, '\x1b]11;rgb:1/2/3\x07\x1b]11;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]11;rgb:1111/2222/3333\x07']); + await writeSync(page, '\x1b]11;#000000\x07\x1b]11;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]11;rgb:1111/2222/3333\x07', '\x1b]11;rgb:0000/0000/0000\x07']); + }); + it('set & query FG & BG color in one call', async () => { + await writeSync(page, '\x1b]10;#123456;rgb:aa/bb/cc\x07\x1b]10;?;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]10;rgb:1212/3434/5656\x07', '\x1b]11;rgb:aaaa/bbbb/cccc\x07']); + await writeSync(page, '\x1b]10;#ffffff;#000000\x07'); + }); + }); + + }); + describe('ESC', () => { describe('DECRC: Save cursor, ESC 7', () => { it('should save the absolute cursor position so resizing restores to the correct position', async () => { From b55ee772b4dbd7dea192be00c136ed04fc58f7e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 8 Nov 2021 19:01:30 +0100 Subject: [PATCH 26/58] fix inputhandler type definition --- src/common/InputHandler.ts | 4 +- src/common/Types.d.ts | 126 +++++++++++++++++++------------------ 2 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index a8d15db1..168990bc 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -399,7 +399,7 @@ export class InputHandler extends Disposable implements IInputHandler { this._parser.registerOscHandler(2, new OscHandler(data => this.setTitle(data))); // 3 - set property X in the form "prop=value" // 4 - Change Color Number - this._parser.registerOscHandler(4, new OscHandler(data => this.setAnsiColor(data))); + this._parser.registerOscHandler(4, new OscHandler(data => this.setOrReportIndexedColor(data))); // 5 - Change Special Color Number // 6 - Enable/disable Special Color Number c // 7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939) @@ -2867,7 +2867,7 @@ export class InputHandler extends Disposable implements IInputHandler { * `c` is the color index between 0 and 255. `spec` color format is 'rgb:hh/hh/hh' where `h` are hexadecimal digits. * There may be multipe c ; spec elements present in the same instruction, e.g. 1;rgb:10/20/30;2;rgb:a0/b0/c0. */ - public setAnsiColor(data: string): boolean { + public setOrReportIndexedColor(data: string): boolean { const event = this._parseAnsiColorChange(data); if (event.length) { this._onColor.fire(event); diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index b38a0643..741f8b7c 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -376,80 +376,84 @@ export interface IInputHandler { registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable; registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable; - /** C0 BEL */ bell(): void; - /** C0 LF */ lineFeed(): void; - /** C0 CR */ carriageReturn(): void; - /** C0 BS */ backspace(): void; - /** C0 HT */ tab(): void; - /** C0 SO */ shiftOut(): void; - /** C0 SI */ shiftIn(): void; + /** C0 BEL */ bell(): boolean; + /** C0 LF */ lineFeed(): boolean; + /** C0 CR */ carriageReturn(): boolean; + /** C0 BS */ backspace(): boolean; + /** C0 HT */ tab(): boolean; + /** C0 SO */ shiftOut(): boolean; + /** C0 SI */ shiftIn(): boolean; + + /** CSI @ */ insertChars(params: IParams): boolean; + /** CSI SP @ */ scrollLeft(params: IParams): boolean; + /** CSI A */ cursorUp(params: IParams): boolean; + /** CSI SP A */ scrollRight(params: IParams): boolean; + /** CSI B */ cursorDown(params: IParams): boolean; + /** CSI C */ cursorForward(params: IParams): boolean; + /** CSI D */ cursorBackward(params: IParams): boolean; + /** CSI E */ cursorNextLine(params: IParams): boolean; + /** CSI F */ cursorPrecedingLine(params: IParams): boolean; + /** CSI G */ cursorCharAbsolute(params: IParams): boolean; + /** CSI H */ cursorPosition(params: IParams): boolean; + /** CSI I */ cursorForwardTab(params: IParams): boolean; + /** CSI J */ eraseInDisplay(params: IParams): boolean; + /** CSI K */ eraseInLine(params: IParams): boolean; + /** CSI L */ insertLines(params: IParams): boolean; + /** CSI M */ deleteLines(params: IParams): boolean; + /** CSI P */ deleteChars(params: IParams): boolean; + /** CSI S */ scrollUp(params: IParams): boolean; + /** CSI T */ scrollDown(params: IParams, collect?: string): boolean; + /** CSI X */ eraseChars(params: IParams): boolean; + /** CSI Z */ cursorBackwardTab(params: IParams): boolean; + /** CSI ` */ charPosAbsolute(params: IParams): boolean; + /** CSI a */ hPositionRelative(params: IParams): boolean; + /** CSI b */ repeatPrecedingCharacter(params: IParams): boolean; + /** CSI c */ sendDeviceAttributesPrimary(params: IParams): boolean; + /** CSI > c */ sendDeviceAttributesSecondary(params: IParams): boolean; + /** CSI d */ linePosAbsolute(params: IParams): boolean; + /** CSI e */ vPositionRelative(params: IParams): boolean; + /** CSI f */ hVPosition(params: IParams): boolean; + /** CSI g */ tabClear(params: IParams): boolean; + /** CSI h */ setMode(params: IParams, collect?: string): boolean; + /** CSI l */ resetMode(params: IParams, collect?: string): boolean; + /** CSI m */ charAttributes(params: IParams): boolean; + /** CSI n */ deviceStatus(params: IParams, collect?: string): boolean; + /** CSI p */ softReset(params: IParams, collect?: string): boolean; + /** CSI q */ setCursorStyle(params: IParams, collect?: string): boolean; + /** CSI r */ setScrollRegion(params: IParams, collect?: string): boolean; + /** CSI s */ saveCursor(params: IParams): boolean; + /** CSI u */ restoreCursor(params: IParams): boolean; + /** CSI ' } */ insertColumns(params: IParams): boolean; + /** CSI ' ~ */ deleteColumns(params: IParams): boolean; - /** CSI @ */ insertChars(params: IParams): void; - /** CSI SP @ */ scrollLeft(params: IParams): void; - /** CSI A */ cursorUp(params: IParams): void; - /** CSI SP A */ scrollRight(params: IParams): void; - /** CSI B */ cursorDown(params: IParams): void; - /** CSI C */ cursorForward(params: IParams): void; - /** CSI D */ cursorBackward(params: IParams): void; - /** CSI E */ cursorNextLine(params: IParams): void; - /** CSI F */ cursorPrecedingLine(params: IParams): void; - /** CSI G */ cursorCharAbsolute(params: IParams): void; - /** CSI H */ cursorPosition(params: IParams): void; - /** CSI I */ cursorForwardTab(params: IParams): void; - /** CSI J */ eraseInDisplay(params: IParams): void; - /** CSI K */ eraseInLine(params: IParams): void; - /** CSI L */ insertLines(params: IParams): void; - /** CSI M */ deleteLines(params: IParams): void; - /** CSI P */ deleteChars(params: IParams): void; - /** CSI S */ scrollUp(params: IParams): void; - /** CSI T */ scrollDown(params: IParams, collect?: string): void; - /** CSI X */ eraseChars(params: IParams): void; - /** CSI Z */ cursorBackwardTab(params: IParams): void; - /** CSI ` */ charPosAbsolute(params: IParams): void; - /** CSI a */ hPositionRelative(params: IParams): void; - /** CSI b */ repeatPrecedingCharacter(params: IParams): void; - /** CSI c */ sendDeviceAttributesPrimary(params: IParams): void; - /** CSI > c */ sendDeviceAttributesSecondary(params: IParams): void; - /** CSI d */ linePosAbsolute(params: IParams): void; - /** CSI e */ vPositionRelative(params: IParams): void; - /** CSI f */ hVPosition(params: IParams): void; - /** CSI g */ tabClear(params: IParams): void; - /** CSI h */ setMode(params: IParams, collect?: string): void; - /** CSI l */ resetMode(params: IParams, collect?: string): void; - /** CSI m */ charAttributes(params: IParams): void; - /** CSI n */ deviceStatus(params: IParams, collect?: string): void; - /** CSI p */ softReset(params: IParams, collect?: string): void; - /** CSI q */ setCursorStyle(params: IParams, collect?: string): void; - /** CSI r */ setScrollRegion(params: IParams, collect?: string): void; - /** CSI s */ saveCursor(params: IParams): void; - /** CSI u */ restoreCursor(params: IParams): void; - /** CSI ' } */ insertColumns(params: IParams): void; - /** CSI ' ~ */ deleteColumns(params: IParams): void; /** OSC 0 - OSC 2 */ setTitle(data: string): void; - /** OSC 4 */ setAnsiColor(data: string): void; - /** ESC E */ nextLine(): void; - /** ESC = */ keypadApplicationMode(): void; - /** ESC > */ keypadNumericMode(): void; + OSC 2 */ setTitle(data: string): boolean; + /** OSC 4 */ setOrReportIndexedColor(data: string): boolean; + /** OSC 10 */ setOrReportFgColor(data: string): boolean; + /** OSC 11 */ setOrReportBgColor(data: string): boolean; + + /** ESC E */ nextLine(): boolean; + /** ESC = */ keypadApplicationMode(): boolean; + /** ESC > */ keypadNumericMode(): boolean; /** ESC % G - ESC % @ */ selectDefaultCharset(): void; + ESC % @ */ selectDefaultCharset(): boolean; /** ESC ( C ESC ) C ESC * C ESC + C ESC - C ESC . C - ESC / C */ selectCharset(collectAndFlag: string): void; - /** ESC D */ index(): void; - /** ESC H */ tabSet(): void; - /** ESC M */ reverseIndex(): void; - /** ESC c */ fullReset(): void; + ESC / C */ selectCharset(collectAndFlag: string): boolean; + /** ESC D */ index(): boolean; + /** ESC H */ tabSet(): boolean; + /** ESC M */ reverseIndex(): boolean; + /** ESC c */ fullReset(): boolean; /** ESC n ESC o ESC | ESC } - ESC ~ */ setgLevel(level: number): void; - /** ESC # 8 */ screenAlignmentPattern(): void; + ESC ~ */ setgLevel(level: number): boolean; + /** ESC # 8 */ screenAlignmentPattern(): boolean; } interface IParseStack { From 54822af73ae63eb051668e29fd6b0d4c940359b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 8 Nov 2021 19:40:35 +0100 Subject: [PATCH 27/58] use xcolor parser for OSC 4 --- src/common/InputHandler.test.ts | 82 ++++++++++++++------------------- src/common/InputHandler.ts | 38 +++++++-------- 2 files changed, 51 insertions(+), 69 deletions(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index e17b23fd..d63a9654 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -17,7 +17,7 @@ import { DEFAULT_OPTIONS } from 'common/services/OptionsService'; import { clone } from 'common/Clone'; import { BufferService } from 'common/services/BufferService'; import { CoreService } from 'common/services/CoreService'; -import { OscHandler } from 'common/parser/OscParser'; + function getCursor(bufferService: IBufferService): number[] { return [ @@ -41,7 +41,6 @@ class TestInputHandler extends InputHandler { public get curAttrData(): IAttributeData { return (this as any)._curAttrData; } public get windowTitleStack(): string[] { return this._windowTitleStack; } public get iconNameStack(): string[] { return this._iconNameStack; } - public parseAnsiColorChange(data: string): IColorEvent{ return this._parseAnsiColorChange(data); } /** * Promise based parse call to await the full resolve of given input data. @@ -1865,53 +1864,42 @@ describe('InputHandler', () => { }); }); describe('OSC', () => { - it('4: should parse correct Ansi color change data', () => { - // this is testing a private method - const event = inputHandler.parseAnsiColorChange('19;rgb:a1/b2/c3'); - - assert.isNotNull(event); - assert.deepEqual(event![0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); + it('4: query color events', async () => { + const stack: IColorEvent[] = []; + inputHandler.onColor(ev => stack.push(ev)); + // single color query + await inputHandler.parseP('\x1b]4;0;?\x07'); + assert.deepEqual(stack, [[{ index: 0 }]]); + stack.length = 0; + await inputHandler.parseP('\x1b]4;123;?\x07'); + assert.deepEqual(stack, [[{ index: 123 }]]); + stack.length = 0; + // multiple queries + await inputHandler.parseP('\x1b]4;0;?;123;?\x07'); + assert.deepEqual(stack, [[{ index: 0 }, { index: 123 }]]); + stack.length = 0; }); - it('4: should ignore incorrect Ansi color change data', () => { - // this is testing a private method - assert.equal(inputHandler.parseAnsiColorChange('17;rgb:a/b/c').length, 0); - assert.equal(inputHandler.parseAnsiColorChange('17;rgb:#aabbcc').length, 0); - assert.equal(inputHandler.parseAnsiColorChange('17;rgba:aa/bb/cc').length, 0); - assert.equal(inputHandler.parseAnsiColorChange('rgb:aa/bb/cc').length, 0); + it('4: set color events', async () => { + const stack: IColorEvent[] = []; + inputHandler.onColor(ev => stack.push(ev)); + // single color query + await inputHandler.parseP('\x1b]4;0;rgb:01/02/03\x07'); + assert.deepEqual(stack, [[{ index: 0, color: [1, 2, 3] }]]); + stack.length = 0; + await inputHandler.parseP('\x1b]4;123;#aabbcc\x07'); + assert.deepEqual(stack, [[{ index: 123, color: [170, 187, 204] }]]); + stack.length = 0; + // multiple queries + await inputHandler.parseP('\x1b]4;0;rgb:aa/bb/cc;123;#001122\x07'); + assert.deepEqual(stack, [[{ index: 0, color: [170, 187, 204] }, { index: 123, color: [0, 17, 34] }]]); + stack.length = 0; }); - it('4: should parse a list of Ansi color changes', () => { - // this is testing a private method - const event = inputHandler.parseAnsiColorChange('19;rgb:a1/b2/c3;17;rgb:00/11/22;255;rgb:01/ef/2d'); - - assert.equal(event.length, 3); - assert.deepEqual(event[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); - assert.deepEqual(event[1], { index: 17, color: [0x00, 0x11, 0x22] }); - assert.deepEqual(event[2], { index: 255, color: [0x01, 0xef, 0x2d] }); - }); - it('4: should ignore incorrect colors in a list of Ansi color changes', () => { - // this is testing a private method - const event = inputHandler.parseAnsiColorChange('19;rgb:a1/b2/c3;17;rgb:WR/ON/G;255;rgb:01/ef/2d'); - - assert.equal(event.length, 2); - assert.deepEqual(event[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); - assert.deepEqual(event[1], { index: 255, color: [0x01, 0xef, 0x2d] }); - }); - it('4: should be case insensitive when parsing Ansi color changes', () => { - // this is testing a private method - const event = inputHandler.parseAnsiColorChange('19;rGb:A1/b2/C3'); - - assert.equal(event.length, 1); - assert.deepEqual(event[0], { index: 19, color: [0xa1, 0xb2, 0xc3] }); - }); - it('4: should fire event on Ansi color change', async () => { - return new Promise(async r => { - inputHandler.onColor(e => { - assert.deepEqual(e[0], { index: 17, color: [0x1a, 0x2b, 0x3c] }); - assert.deepEqual(e[1], { index: 12, color: [0x11, 0x22, 0x33] }); - r(); - }); - await inputHandler.parseP('\x1b]4;17;rgb:1a/2b/3c;12;rgb:11/22/33\x1b\\'); - }); + it('4: should ignore invalid values', async () => { + const stack: IColorEvent[] = []; + inputHandler.onColor(ev => stack.push(ev)); + await inputHandler.parseP('\x1b]4;0;rgb:aa/bb/cc;45;rgb:1/22/333;123;#001122\x07'); + assert.deepEqual(stack, [[{ index: 0, color: [170, 187, 204] }, { index: 123, color: [0, 17, 34] }]]); + stack.length = 0; }); it('10: should create appropriate events', async () => { diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 168990bc..00943601 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -2842,24 +2842,6 @@ export class InputHandler extends Disposable implements IInputHandler { return true; } - protected _parseAnsiColorChange(data: string): IColorEvent { - const result: IColorEvent = []; - // example data: 5;rgb:aa/bb/cc - const regex = /(\d+);rgb:([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})/gi; - let match; - while ((match = regex.exec(data)) !== null) { - result.push({ - index: parseInt(match[1]), - color: [ - parseInt(match[2], 16), - parseInt(match[3], 16), - parseInt(match[4], 16) - ] - }); - } - return result; - } - /** * OSC 4; ; ST (set ANSI color to ) * @@ -2868,13 +2850,25 @@ export class InputHandler extends Disposable implements IInputHandler { * There may be multipe c ; spec elements present in the same instruction, e.g. 1;rgb:10/20/30;2;rgb:a0/b0/c0. */ public setOrReportIndexedColor(data: string): boolean { - const event = this._parseAnsiColorChange(data); + const event: IColorEvent = []; + const slots = data.split(';'); + while (slots.length > 1) { + const idx = slots.shift() as string; + const spec = slots.shift() as string; + if (/^\d+$/.exec(idx)) { + if (spec === '?') { + event.push({ index: parseInt(idx) }); + } else { + const color = parseColor(spec); + if (color) { + event.push({ index: parseInt(idx), color }); + } + } + } + } if (event.length) { this._onColor.fire(event); } - else { - this._logService.warn(`Expected format ;rgb:// but got data: ${data}`); - } return true; } From b8097f53a6619e1f46998b50c8ebbc06efefc03e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 8 Nov 2021 20:55:47 +0100 Subject: [PATCH 28/58] OSC 4 integration tests --- test/api/InputHandler.api.ts | 50 +++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/test/api/InputHandler.api.ts b/test/api/InputHandler.api.ts index f236c6cb..b803d05d 100644 --- a/test/api/InputHandler.api.ts +++ b/test/api/InputHandler.api.ts @@ -386,7 +386,55 @@ describe('InputHandler Integration Tests', function(): void { }); }); - describe('OSC', () => { + describe.only('OSC', () => { + describe('OSC 4', () => { + before(async () => { + await page.evaluate('(() => {window._recordedData = []; window._h = term.onData(d => window._recordedData.push(d));})()'); + }); + after(async () => { + await page.evaluate('window._h.dispose()'); + }); + beforeEach(async () => { + await page.evaluate('window._recordedData.length = 0;'); + }); + it('query single color', async () => { + await writeSync(page, '\x1b]4;0;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]4;0;rgb:2e2e/3434/3636\x07']); + await writeSync(page, '\x1b]4;77;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]4;0;rgb:2e2e/3434/3636\x07', '\x1b]4;77;rgb:5f5f/d7d7/5f5f\x07']); + }); + it('query multiple colors', async () => { + await writeSync(page, '\x1b]4;0;?;77;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]4;0;rgb:2e2e/3434/3636\x07', '\x1b]4;77;rgb:5f5f/d7d7/5f5f\x07']); + }); + it('set & query single color', async () => { + await writeSync(page, '\x1b]4;0;?\x07'); + const restore: string[] = await page.evaluate('window._recordedData'); + assert.deepEqual(await page.evaluate('window._recordedData'), restore); + // set new color & query + await writeSync(page, '\x1b]4;0;rgb:01/02/03\x07\x1b]4;0;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), [restore[0], '\x1b]4;0;rgb:0101/0202/0303\x07']); + // restore should set old color + await writeSync(page, restore[0] + '\x1b]4;0;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), [restore[0], '\x1b]4;0;rgb:0101/0202/0303\x07', restore[0]]); + }); + it('query & set colors mixed', async () => { + await writeSync(page, '\x1b]4;0;?;77;?\x07'); + const restore: string[] = await page.evaluate('window._recordedData'); + await page.evaluate('window._recordedData.length = 0;'); + // mixed call - change 0, query 43, change 77 + await writeSync(page, '\x1b]4;0;rgb:01/02/03;43;?;77;#aabbcc\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]4;43;rgb:0000/d7d7/afaf\x07']); + await page.evaluate('window._recordedData.length = 0;'); + // query new values for 0 + 77 + await writeSync(page, '\x1b]4;0;?;77;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]4;0;rgb:0101/0202/0303\x07', '\x1b]4;77;rgb:aaaa/bbbb/cccc\x07']); + await page.evaluate('window._recordedData.length = 0;'); + // restore old values for 0 + 77 + await writeSync(page, restore[0] + restore[1] + '\x1b]4;0;?;77;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), restore); + }); + }); describe('OSC 10 & 11', () => { before(async () => { await page.evaluate('(() => {window._recordedData = []; window._h = term.onData(d => window._recordedData.push(d));})()'); From 855ed636e7566025ee95f7fe06af127822298d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 8 Nov 2021 20:57:22 +0100 Subject: [PATCH 29/58] remove only from tests --- test/api/InputHandler.api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/api/InputHandler.api.ts b/test/api/InputHandler.api.ts index b803d05d..42681a4e 100644 --- a/test/api/InputHandler.api.ts +++ b/test/api/InputHandler.api.ts @@ -386,7 +386,7 @@ describe('InputHandler Integration Tests', function(): void { }); }); - describe.only('OSC', () => { + describe('OSC', () => { describe('OSC 4', () => { before(async () => { await page.evaluate('(() => {window._recordedData = []; window._h = term.onData(d => window._recordedData.push(d));})()'); From 896f5a7e4cc472600d3234a0072be1925e3f7819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Tue, 9 Nov 2021 13:46:54 +0100 Subject: [PATCH 30/58] extend logic to OSC 12 cursor color --- src/browser/Color.ts | 7 --- src/browser/Terminal.ts | 37 +++++++++++---- src/common/InputHandler.test.ts | 46 +++++++++++++++---- src/common/InputHandler.ts | 81 +++++++++++++++++++-------------- src/common/Types.d.ts | 6 ++- test/api/InputHandler.api.ts | 6 +++ 6 files changed, 123 insertions(+), 60 deletions(-) diff --git a/src/browser/Color.ts b/src/browser/Color.ts index 6a9dff94..a4e415af 100644 --- a/src/browser/Color.ts +++ b/src/browser/Color.ts @@ -217,13 +217,6 @@ export namespace rgba { rgba: channels.toRgba(r, g, b) }; } - - /** - * convert 0xRRGGBBAA to 0xAABBGGRR (32-bit representation on LE systems) - */ - export function toABGR32(rgba: number): number { - return ((rgba & 0xFF) << 24 | (rgba >>> 8 & 0xFF) << 16 | (rgba >>> 16 & 0xFF) << 8 | rgba >>> 24 & 0xFF) >>> 0; - } } export function toPaddedHex(c: number): string { diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 0602f604..9e0d7f54 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -178,23 +178,44 @@ export class Terminal extends CoreTerminal implements ITerminal { this.register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows))); } + /** + * Handle color event from inputhandler for OSC 4 | 10 | 11 | 12. + * An event from OSC 4 may contain multiple set or report requests, + * while OSC 10 | 11 | 12 create single requests. + */ private _handleColorEvent(event: IColorEvent): void { if (!this._colorManager) return; for (const req of event) { + let acc: 'foreground' | 'background' | 'cursor' | 'ansi' | undefined = undefined; + let ident = ''; switch (req.index) { case ColorIndex.FOREGROUND: // OSC 10 - if (req.color) this._colorManager.colors.foreground = rgba.toColor(...req.color); - else this.coreService.triggerDataEvent(`${C0.ESC}]10;${toRgbString(color.toColorRGB(this._colorManager.colors.foreground))}${C0.BEL}`); + acc = 'foreground'; + ident = '10'; break; case ColorIndex.BACKGROUND: // OSC 11 - if (req.color) this._colorManager.colors.background = rgba.toColor(...req.color); - else this.coreService.triggerDataEvent(`${C0.ESC}]11;${toRgbString(color.toColorRGB(this._colorManager.colors.background))}${C0.BEL}`); + acc = 'background'; + ident = '11'; + break; + case ColorIndex.CURSOR: // OSC 12 + acc = 'cursor'; + ident = '12'; break; default: // OSC 4 - if (0 <= req.index && req.index < 256) { - if (req.color) this._colorManager.colors.ansi[req.index] = rgba.toColor(...req.color); - else this.coreService.triggerDataEvent(`${C0.ESC}]4;${req.index};${toRgbString(color.toColorRGB(this._colorManager.colors.ansi[req.index]))}${C0.BEL}`); - } + // we can skip the [0..255] range check here (already done in inputhandler) + acc = 'ansi'; + ident = '4;' + req.index; + } + if (acc) { + if (req.color) { + if (acc === 'ansi') this._colorManager.colors.ansi[req.index] = rgba.toColor(...req.color); + else this._colorManager.colors[acc] = rgba.toColor(...req.color); + } else { + const channels = color.toColorRGB(acc === 'ansi' + ? this._colorManager.colors.ansi[req.index] + : this._colorManager.colors[acc]); + this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(channels)}${C0.BEL}`); + } } } this._renderService?.setColors(this._colorManager.colors); diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index d63a9654..fe48cafc 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -1902,16 +1902,16 @@ describe('InputHandler', () => { stack.length = 0; }); - it('10: should create appropriate events', async () => { + it('10: FG set & query events', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); // single foreground query --> color undefined await inputHandler.parseP('\x1b]10;?\x07'); assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND }]]); stack.length = 0; - // OSC with multiple values maps to OSC 10 & OSC 11 + // OSC with multiple values maps to OSC 10 & OSC 11 & OSC 12 await inputHandler.parseP('\x1b]10;?;?;?;?\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND }], [{ index: ColorIndex.BACKGROUND }]]); + assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND }], [{ index: ColorIndex.BACKGROUND }], [{ index: ColorIndex.CURSOR }]]); stack.length = 0; // set foreground color events await inputHandler.parseP('\x1b]10;rgb:01/02/03\x07'); @@ -1920,23 +1920,24 @@ describe('InputHandler', () => { await inputHandler.parseP('\x1b]10;#aabbcc\x07'); assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND, color: [170, 187, 204] }]]); stack.length = 0; - // set FG and BG at once - await inputHandler.parseP('\x1b]10;rgb:aa/bb/cc;#001122\x07'); + // set FG, BG and cursor color at once + await inputHandler.parseP('\x1b]10;rgb:aa/bb/cc;#001122;rgb:12/34/56\x07'); assert.deepEqual(stack, [ [{ index: ColorIndex.FOREGROUND, color: [170, 187, 204] }], - [{ index: ColorIndex.BACKGROUND, color: [0, 17, 34] }] + [{ index: ColorIndex.BACKGROUND, color: [0, 17, 34] }], + [{ index: ColorIndex.CURSOR, color: [18, 52, 86] }] ]); }); - it('11: should create appropriate events', async () => { + it('11: BG set & query events', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); - // single foreground query --> color undefined + // single background query --> color undefined await inputHandler.parseP('\x1b]11;?\x07'); assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND }]]); stack.length = 0; - // OSC 11 with multiple values creates only one BG event + // OSC 11 with multiple values creates only BG and cursor event await inputHandler.parseP('\x1b]11;?;?;?;?\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND }]]); + assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND }], [{ index: ColorIndex.CURSOR }]]); stack.length = 0; // set background color events await inputHandler.parseP('\x1b]11;rgb:01/02/03\x07'); @@ -1944,6 +1945,31 @@ describe('InputHandler', () => { stack.length = 0; await inputHandler.parseP('\x1b]11;#aabbcc\x07'); assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND, color: [170, 187, 204] }]]); + stack.length = 0; + // set BG and cursor color at once + await inputHandler.parseP('\x1b]11;#001122;rgb:12/34/56\x07'); + assert.deepEqual(stack, [ + [{ index: ColorIndex.BACKGROUND, color: [0, 17, 34] }], + [{ index: ColorIndex.CURSOR, color: [18, 52, 86] }] + ]); + }); + it('12: cursor color set & query events', async () => { + const stack: IColorEvent[] = []; + inputHandler.onColor(ev => stack.push(ev)); + // single cursor query --> color undefined + await inputHandler.parseP('\x1b]12;?\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.CURSOR }]]); + stack.length = 0; + // OSC 12 with multiple values creates only cursor event + await inputHandler.parseP('\x1b]12;?;?;?;?\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.CURSOR }]]); + stack.length = 0; + // set cursor color events + await inputHandler.parseP('\x1b]12;rgb:01/02/03\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.CURSOR, color: [1, 2, 3] }]]); + stack.length = 0; + await inputHandler.parseP('\x1b]12;#aabbcc\x07'); + assert.deepEqual(stack, [[{ index: ColorIndex.CURSOR, color: [170, 187, 204] }]]); }); }); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 00943601..5377bc03 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -408,6 +408,7 @@ export class InputHandler extends Disposable implements IInputHandler { // 11 - Change VT100 text background color to Pt. this._parser.registerOscHandler(11, new OscHandler(data => this.setOrReportBgColor(data))); // 12 - Change text cursor color to Pt. + this._parser.registerOscHandler(12, new OscHandler(data => this.setOrReportCursorColor(data))); // 13 - Change mouse foreground color to Pt. // 14 - Change mouse background color to Pt. // 15 - Change Tektronix foreground color to Pt. @@ -2846,8 +2847,9 @@ export class InputHandler extends Disposable implements IInputHandler { * OSC 4; ; ST (set ANSI color to ) * * @vt: #Y OSC 4 "Set ANSI color" "OSC 4 ; c ; spec BEL" "Change color number `c` to the color specified by `spec`." - * `c` is the color index between 0 and 255. `spec` color format is 'rgb:hh/hh/hh' where `h` are hexadecimal digits. - * There may be multipe c ; spec elements present in the same instruction, e.g. 1;rgb:10/20/30;2;rgb:a0/b0/c0. + * `c` is the color index between 0 and 255. The color format of `spec` is derived from `XParseColor` (see OSC 10 for supported formats). + * There may be multipe `c ; spec` pairs present in the same instruction. + * If `spec` contains `?` the terminal returns a sequence with the currently set color. */ public setOrReportIndexedColor(data: string): boolean { const event: IColorEvent = []; @@ -2856,12 +2858,15 @@ export class InputHandler extends Disposable implements IInputHandler { const idx = slots.shift() as string; const spec = slots.shift() as string; if (/^\d+$/.exec(idx)) { - if (spec === '?') { - event.push({ index: parseInt(idx) }); - } else { - const color = parseColor(spec); - if (color) { - event.push({ index: parseInt(idx), color }); + const index = parseInt(idx); + if (0 <= index && index < 256) { + if (spec === '?') { + event.push({ index }); + } else { + const color = parseColor(spec); + if (color) { + event.push({ index, color }); + } } } } @@ -2872,6 +2877,30 @@ export class InputHandler extends Disposable implements IInputHandler { return true; } + // special colors - OSC 10 | 11 | 12 + private _specialColors = [ColorIndex.FOREGROUND, ColorIndex.BACKGROUND, ColorIndex.CURSOR]; + + /** + * Apply colors requests for special colors in OSC 10 | 11 | 12. + * Since these commands are stacking from multiple parameters, + * we handle them in a loop with an entry offset to `_specialColors`. + */ + private _setOrReportSpecialColor(data: string, offset: number): boolean { + const slots = data.split(';'); + for (let i = 0; i < slots.length; ++i, ++offset) { + if (offset >= this._specialColors.length) break; + if (slots[i] === '?') { + this._onColor.fire([{ index: this._specialColors[offset] }]); + } else { + const color = parseColor(slots[i]); + if (color) { + this._onColor.fire([{ index: this._specialColors[offset], color }]); + } + } + } + return true; + } + /** * OSC 10 ; | ST - set or query default foreground color * @@ -2895,21 +2924,7 @@ export class InputHandler extends Disposable implements IInputHandler { * Therefore stacking multiple `Pt` separated by `;` only works for the first two entries. */ public setOrReportFgColor(data: string): boolean { - // Note: data may contain multiple values separated with ; mapping to OSC 10 - 19 - const slots = data.split(';'); - if (slots[0] === '?') { - this._onColor.fire([{ index: ColorIndex.FOREGROUND }]); - } else { - const color = parseColor(slots[0]); - if (color) { - this._onColor.fire([{ index: ColorIndex.FOREGROUND, color }]); - } - } - // forward second slot to OSC 11 (higher slots are not supported) - if (slots.length > 1) { - this.setOrReportBgColor(slots[1]); - } - return true; + return this._setOrReportSpecialColor(data, 0); } /** @@ -2918,16 +2933,16 @@ export class InputHandler extends Disposable implements IInputHandler { * @vt: #Y OSC 11 "Set or query default background color" "OSC 11 ; Pt BEL" "Same as OSC 10, but for default background." */ public setOrReportBgColor(data: string): boolean { - const slots = data.split(';'); - if (slots[0] === '?') { - this._onColor.fire([{ index: ColorIndex.BACKGROUND }]); - } else { - const color = parseColor(slots[0]); - if (color) { - this._onColor.fire([{ index: ColorIndex.BACKGROUND, color }]); - } - } - return true; + return this._setOrReportSpecialColor(data, 1); + } + + /** + * OSC 12 ; | ST - set or query default cursor color + * + * @vt: #Y OSC 12 "Set or query default cursor color" "OSC 12 ; Pt BEL" "Same as OSC 10, but for default cursor color." + */ + public setOrReportCursorColor(data: string): boolean { + return this._setOrReportSpecialColor(data, 2); } /** diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index 741f8b7c..7e1778a9 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -348,10 +348,11 @@ export interface IWindowOptions { setWinLines?: boolean; } -// color events from common, used for OSC 4/10/11 +// color events from common, used for OSC 4/10/11/12 export const enum ColorIndex { FOREGROUND = 256, - BACKGROUND = 257 + BACKGROUND = 257, + CURSOR = 258 } export interface IColorReportRequest { index: ColorIndex; @@ -431,6 +432,7 @@ export interface IInputHandler { /** OSC 4 */ setOrReportIndexedColor(data: string): boolean; /** OSC 10 */ setOrReportFgColor(data: string): boolean; /** OSC 11 */ setOrReportBgColor(data: string): boolean; + /** OSC 12 */ setOrReportCursorColor(data: string): boolean; /** ESC E */ nextLine(): boolean; /** ESC = */ keypadApplicationMode(): boolean; diff --git a/test/api/InputHandler.api.ts b/test/api/InputHandler.api.ts index 42681a4e..fc8aadab 100644 --- a/test/api/InputHandler.api.ts +++ b/test/api/InputHandler.api.ts @@ -469,6 +469,12 @@ describe('InputHandler Integration Tests', function(): void { await writeSync(page, '\x1b]11;#000000\x07\x1b]11;?\x07'); assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]11;rgb:1111/2222/3333\x07', '\x1b]11;rgb:0000/0000/0000\x07']); }); + it('set & query cursor color', async () => { + await writeSync(page, '\x1b]12;rgb:1/2/3\x07\x1b]12;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]12;rgb:1111/2222/3333\x07']); + await writeSync(page, '\x1b]12;#ffffff\x07\x1b]12;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]12;rgb:1111/2222/3333\x07', '\x1b]12;rgb:ffff/ffff/ffff\x07']); + }); it('set & query FG & BG color in one call', async () => { await writeSync(page, '\x1b]10;#123456;rgb:aa/bb/cc\x07\x1b]10;?;?\x07'); assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]10;rgb:1212/3434/5656\x07', '\x1b]11;rgb:aaaa/bbbb/cccc\x07']); From d54c40a3edb97fc57ec144fc65eb5b87760eefad Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 9 Nov 2021 06:46:00 -0800 Subject: [PATCH 31/58] Allow shift+wheel to bubble up the DOM Fixes #3550 --- src/browser/Terminal.ts | 2 +- src/browser/Viewport.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 24dc7af9..23122f3f 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -820,7 +820,7 @@ export class Terminal extends CoreTerminal implements ITerminal { // normal viewport scrolling // conditionally stop event, if the viewport still had rows to scroll within - if (!this.viewport!.onWheel(ev)) { + if (this.viewport!.onWheel(ev)) { return this.cancel(ev); } }, { passive: false })); diff --git a/src/browser/Viewport.ts b/src/browser/Viewport.ts index f73594bf..1dfc9e3e 100644 --- a/src/browser/Viewport.ts +++ b/src/browser/Viewport.ts @@ -220,7 +220,7 @@ export class Viewport extends Disposable implements IViewport { private _getPixelsScrolled(ev: WheelEvent): number { // Do nothing if it's not a vertical scroll event - if (ev.deltaY === 0) { + if (ev.deltaY === 0 || ev.shiftKey) { return 0; } @@ -241,7 +241,7 @@ export class Viewport extends Disposable implements IViewport { */ public getLinesScrolled(ev: WheelEvent): number { // Do nothing if it's not a vertical scroll event - if (ev.deltaY === 0) { + if (ev.deltaY === 0 || ev.shiftKey) { return 0; } From b1c179461d612e0ef5e2c35395218ad8d28231cc Mon Sep 17 00:00:00 2001 From: silamon <32477463+silamon@users.noreply.github.com> Date: Wed, 10 Nov 2021 09:15:43 +0100 Subject: [PATCH 32/58] Update typings/xterm.d.ts Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- typings/xterm.d.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 39f2bfb0..234b7ea0 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -636,7 +636,26 @@ declare module 'xterm' { readonly modes: IModes; /** - * Get the terminal options + * Gets or sets the terminal options. This supports setting multiple options. + * + * @example Get a single option + * ```typescript + * console.log(terminal.options.fontSize); + * ``` + * + * @example Set a single option + * ```typescript + * terminal.options.fontSize = 12; + * ``` + * + * @example Set multiple options + * ```typescript + * terminal.options = { + * fontSize: 12, + * fontFamily: 'Arial', + * ; + * ``` + */ */ options: ITerminalOptions; From 2c65d9686376fa9cdc901d045c3ca9daa0c6ada3 Mon Sep 17 00:00:00 2001 From: Simon Lamon Date: Wed, 10 Nov 2021 08:39:28 +0000 Subject: [PATCH 33/58] Fix tests --- src/browser/Terminal.ts | 10 +++++++++- src/common/CoreTerminal.ts | 4 ++-- typings/xterm.d.ts | 3 +-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index b0506850..5336382d 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -39,7 +39,7 @@ import { MouseZoneManager } from 'browser/MouseZoneManager'; import { AccessibilityManager } from './AccessibilityManager'; import { ITheme, IMarker, IDisposable, ISelectionPosition, ILinkProvider } from 'xterm'; import { DomRenderer } from 'browser/renderer/dom/DomRenderer'; -import { IKeyboardEvent, KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IAnsiColorChangeEvent } from 'common/Types'; +import { IKeyboardEvent, KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ScrollSource, IAnsiColorChangeEvent } from 'common/Types'; import { evaluateKeyboardEvent } from 'common/input/Keyboard'; import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; @@ -54,6 +54,7 @@ import { CoreBrowserService } from 'browser/services/CoreBrowserService'; import { CoreTerminal } from 'common/CoreTerminal'; import { rgba } from 'browser/Color'; import { CharacterJoinerService } from 'browser/services/CharacterJoinerService'; +import { ITerminalOptions } from 'common/services/Services'; // Let it work inside Node.js for automated testing purposes. const document: Document = (typeof window !== 'undefined') ? window.document : null as any; @@ -73,6 +74,13 @@ export class Terminal extends CoreTerminal implements ITerminal { public browser: IBrowser = Browser as any; + public get options(): ITerminalOptions { return this.optionsService.options; } + public set options(options: ITerminalOptions) { + for (const key in options) { + this.optionsService.options[key] = options[key]; + } + } + private _customKeyEventHandler: CustomKeyEventHandler | undefined; // browser services diff --git a/src/common/CoreTerminal.ts b/src/common/CoreTerminal.ts index 6ef9011a..ab1d6c24 100644 --- a/src/common/CoreTerminal.ts +++ b/src/common/CoreTerminal.ts @@ -22,12 +22,12 @@ */ import { Disposable } from 'common/Lifecycle'; -import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, ICoreMouseService, IUnicodeService, IDirtyRowService, LogLevelEnum, ITerminalOptions } from 'common/services/Services'; +import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, ICoreMouseService, IUnicodeService, IDirtyRowService, LogLevelEnum } from 'common/services/Services'; import { InstantiationService } from 'common/services/InstantiationService'; import { LogService } from 'common/services/LogService'; import { BufferService, MINIMUM_COLS, MINIMUM_ROWS } from 'common/services/BufferService'; import { OptionsService } from 'common/services/OptionsService'; -import { IDisposable, IBufferLine, IAttributeData, ICoreTerminal, IKeyboardEvent, IScrollEvent, ScrollSource } from 'common/Types'; +import { IDisposable, IBufferLine, IAttributeData, ICoreTerminal, IKeyboardEvent, IScrollEvent, ScrollSource, ITerminalOptions } from 'common/Types'; import { CoreService } from 'common/services/CoreService'; import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter'; import { CoreMouseService } from 'common/services/CoreMouseService'; diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 234b7ea0..2a274a24 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -653,10 +653,9 @@ declare module 'xterm' { * terminal.options = { * fontSize: 12, * fontFamily: 'Arial', - * ; + * }; * ``` */ - */ options: ITerminalOptions; /** From 317641c3bb4bd6ebe2ff2a345920be1bdda983cc Mon Sep 17 00:00:00 2001 From: Simon Lamon Date: Wed, 10 Nov 2021 09:42:45 +0000 Subject: [PATCH 34/58] Add some tests --- src/browser/Terminal.test.ts | 18 +++++++++++- src/browser/Terminal.ts | 7 ----- src/browser/TestUtils.test.ts | 1 + src/browser/Types.d.ts | 1 + src/browser/public/Terminal.test.ts | 43 +++++++++++++++++++++++++++++ src/browser/public/Terminal.ts | 4 +-- src/common/CoreTerminal.ts | 14 +++++++--- 7 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 src/browser/public/Terminal.test.ts diff --git a/src/browser/Terminal.test.ts b/src/browser/Terminal.test.ts index a102d93f..872bfdc7 100644 --- a/src/browser/Terminal.test.ts +++ b/src/browser/Terminal.test.ts @@ -11,7 +11,7 @@ import { IBufferService, IUnicodeService } from 'common/services/Services'; import { Linkifier } from 'browser/Linkifier'; import { MockLogService, MockUnicodeService } from 'common/TestUtils.test'; import { IRegisteredLinkMatcher, IMouseZoneManager, IMouseZone } from 'browser/Types'; -import { IMarker } from 'common/Types'; +import { IMarker, ITerminalOptions } from 'common/Types'; const INIT_COLS = 80; const INIT_ROWS = 24; @@ -1501,6 +1501,22 @@ describe('Terminal', () => { assert.deepEqual(markers.map(el => el.line), [-1, -1, 0, 1, 2]); }); }); + + describe('options', () => { + beforeEach(async () => { + term = new TestTerminal({}); + }); + it('get options', () => { + assert.equal(term.options.cols, 80); + assert.equal(term.options.rows, 24); + }); + it('set options', async () => { + term.options.cols = 40; + assert.equal(term.options.cols, 40); + term.options.rows = 20; + assert.equal(term.options.rows, 20); + }); + }); }); class TestLinkifier extends Linkifier { diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 5336382d..523b50d2 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -74,13 +74,6 @@ export class Terminal extends CoreTerminal implements ITerminal { public browser: IBrowser = Browser as any; - public get options(): ITerminalOptions { return this.optionsService.options; } - public set options(options: ITerminalOptions) { - for (const key in options) { - this.optionsService.options[key] = options[key]; - } - } - private _customKeyEventHandler: CustomKeyEventHandler | undefined; // browser services diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index 8fdf458e..268630c7 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -147,6 +147,7 @@ export class MockTerminal implements ITerminal { public linkifier2!: ILinkifier2; public isFocused!: boolean; public options: ITerminalOptions = {}; + public publicOptions: ITerminalOptions = {}; public element!: HTMLElement; public screenElement!: HTMLElement; public rowContainer!: HTMLElement; diff --git a/src/browser/Types.d.ts b/src/browser/Types.d.ts index a6165840..5540690d 100644 --- a/src/browser/Types.d.ts +++ b/src/browser/Types.d.ts @@ -16,6 +16,7 @@ export interface ITerminal extends IPublicTerminal, ICoreTerminal { browser: IBrowser; buffer: IBuffer; viewport: IViewport | undefined; + publicOptions: ITerminalOptions; options: ITerminalOptions; linkifier: ILinkifier; linkifier2: ILinkifier2; diff --git a/src/browser/public/Terminal.test.ts b/src/browser/public/Terminal.test.ts new file mode 100644 index 00000000..f03945a0 --- /dev/null +++ b/src/browser/public/Terminal.test.ts @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { Terminal } from 'browser/public/Terminal'; +import { assert } from 'chai'; +import { ITerminalOptions } from 'common/Types'; + +const INIT_COLS = 80; +const INIT_ROWS = 24; + +describe('Public Terminal', () => { + let term: Terminal; + const termOptions = { + cols: INIT_COLS, + rows: INIT_ROWS + }; + + describe('options', () => { + beforeEach(async () => { + term = new Terminal(termOptions); + }); + it('get options', () => { + const options: ITerminalOptions = term.options; + assert.equal(options.cols, 80); + assert.equal(options.rows, 24); + }); + it('set options', async () => { + const options: ITerminalOptions = term.options; + assert.throws(() => options.cols = 40); + assert.throws(() => options.rows = 20); + term.options.scrollback = 1; + assert.equal(term.options.scrollback, 1); + term.options= { + fontSize: 12, + fontFamily: 'Arial' + }; + assert.equal(term.options.fontSize, 12); + assert.equal(term.options.fontFamily, 'Arial'); + }); + }); +}); diff --git a/src/browser/public/Terminal.ts b/src/browser/public/Terminal.ts index a5536855..2138f116 100644 --- a/src/browser/public/Terminal.ts +++ b/src/browser/public/Terminal.ts @@ -90,10 +90,10 @@ export class Terminal implements ITerminalApi { }; } public get options(): ITerminalOptions { - return this._core.options; + return this._core.publicOptions; } public set options(options: ITerminalOptions) { - this._core.options = options; + this._core.publicOptions = options; } public blur(): void { this._core.blur(); diff --git a/src/common/CoreTerminal.ts b/src/common/CoreTerminal.ts index ab1d6c24..4223e780 100644 --- a/src/common/CoreTerminal.ts +++ b/src/common/CoreTerminal.ts @@ -22,12 +22,12 @@ */ import { Disposable } from 'common/Lifecycle'; -import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, ICoreMouseService, IUnicodeService, IDirtyRowService, LogLevelEnum } from 'common/services/Services'; +import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, ICoreMouseService, IUnicodeService, IDirtyRowService, LogLevelEnum, ITerminalOptions } from 'common/services/Services'; import { InstantiationService } from 'common/services/InstantiationService'; import { LogService } from 'common/services/LogService'; import { BufferService, MINIMUM_COLS, MINIMUM_ROWS } from 'common/services/BufferService'; import { OptionsService } from 'common/services/OptionsService'; -import { IDisposable, IBufferLine, IAttributeData, ICoreTerminal, IKeyboardEvent, IScrollEvent, ScrollSource, ITerminalOptions } from 'common/Types'; +import { IDisposable, IBufferLine, IAttributeData, ICoreTerminal, IKeyboardEvent, IScrollEvent, ScrollSource, ITerminalOptions as IPublicTerminalOptions } from 'common/Types'; import { CoreService } from 'common/services/CoreService'; import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter'; import { CoreMouseService } from 'common/services/CoreMouseService'; @@ -86,12 +86,18 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal { public get cols(): number { return this._bufferService.cols; } public get rows(): number { return this._bufferService.rows; } public get buffers(): IBufferSet { return this._bufferService.buffers; } - public get options(): ITerminalOptions { return this.optionsService.publicOptions; } - public set options(options: ITerminalOptions) { + public get publicOptions(): IPublicTerminalOptions { return this.optionsService.publicOptions; } + public set publicOptions(options: IPublicTerminalOptions) { for (const key in options) { this.optionsService.publicOptions[key] = options[key]; } } + public get options(): ITerminalOptions { return this.optionsService.options; } + public set options(options: ITerminalOptions) { + for (const key in options) { + this.optionsService.options[key] = options[key]; + } + } constructor( options: Partial From 4245ce33b59f876a6c7403d0ab84a76c10bc2449 Mon Sep 17 00:00:00 2001 From: Simon Lamon Date: Wed, 10 Nov 2021 10:17:14 +0000 Subject: [PATCH 35/58] Remove publicOptions completely --- src/browser/TestUtils.test.ts | 1 - src/browser/Types.d.ts | 1 - src/browser/public/Terminal.ts | 22 ++++++++++++++++++++-- src/common/CoreTerminal.ts | 6 ------ src/common/TestUtils.test.ts | 3 --- src/common/services/OptionsService.ts | 22 ++++------------------ src/common/services/Services.ts | 1 - 7 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index 268630c7..8fdf458e 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -147,7 +147,6 @@ export class MockTerminal implements ITerminal { public linkifier2!: ILinkifier2; public isFocused!: boolean; public options: ITerminalOptions = {}; - public publicOptions: ITerminalOptions = {}; public element!: HTMLElement; public screenElement!: HTMLElement; public rowContainer!: HTMLElement; diff --git a/src/browser/Types.d.ts b/src/browser/Types.d.ts index 5540690d..a6165840 100644 --- a/src/browser/Types.d.ts +++ b/src/browser/Types.d.ts @@ -16,7 +16,6 @@ export interface ITerminal extends IPublicTerminal, ICoreTerminal { browser: IBrowser; buffer: IBuffer; viewport: IViewport | undefined; - publicOptions: ITerminalOptions; options: ITerminalOptions; linkifier: ILinkifier; linkifier2: ILinkifier2; diff --git a/src/browser/public/Terminal.ts b/src/browser/public/Terminal.ts index 2138f116..059b6402 100644 --- a/src/browser/public/Terminal.ts +++ b/src/browser/public/Terminal.ts @@ -13,6 +13,11 @@ import { UnicodeApi } from 'common/public/UnicodeApi'; import { AddonManager } from 'common/public/AddonManager'; import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi'; +/** + * The set of options that only have an effect when set in the Terminal constructor. + */ +const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows']; + export class Terminal implements ITerminalApi { private _core: ITerminal; private _addonManager: AddonManager; @@ -90,10 +95,11 @@ export class Terminal implements ITerminalApi { }; } public get options(): ITerminalOptions { - return this._core.publicOptions; + return this._core.options; } public set options(options: ITerminalOptions) { - this._core.publicOptions = options; + this._checkReadonlyOptions(options); + this._core.options = options; } public blur(): void { this._core.blur(); @@ -219,6 +225,7 @@ export class Terminal implements ITerminalApi { public setOption(key: 'cols' | 'rows', value: number): void; public setOption(key: string, value: any): void; public setOption(key: any, value: any): void { + this._checkReadonlyOptions(); this._core.optionsService.setOption(key, value); } public refresh(start: number, end: number): void { @@ -245,4 +252,15 @@ export class Terminal implements ITerminalApi { } } } + + private _checkReadonlyOptions(options?: ITerminalOptions): void { + // Throw an error if any constructor only option is modified + // from terminal.options + // Modifications from anywhere else are allowed + for (const propName in options) { + if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) { + throw new Error(`Option "${propName}" can only be set in the constructor`); + } + } + } } diff --git a/src/common/CoreTerminal.ts b/src/common/CoreTerminal.ts index 4223e780..d5378247 100644 --- a/src/common/CoreTerminal.ts +++ b/src/common/CoreTerminal.ts @@ -86,12 +86,6 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal { public get cols(): number { return this._bufferService.cols; } public get rows(): number { return this._bufferService.rows; } public get buffers(): IBufferSet { return this._bufferService.buffers; } - public get publicOptions(): IPublicTerminalOptions { return this.optionsService.publicOptions; } - public set publicOptions(options: IPublicTerminalOptions) { - for (const key in options) { - this.optionsService.publicOptions[key] = options[key]; - } - } public get options(): ITerminalOptions { return this.optionsService.options; } public set options(options: ITerminalOptions) { for (const key in options) { diff --git a/src/common/TestUtils.test.ts b/src/common/TestUtils.test.ts index 00aedff6..67488be0 100644 --- a/src/common/TestUtils.test.ts +++ b/src/common/TestUtils.test.ts @@ -121,20 +121,17 @@ export class MockLogService implements ILogService { export class MockOptionsService implements IOptionsService { public serviceBrand: any; public options: ITerminalOptions = clone(DEFAULT_OPTIONS); - public publicOptions: ITerminalOptions = clone(DEFAULT_OPTIONS); public onOptionChange: IEvent = new EventEmitter().event; constructor(testOptions?: Partial) { if (testOptions) { for (const key of Object.keys(testOptions)) { this.options[key] = testOptions[key]; - this.publicOptions[key] = testOptions[key]; } } } public setOptions(options: ITerminalOptions): void { for (const key of Object.keys(options)) { this.options[key] = options[key]; - this.publicOptions[key] = options[key]; } } public setOption(key: string, value: T): void { diff --git a/src/common/services/OptionsService.ts b/src/common/services/OptionsService.ts index a245c153..65b0703c 100644 --- a/src/common/services/OptionsService.ts +++ b/src/common/services/OptionsService.ts @@ -57,17 +57,11 @@ export const DEFAULT_OPTIONS: Readonly = { const FONT_WEIGHT_OPTIONS: Extract[] = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900']; -/** - * The set of options that only have an effect when set in the Terminal constructor. - */ -const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows']; - export class OptionsService implements IOptionsService { public serviceBrand: any; private _options: ITerminalOptions; public options: ITerminalOptions; - public publicOptions: ITerminalOptions; private _onOptionChange = new EventEmitter(); public get onOptionChange(): IEvent { return this._onOptionChange.event; } @@ -87,11 +81,10 @@ export class OptionsService implements IOptionsService { } // set up getters and setters for each option - this.options = this._setupOptions(this._options, false); - this.publicOptions = this._setupOptions(this._options, true); + this.options = this._setupOptions(this._options); } - private _setupOptions(options: ITerminalOptions, isPublic: boolean): ITerminalOptions { + private _setupOptions(options: ITerminalOptions): ITerminalOptions { const copiedOptions = { ... options }; for (const propName in copiedOptions) { Object.defineProperty(copiedOptions, propName, { @@ -106,13 +99,6 @@ export class OptionsService implements IOptionsService { throw new Error(`No option with key "${propName}"`); } - // Throw an error if any constructor only option is modified - // from terminal.options - // Modifications from anywhere else are allowed - if (isPublic && CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) { - throw new Error(`Option "${propName}" can only be set in the constructor`); - } - value = this._sanitizeAndValidateOption(propName, value); // Don't fire an option change event if they didn't change if (this._options[propName] !== value) { @@ -126,7 +112,7 @@ export class OptionsService implements IOptionsService { } public setOption(key: string, value: any): void { - this.publicOptions[key] = value; + this.options[key] = value; } private _sanitizeAndValidateOption(key: string, value: any): any { @@ -181,6 +167,6 @@ export class OptionsService implements IOptionsService { } public getOption(key: string): any { - return this.publicOptions[key]; + return this.options[key]; } } diff --git a/src/common/services/Services.ts b/src/common/services/Services.ts index ed909723..537ac6db 100644 --- a/src/common/services/Services.ts +++ b/src/common/services/Services.ts @@ -189,7 +189,6 @@ export interface IOptionsService { serviceBrand: undefined; readonly options: ITerminalOptions; - readonly publicOptions: ITerminalOptions; readonly onOptionChange: IEvent; From 71257ec00e00a57ee557eb2087ce788f11915b31 Mon Sep 17 00:00:00 2001 From: Simon Lamon Date: Wed, 10 Nov 2021 10:45:42 +0000 Subject: [PATCH 36/58] Fix tests --- src/browser/public/Terminal.ts | 46 ++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/browser/public/Terminal.ts b/src/browser/public/Terminal.ts index 059b6402..f65d48c1 100644 --- a/src/browser/public/Terminal.ts +++ b/src/browser/public/Terminal.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings, ITerminalAddon, ISelectionPosition, IBufferNamespace as IBufferNamespaceApi, IParser, ILinkProvider, IUnicodeHandling, FontWeight, IModes } from 'xterm'; +import { Terminal as ITerminalApi, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings, ITerminalAddon, ISelectionPosition, IBufferNamespace as IBufferNamespaceApi, IParser, ILinkProvider, IUnicodeHandling, FontWeight, IModes } from 'xterm'; import { ITerminal } from 'browser/Types'; import { Terminal as TerminalCore } from 'browser/Terminal'; import * as Strings from 'browser/LocalizableStrings'; @@ -12,6 +12,7 @@ import { ParserApi } from 'common/public/ParserApi'; import { UnicodeApi } from 'common/public/UnicodeApi'; import { AddonManager } from 'common/public/AddonManager'; import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi'; +import { ITerminalOptions } from 'common/Types'; /** * The set of options that only have an effect when set in the Terminal constructor. @@ -23,10 +24,33 @@ export class Terminal implements ITerminalApi { private _addonManager: AddonManager; private _parser: IParser | undefined; private _buffer: BufferNamespaceApi | undefined; + private _publicOptions: ITerminalOptions; constructor(options?: ITerminalOptions) { this._core = new TerminalCore(options); this._addonManager = new AddonManager(); + + this._publicOptions = {}; + for (const propName in this._core.options) { + Object.defineProperty(this._publicOptions, propName, { + get: () => { + return this._core.options[propName]; + }, + set: (value: any) => { + this._checkReadonlyOptions(propName); + this._core.options[propName] = value; + } + }); + } + } + + private _checkReadonlyOptions(propName: string): void { + // Throw an error if any constructor only option is modified + // from terminal.options + // Modifications from anywhere else are allowed + if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) { + throw new Error(`Option "${propName}" can only be set in the constructor`); + } } private _checkProposedApi(): void { @@ -95,11 +119,12 @@ export class Terminal implements ITerminalApi { }; } public get options(): ITerminalOptions { - return this._core.options; + return this._publicOptions; } public set options(options: ITerminalOptions) { - this._checkReadonlyOptions(options); - this._core.options = options; + for (const propName in options) { + this._publicOptions[propName] = options[propName]; + } } public blur(): void { this._core.blur(); @@ -225,7 +250,7 @@ export class Terminal implements ITerminalApi { public setOption(key: 'cols' | 'rows', value: number): void; public setOption(key: string, value: any): void; public setOption(key: any, value: any): void { - this._checkReadonlyOptions(); + this._checkReadonlyOptions(key); this._core.optionsService.setOption(key, value); } public refresh(start: number, end: number): void { @@ -252,15 +277,4 @@ export class Terminal implements ITerminalApi { } } } - - private _checkReadonlyOptions(options?: ITerminalOptions): void { - // Throw an error if any constructor only option is modified - // from terminal.options - // Modifications from anywhere else are allowed - for (const propName in options) { - if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) { - throw new Error(`Option "${propName}" can only be set in the constructor`); - } - } - } } From 5a468c08770aec164597d9a7bb250cc22558590f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Wed, 10 Nov 2021 18:02:00 +0100 Subject: [PATCH 37/58] fix #3548 --- src/browser/renderer/atlas/CharAtlasUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/renderer/atlas/CharAtlasUtils.ts b/src/browser/renderer/atlas/CharAtlasUtils.ts index b196b373..be92727a 100644 --- a/src/browser/renderer/atlas/CharAtlasUtils.ts +++ b/src/browser/renderer/atlas/CharAtlasUtils.ts @@ -16,7 +16,7 @@ export function generateConfig(scaledCharWidth: number, scaledCharHeight: number cursor: undefined, cursorAccent: undefined, selection: undefined, - ansi: colors.ansi + ansi: [...colors.ansi] }; return { devicePixelRatio: window.devicePixelRatio, From 9964210ac4c6af300693dd4714183f93273d1beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Wed, 10 Nov 2021 22:15:35 +0100 Subject: [PATCH 38/58] implement OSC 104|110|111|112 --- src/browser/ColorManager.ts | 43 +++++++++++++++++ src/browser/Terminal.ts | 39 +++++++++------- src/common/InputHandler.test.ts | 82 +++++++++++++++++++++++---------- src/common/InputHandler.ts | 73 +++++++++++++++++++++++++++-- src/common/Types.d.ts | 23 +++++++-- test/api/InputHandler.api.ts | 71 +++++++++++++++++++++++++++- 6 files changed, 279 insertions(+), 52 deletions(-) diff --git a/src/browser/ColorManager.ts b/src/browser/ColorManager.ts index b6950d28..ec7bdc8a 100644 --- a/src/browser/ColorManager.ts +++ b/src/browser/ColorManager.ts @@ -7,6 +7,7 @@ import { IColorManager, IColor, IColorSet, IColorContrastCache } from 'browser/T import { ITheme } from 'common/services/Services'; import { channels, color, css } from 'browser/Color'; import { ColorContrastCache } from 'browser/ColorContrastCache'; +import { ColorIndex } from 'common/Types'; const DEFAULT_FOREGROUND = css.toColor('#ffffff'); const DEFAULT_BACKGROUND = css.toColor('#000000'); @@ -65,6 +66,13 @@ export const DEFAULT_ANSI_COLORS = Object.freeze((() => { return colors; })()); +interface IRestoreColorSet { + foreground: IColor; + background: IColor; + cursor: IColor; + ansi: IColor[]; +} + /** * Manages the source of truth for a terminal's colors. */ @@ -73,6 +81,7 @@ export class ColorManager implements IColorManager { private _ctx: CanvasRenderingContext2D; private _litmusColor: CanvasGradient; private _contrastCache: IColorContrastCache; + private _restoreColors!: IRestoreColorSet; constructor(document: Document, public allowTransparency: boolean) { const canvas = document.createElement('canvas'); @@ -96,6 +105,7 @@ export class ColorManager implements IColorManager { ansi: DEFAULT_ANSI_COLORS.slice(), contrastCache: this._contrastCache }; + this._updateRestoreColors(); } public onOptionsChange(key: string): void { @@ -142,6 +152,39 @@ export class ColorManager implements IColorManager { this.colors.ansi[15] = this._parseColor(theme.brightWhite, DEFAULT_ANSI_COLORS[15]); // Clear our the cache this._contrastCache.clear(); + this._updateRestoreColors(); + } + + public restoreColor(slot?: ColorIndex): void { + // unset slot restores all ansi colors + if (slot === undefined) { + for (let i = 0; i < this._restoreColors.ansi.length; ++i) { + this.colors.ansi[i] = this._restoreColors.ansi[i]; + } + return; + } + switch (slot) { + case ColorIndex.FOREGROUND: + this.colors.foreground = this._restoreColors.foreground; + break; + case ColorIndex.BACKGROUND: + this.colors.background = this._restoreColors.background; + break; + case ColorIndex.CURSOR: + this.colors.cursor = this._restoreColors.cursor; + break; + default: + this.colors.ansi[slot] = this._restoreColors.ansi[slot]; + } + } + + private _updateRestoreColors(): void { + this._restoreColors = { + foreground: this.colors.foreground, + background: this.colors.background, + cursor: this.colors.cursor, + ansi: [...this.colors.ansi] + }; } private _parseColor( diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 7bc8f978..7273eebb 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -39,7 +39,7 @@ import { MouseZoneManager } from 'browser/MouseZoneManager'; import { AccessibilityManager } from './AccessibilityManager'; import { ITheme, IMarker, IDisposable, ISelectionPosition, ILinkProvider } from 'xterm'; import { DomRenderer } from 'browser/renderer/dom/DomRenderer'; -import { IKeyboardEvent, KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IColorEvent, ColorIndex, IColorRGB } from 'common/Types'; +import { IKeyboardEvent, KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IColorEvent, ColorIndex, IColorRGB, ColorRequestType } from 'common/Types'; import { evaluateKeyboardEvent } from 'common/input/Keyboard'; import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; @@ -179,9 +179,10 @@ export class Terminal extends CoreTerminal implements ITerminal { } /** - * Handle color event from inputhandler for OSC 4 | 10 | 11 | 12. - * An event from OSC 4 may contain multiple set or report requests, - * while OSC 10 | 11 | 12 create single requests. + * Handle color event from inputhandler for OSC 4|104 | 10|110 | 11|111 | 12|112. + * An event from OSC 4|104 may contain multiple set or report requests, and multiple + * or none restore requests (restting all), + * while an event from OSC 10|110 | 11|111 | 12|112 always contains a single request. */ private _handleColorEvent(event: IColorEvent): void { if (!this._colorManager) return; @@ -189,32 +190,38 @@ export class Terminal extends CoreTerminal implements ITerminal { let acc: 'foreground' | 'background' | 'cursor' | 'ansi' | undefined = undefined; let ident = ''; switch (req.index) { - case ColorIndex.FOREGROUND: // OSC 10 + case ColorIndex.FOREGROUND: // OSC 10 | 110 acc = 'foreground'; ident = '10'; break; - case ColorIndex.BACKGROUND: // OSC 11 + case ColorIndex.BACKGROUND: // OSC 11 | 111 acc = 'background'; ident = '11'; break; - case ColorIndex.CURSOR: // OSC 12 + case ColorIndex.CURSOR: // OSC 12 | 112 acc = 'cursor'; ident = '12'; break; - default: // OSC 4 + default: // OSC 4 | 104 // we can skip the [0..255] range check here (already done in inputhandler) acc = 'ansi'; ident = '4;' + req.index; } if (acc) { - if (req.color) { - if (acc === 'ansi') this._colorManager.colors.ansi[req.index] = rgba.toColor(...req.color); - else this._colorManager.colors[acc] = rgba.toColor(...req.color); - } else { - const channels = color.toColorRGB(acc === 'ansi' - ? this._colorManager.colors.ansi[req.index] - : this._colorManager.colors[acc]); - this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(channels)}${C0.BEL}`); + switch (req.type) { + case ColorRequestType.REPORT: + const channels = color.toColorRGB(acc === 'ansi' + ? this._colorManager.colors.ansi[req.index] + : this._colorManager.colors[acc]); + this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(channels)}${C0.BEL}`); + break; + case ColorRequestType.SET: + if (acc === 'ansi') this._colorManager.colors.ansi[req.index] = rgba.toColor(...req.color); + else this._colorManager.colors[acc] = rgba.toColor(...req.color); + break; + case ColorRequestType.RESTORE: + this._colorManager.restoreColor(req.index); + break; } } } diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index fe48cafc..b2830ae6 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -5,7 +5,7 @@ import { assert } from 'chai'; import { InputHandler } from 'common/InputHandler'; -import { IBufferLine, IAttributeData, IColorEvent, ColorIndex } from 'common/Types'; +import { IBufferLine, IAttributeData, IColorEvent, ColorIndex, ColorRequestType } from 'common/Types'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; import { CellData } from 'common/buffer/CellData'; import { Attributes, UnderlineStyle } from 'common/buffer/Constants'; @@ -1869,14 +1869,14 @@ describe('InputHandler', () => { inputHandler.onColor(ev => stack.push(ev)); // single color query await inputHandler.parseP('\x1b]4;0;?\x07'); - assert.deepEqual(stack, [[{ index: 0 }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: 0 }]]); stack.length = 0; await inputHandler.parseP('\x1b]4;123;?\x07'); - assert.deepEqual(stack, [[{ index: 123 }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: 123 }]]); stack.length = 0; // multiple queries await inputHandler.parseP('\x1b]4;0;?;123;?\x07'); - assert.deepEqual(stack, [[{ index: 0 }, { index: 123 }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: 0 }, { type: ColorRequestType.REPORT, index: 123 }]]); stack.length = 0; }); it('4: set color events', async () => { @@ -1884,92 +1884,124 @@ describe('InputHandler', () => { inputHandler.onColor(ev => stack.push(ev)); // single color query await inputHandler.parseP('\x1b]4;0;rgb:01/02/03\x07'); - assert.deepEqual(stack, [[{ index: 0, color: [1, 2, 3] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: 0, color: [1, 2, 3] }]]); stack.length = 0; await inputHandler.parseP('\x1b]4;123;#aabbcc\x07'); - assert.deepEqual(stack, [[{ index: 123, color: [170, 187, 204] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: 123, color: [170, 187, 204] }]]); stack.length = 0; // multiple queries await inputHandler.parseP('\x1b]4;0;rgb:aa/bb/cc;123;#001122\x07'); - assert.deepEqual(stack, [[{ index: 0, color: [170, 187, 204] }, { index: 123, color: [0, 17, 34] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: 0, color: [170, 187, 204] }, { type: ColorRequestType.SET, index: 123, color: [0, 17, 34] }]]); stack.length = 0; }); it('4: should ignore invalid values', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); await inputHandler.parseP('\x1b]4;0;rgb:aa/bb/cc;45;rgb:1/22/333;123;#001122\x07'); - assert.deepEqual(stack, [[{ index: 0, color: [170, 187, 204] }, { index: 123, color: [0, 17, 34] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: 0, color: [170, 187, 204] }, { type: ColorRequestType.SET, index: 123, color: [0, 17, 34] }]]); stack.length = 0; }); + it('104: restore events', async () => { + const stack: IColorEvent[] = []; + inputHandler.onColor(ev => stack.push(ev)); + await inputHandler.parseP('\x1b]104;0\x07\x1b]104;43\x07'); + assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: 0 }], [{ type: ColorRequestType.RESTORE, index: 43 }]]); + stack.length = 0; + // multiple in one command + await inputHandler.parseP('\x1b]104;0;43\x07'); + assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: 0 }, { type: ColorRequestType.RESTORE, index: 43 }]]); + stack.length = 0; + // full ANSI table restore + await inputHandler.parseP('\x1b]104\x07'); + assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE}]]); + }); it('10: FG set & query events', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); // single foreground query --> color undefined await inputHandler.parseP('\x1b]10;?\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndex.FOREGROUND }]]); stack.length = 0; // OSC with multiple values maps to OSC 10 & OSC 11 & OSC 12 await inputHandler.parseP('\x1b]10;?;?;?;?\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND }], [{ index: ColorIndex.BACKGROUND }], [{ index: ColorIndex.CURSOR }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndex.FOREGROUND }], [{ type: ColorRequestType.REPORT, index: ColorIndex.BACKGROUND }], [{ type: ColorRequestType.REPORT, index: ColorIndex.CURSOR }]]); stack.length = 0; // set foreground color events await inputHandler.parseP('\x1b]10;rgb:01/02/03\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND, color: [1, 2, 3] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndex.FOREGROUND, color: [1, 2, 3] }]]); stack.length = 0; await inputHandler.parseP('\x1b]10;#aabbcc\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.FOREGROUND, color: [170, 187, 204] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndex.FOREGROUND, color: [170, 187, 204] }]]); stack.length = 0; // set FG, BG and cursor color at once await inputHandler.parseP('\x1b]10;rgb:aa/bb/cc;#001122;rgb:12/34/56\x07'); assert.deepEqual(stack, [ - [{ index: ColorIndex.FOREGROUND, color: [170, 187, 204] }], - [{ index: ColorIndex.BACKGROUND, color: [0, 17, 34] }], - [{ index: ColorIndex.CURSOR, color: [18, 52, 86] }] + [{ type: ColorRequestType.SET, index: ColorIndex.FOREGROUND, color: [170, 187, 204] }], + [{ type: ColorRequestType.SET, index: ColorIndex.BACKGROUND, color: [0, 17, 34] }], + [{ type: ColorRequestType.SET, index: ColorIndex.CURSOR, color: [18, 52, 86] }] ]); }); + it('110: restore FG color', async () => { + const stack: IColorEvent[] = []; + inputHandler.onColor(ev => stack.push(ev)); + await inputHandler.parseP('\x1b]110\x07'); + assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: ColorIndex.FOREGROUND }]]); + }); it('11: BG set & query events', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); // single background query --> color undefined await inputHandler.parseP('\x1b]11;?\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndex.BACKGROUND }]]); stack.length = 0; // OSC 11 with multiple values creates only BG and cursor event await inputHandler.parseP('\x1b]11;?;?;?;?\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND }], [{ index: ColorIndex.CURSOR }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndex.BACKGROUND }], [{ type: ColorRequestType.REPORT, index: ColorIndex.CURSOR }]]); stack.length = 0; // set background color events await inputHandler.parseP('\x1b]11;rgb:01/02/03\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND, color: [1, 2, 3] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndex.BACKGROUND, color: [1, 2, 3] }]]); stack.length = 0; await inputHandler.parseP('\x1b]11;#aabbcc\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.BACKGROUND, color: [170, 187, 204] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndex.BACKGROUND, color: [170, 187, 204] }]]); stack.length = 0; // set BG and cursor color at once await inputHandler.parseP('\x1b]11;#001122;rgb:12/34/56\x07'); assert.deepEqual(stack, [ - [{ index: ColorIndex.BACKGROUND, color: [0, 17, 34] }], - [{ index: ColorIndex.CURSOR, color: [18, 52, 86] }] + [{ type: ColorRequestType.SET, index: ColorIndex.BACKGROUND, color: [0, 17, 34] }], + [{ type: ColorRequestType.SET, index: ColorIndex.CURSOR, color: [18, 52, 86] }] ]); }); + it('111: restore BG color', async () => { + const stack: IColorEvent[] = []; + inputHandler.onColor(ev => stack.push(ev)); + await inputHandler.parseP('\x1b]111\x07'); + assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: ColorIndex.BACKGROUND }]]); + }); it('12: cursor color set & query events', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); // single cursor query --> color undefined await inputHandler.parseP('\x1b]12;?\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.CURSOR }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndex.CURSOR }]]); stack.length = 0; // OSC 12 with multiple values creates only cursor event await inputHandler.parseP('\x1b]12;?;?;?;?\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.CURSOR }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndex.CURSOR }]]); stack.length = 0; // set cursor color events await inputHandler.parseP('\x1b]12;rgb:01/02/03\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.CURSOR, color: [1, 2, 3] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndex.CURSOR, color: [1, 2, 3] }]]); stack.length = 0; await inputHandler.parseP('\x1b]12;#aabbcc\x07'); - assert.deepEqual(stack, [[{ index: ColorIndex.CURSOR, color: [170, 187, 204] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndex.CURSOR, color: [170, 187, 204] }]]); + }); + it('112: restore cursor color', async () => { + const stack: IColorEvent[] = []; + inputHandler.onColor(ev => stack.push(ev)); + await inputHandler.parseP('\x1b]112\x07'); + assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: ColorIndex.CURSOR }]]); }); }); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 5377bc03..600e34aa 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -4,7 +4,7 @@ * @license MIT */ -import { IInputHandler, IAttributeData, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex } from 'common/Types'; +import { IInputHandler, IAttributeData, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex, ColorRequestType } from 'common/Types'; import { C0, C1 } from 'common/data/EscapeSequences'; import { CHARSETS, DEFAULT_CHARSET } from 'common/data/Charsets'; import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser'; @@ -421,11 +421,15 @@ export class InputHandler extends Disposable implements IInputHandler { // 51 - reserved for Emacs shell. // 52 - Manipulate Selection Data. // 104 ; c - Reset Color Number c. + this._parser.registerOscHandler(104, new OscHandler(data => this.restoreIndexedColor(data))); // 105 ; c - Reset Special Color Number c. // 106 ; c; f - Enable/disable Special Color Number c. // 110 - Reset VT100 text foreground color. + this._parser.registerOscHandler(110, new OscHandler(data => this.restoreFgColor(data))); // 111 - Reset VT100 text background color. + this._parser.registerOscHandler(111, new OscHandler(data => this.restoreBgColor(data))); // 112 - Reset text cursor color. + this._parser.registerOscHandler(112, new OscHandler(data => this.restoreCursorColor(data))); // 113 - Reset mouse foreground color. // 114 - Reset mouse background color. // 115 - Reset Tektronix foreground color. @@ -2861,11 +2865,11 @@ export class InputHandler extends Disposable implements IInputHandler { const index = parseInt(idx); if (0 <= index && index < 256) { if (spec === '?') { - event.push({ index }); + event.push({ type: ColorRequestType.REPORT, index }); } else { const color = parseColor(spec); if (color) { - event.push({ index, color }); + event.push({ type: ColorRequestType.SET, index, color }); } } } @@ -2890,11 +2894,11 @@ export class InputHandler extends Disposable implements IInputHandler { for (let i = 0; i < slots.length; ++i, ++offset) { if (offset >= this._specialColors.length) break; if (slots[i] === '?') { - this._onColor.fire([{ index: this._specialColors[offset] }]); + this._onColor.fire([{ type: ColorRequestType.REPORT, index: this._specialColors[offset] }]); } else { const color = parseColor(slots[i]); if (color) { - this._onColor.fire([{ index: this._specialColors[offset], color }]); + this._onColor.fire([{ type: ColorRequestType.SET, index: this._specialColors[offset], color }]); } } } @@ -2945,6 +2949,65 @@ export class InputHandler extends Disposable implements IInputHandler { return this._setOrReportSpecialColor(data, 2); } + /** + * OSC 104 ; ST - restore ANSI color + * + * @vt: #Y OSC 104 "Reset ANSI color" "OSC 104 ; c BEL" "Reset color number `c` to themed color." + * `c` is the color index between 0 and 255. This function restores the default color for `c` as + * specified by the loaded theme. Any number of `c` parameters may be given. + * If no parameters are given, the entire indexed color table will be reset. + */ + public restoreIndexedColor(data: string): boolean { + if (!data) { + this._onColor.fire([{ type: ColorRequestType.RESTORE }]); + return true; + } + const event: IColorEvent = []; + const slots = data.split(';'); + for (let i = 0; i < slots.length; ++i) { + if (/^\d+$/.exec(slots[i])) { + const index = parseInt(slots[i]); + if (0 <= index && index < 256) { + event.push({ type: ColorRequestType.RESTORE, index }); + } + } + } + if (event.length) { + this._onColor.fire(event); + } + return true; + } + + /** + * OSC 110 ST - restore default foreground color + * + * @vt: #Y OSC 110 "Restore default foreground color" "OSC 110 BEL" "Restore default foreground to themed color." + */ + public restoreFgColor(data: string): boolean { + this._onColor.fire([{ type: ColorRequestType.RESTORE, index: ColorIndex.FOREGROUND }]); + return true; + } + + /** + * OSC 111 ST - restore default background color + * + * @vt: #Y OSC 111 "Restore default background color" "OSC 111 BEL" "Restore default background to themed color." + */ + public restoreBgColor(data: string): boolean { + this._onColor.fire([{ type: ColorRequestType.RESTORE, index: ColorIndex.BACKGROUND }]); + return true; + } + + /** + * OSC 112 ST - restore default cursor color + * + * @vt: #Y OSC 112 "Restore default cursor color" "OSC 112 BEL" "Restore default cursor to themed color." + */ + public restoreCursorColor(data: string): boolean { + this._onColor.fire([{ type: ColorRequestType.RESTORE, index: ColorIndex.CURSOR }]); + return true; + } + /** * ESC E * C1.NEL diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index 7e1778a9..cef64356 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -348,20 +348,31 @@ export interface IWindowOptions { setWinLines?: boolean; } -// color events from common, used for OSC 4/10/11/12 +// color events from common, used for OSC 4/10/11/12 and 104/110/111/112 +export const enum ColorRequestType { + REPORT = 0, + SET = 1, + RESTORE = 2 +} export const enum ColorIndex { FOREGROUND = 256, BACKGROUND = 257, CURSOR = 258 } export interface IColorReportRequest { + type: ColorRequestType.REPORT; index: ColorIndex; - color?: IColorRGB; } -export interface IColorSetRequest extends IColorReportRequest { +export interface IColorSetRequest { + type: ColorRequestType.SET; + index: ColorIndex; color: IColorRGB; } -export type IColorEvent = (IColorReportRequest | IColorSetRequest)[]; +export interface IColorRestoreRequest { + type: ColorRequestType.RESTORE; + index?: ColorIndex; +} +export type IColorEvent = (IColorReportRequest | IColorSetRequest | IColorRestoreRequest)[]; /** @@ -433,6 +444,10 @@ export interface IInputHandler { /** OSC 10 */ setOrReportFgColor(data: string): boolean; /** OSC 11 */ setOrReportBgColor(data: string): boolean; /** OSC 12 */ setOrReportCursorColor(data: string): boolean; + /** OSC 104 */ restoreIndexedColor(data: string): boolean; + /** OSC 110 */ restoreFgColor(data: string): boolean; + /** OSC 111 */ restoreBgColor(data: string): boolean; + /** OSC 112 */ restoreCursorColor(data: string): boolean; /** ESC E */ nextLine(): boolean; /** ESC = */ keypadApplicationMode(): boolean; diff --git a/test/api/InputHandler.api.ts b/test/api/InputHandler.api.ts index fc8aadab..4d3a15dd 100644 --- a/test/api/InputHandler.api.ts +++ b/test/api/InputHandler.api.ts @@ -435,7 +435,51 @@ describe('InputHandler Integration Tests', function(): void { assert.deepEqual(await page.evaluate('window._recordedData'), restore); }); }); - describe('OSC 10 & 11', () => { + describe('OSC 4 & 104', () => { + before(async () => { + await page.evaluate('(() => {window._recordedData = []; window._h = term.onData(d => window._recordedData.push(d));})()'); + }); + after(async () => { + await page.evaluate('window._h.dispose()'); + }); + beforeEach(async () => { + await page.evaluate('window._recordedData.length = 0;'); + }); + it('change & restore single color', async () => { + // test for some random color slots + for (const i of [0, 43, 77, 255]) { + await writeSync(page, `\x1b]4;${i};?\x07`); + const restore: string[] = await page.evaluate('window._recordedData'); + await writeSync(page, `\x1b]4;${i};rgb:01/02/03\x07\x1b]4;${i};?\x07`); + assert.deepEqual(await page.evaluate('window._recordedData'), [restore[0], `\x1b]4;${i};rgb:0101/0202/0303\x07`]); + // restore slot color + await writeSync(page, `\x1b]104;${i}\x07\x1b]4;${i};?\x07`); + assert.deepEqual(await page.evaluate('window._recordedData'), [restore[0], `\x1b]4;${i};rgb:0101/0202/0303\x07`, restore[0]]); + await page.evaluate('window._recordedData.length = 0;'); + } + }); + it('restore multiple at once', async () => { + // change 3 random slots + await writeSync(page, `\x1b]4;0;?;43;?;77;?\x07`); + const restore: string[] = await page.evaluate('window._recordedData'); + await page.evaluate('window._recordedData.length = 0;'); + await writeSync(page, `\x1b]4;0;rgb:01/02/03;43;#aabbcc;77;#123456\x07`); + // restore specific slots + await writeSync(page, `\x1b]104;0;43;77\x07` + `\x1b]4;0;?;43;?;77;?\x07`); + assert.deepEqual(await page.evaluate('window._recordedData'), restore); + }); + it('restore full table', async () => { + // change 3 random slots + await writeSync(page, `\x1b]4;0;?;43;?;77;?\x07`); + const restore: string[] = await page.evaluate('window._recordedData'); + await page.evaluate('window._recordedData.length = 0;'); + await writeSync(page, `\x1b]4;0;rgb:01/02/03;43;#aabbcc;77;#123456\x07`); + // restore all + await writeSync(page, `\x1b]104\x07` + `\x1b]4;0;?;43;?;77;?\x07`); + assert.deepEqual(await page.evaluate('window._recordedData'), restore); + }); + }); + describe('OSC 10 & 11 + 110 | 111 | 112', () => { before(async () => { await page.evaluate('(() => {window._recordedData = []; window._h = term.onData(d => window._recordedData.push(d));})()'); }); @@ -480,8 +524,31 @@ describe('InputHandler Integration Tests', function(): void { assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]10;rgb:1212/3434/5656\x07', '\x1b]11;rgb:aaaa/bbbb/cccc\x07']); await writeSync(page, '\x1b]10;#ffffff;#000000\x07'); }); + it('OSC 110: restore FG color', async () => { + await writeSync(page, '\x1b]10;rgb:1/2/3\x07\x1b]10;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]10;rgb:1111/2222/3333\x07']); + await page.evaluate('window._recordedData.length = 0;'); + // restore + await writeSync(page, '\x1b]110\x07\x1b]10;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]10;rgb:ffff/ffff/ffff\x07']); + }); + it('OSC 111: restore BG color', async () => { + await writeSync(page, '\x1b]11;rgb:1/2/3\x07\x1b]11;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]11;rgb:1111/2222/3333\x07']); + await page.evaluate('window._recordedData.length = 0;'); + // restore + await writeSync(page, '\x1b]111\x07\x1b]11;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]11;rgb:0000/0000/0000\x07']); + }); + it('OSC 112: restore cursor color', async () => { + await writeSync(page, '\x1b]12;rgb:1/2/3\x07\x1b]12;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]12;rgb:1111/2222/3333\x07']); + await page.evaluate('window._recordedData.length = 0;'); + // restore + await writeSync(page, '\x1b]112\x07\x1b]12;?\x07'); + assert.deepEqual(await page.evaluate('window._recordedData'), ['\x1b]12;rgb:ffff/ffff/ffff\x07']); + }); }); - }); describe('ESC', () => { From 84325627aaa1c509e89c880326374816b2b00d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Wed, 10 Nov 2021 22:36:50 +0100 Subject: [PATCH 39/58] cleanup --- src/browser/ColorManager.ts | 16 +++++++++------- src/browser/Terminal.ts | 6 +++--- src/browser/renderer/atlas/CharAtlasUtils.ts | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/browser/ColorManager.ts b/src/browser/ColorManager.ts index ec7bdc8a..b4b57c67 100644 --- a/src/browser/ColorManager.ts +++ b/src/browser/ColorManager.ts @@ -9,6 +9,15 @@ import { channels, color, css } from 'browser/Color'; import { ColorContrastCache } from 'browser/ColorContrastCache'; import { ColorIndex } from 'common/Types'; + +interface IRestoreColorSet { + foreground: IColor; + background: IColor; + cursor: IColor; + ansi: IColor[]; +} + + const DEFAULT_FOREGROUND = css.toColor('#ffffff'); const DEFAULT_BACKGROUND = css.toColor('#000000'); const DEFAULT_CURSOR = css.toColor('#ffffff'); @@ -66,13 +75,6 @@ export const DEFAULT_ANSI_COLORS = Object.freeze((() => { return colors; })()); -interface IRestoreColorSet { - foreground: IColor; - background: IColor; - cursor: IColor; - ansi: IColor[]; -} - /** * Manages the source of truth for a terminal's colors. */ diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 7273eebb..4ea5afb7 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -21,7 +21,7 @@ * http://linux.die.net/man/7/urxvt */ -import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler, ILinkifier, IMouseZoneManager, LinkMatcherHandler, ILinkMatcherOptions, IViewport, ILinkifier2, CharacterJoinerHandler, IColor } from 'browser/Types'; +import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler, ILinkifier, IMouseZoneManager, LinkMatcherHandler, ILinkMatcherOptions, IViewport, ILinkifier2, CharacterJoinerHandler } from 'browser/Types'; import { IRenderer } from 'browser/renderer/Types'; import { CompositionHelper } from 'browser/input/CompositionHelper'; import { Viewport } from 'browser/Viewport'; @@ -39,7 +39,7 @@ import { MouseZoneManager } from 'browser/MouseZoneManager'; import { AccessibilityManager } from './AccessibilityManager'; import { ITheme, IMarker, IDisposable, ISelectionPosition, ILinkProvider } from 'xterm'; import { DomRenderer } from 'browser/renderer/dom/DomRenderer'; -import { IKeyboardEvent, KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IColorEvent, ColorIndex, IColorRGB, ColorRequestType } from 'common/Types'; +import { IKeyboardEvent, KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IColorEvent, ColorIndex, ColorRequestType } from 'common/Types'; import { evaluateKeyboardEvent } from 'common/input/Keyboard'; import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; @@ -181,7 +181,7 @@ export class Terminal extends CoreTerminal implements ITerminal { /** * Handle color event from inputhandler for OSC 4|104 | 10|110 | 11|111 | 12|112. * An event from OSC 4|104 may contain multiple set or report requests, and multiple - * or none restore requests (restting all), + * or none restore requests (resetting all), * while an event from OSC 10|110 | 11|111 | 12|112 always contains a single request. */ private _handleColorEvent(event: IColorEvent): void { diff --git a/src/browser/renderer/atlas/CharAtlasUtils.ts b/src/browser/renderer/atlas/CharAtlasUtils.ts index b196b373..be92727a 100644 --- a/src/browser/renderer/atlas/CharAtlasUtils.ts +++ b/src/browser/renderer/atlas/CharAtlasUtils.ts @@ -16,7 +16,7 @@ export function generateConfig(scaledCharWidth: number, scaledCharHeight: number cursor: undefined, cursorAccent: undefined, selection: undefined, - ansi: colors.ansi + ansi: [...colors.ansi] }; return { devicePixelRatio: window.devicePixelRatio, From 0c20589a7f99168f829f9fe9092b61fe8ee5c14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Wed, 10 Nov 2021 23:00:36 +0100 Subject: [PATCH 40/58] remove temp atlas fix --- src/browser/renderer/atlas/CharAtlasUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/renderer/atlas/CharAtlasUtils.ts b/src/browser/renderer/atlas/CharAtlasUtils.ts index be92727a..b196b373 100644 --- a/src/browser/renderer/atlas/CharAtlasUtils.ts +++ b/src/browser/renderer/atlas/CharAtlasUtils.ts @@ -16,7 +16,7 @@ export function generateConfig(scaledCharWidth: number, scaledCharHeight: number cursor: undefined, cursorAccent: undefined, selection: undefined, - ansi: [...colors.ansi] + ansi: colors.ansi }; return { devicePixelRatio: window.devicePixelRatio, From 935a1ba903cdc3a56c953f517e289a070ec985d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Acid=20Chicken=20=28=E7=A1=AB=E9=85=B8=E9=B6=8F=29?= Date: Fri, 12 Nov 2021 15:14:13 +0000 Subject: [PATCH 41/58] fix(xterm-addon-webgl): wide characters overflow the cache canvas --- addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts index 609df6eb..3627e1f5 100644 --- a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts +++ b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts @@ -14,8 +14,9 @@ import { AttributeData } from 'common/buffer/AttributeData'; import { channels, rgba } from 'browser/Color'; import { tryDrawCustomChar } from 'browser/renderer/CustomGlyphs'; -// In practice we're probably never going to exhaust a texture this large. For debugging purposes, -// however, it can be useful to set this to a really tiny value, to verify that LRU eviction works. +// FIXME: rendering many characters can overflow the texture rarely +// For debugging purposes, it can be useful to set this to a really tiny value, +// to verify that LRU eviction works. const TEXTURE_WIDTH = 1024; const TEXTURE_HEIGHT = 1024; @@ -463,7 +464,7 @@ export class WebglCharAtlas implements IDisposable { const clippedImageData = this._clipImageData(imageData, this._workBoundingBox); // Check if there is enough room in the current row and go to next if needed - if (this._currentRowX + this._config.scaledCharWidth > TEXTURE_WIDTH) { + if (this._currentRowX + rasterizedGlyph.size.x > TEXTURE_WIDTH) { this._currentRowX = 0; this._currentRowY += this._currentRowHeight; this._currentRowHeight = 0; From dbd3766a9dcb667fe73735e6938f199bac2d1dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Acid=20Chicken=20=28=E7=A1=AB=E9=85=B8=E9=B6=8F=29?= Date: Sat, 13 Nov 2021 01:36:46 +0900 Subject: [PATCH 42/58] chore: reflect reviews --- addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts index 3627e1f5..dd95f177 100644 --- a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts +++ b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts @@ -14,7 +14,6 @@ import { AttributeData } from 'common/buffer/AttributeData'; import { channels, rgba } from 'browser/Color'; import { tryDrawCustomChar } from 'browser/renderer/CustomGlyphs'; -// FIXME: rendering many characters can overflow the texture rarely // For debugging purposes, it can be useful to set this to a really tiny value, // to verify that LRU eviction works. const TEXTURE_WIDTH = 1024; From d7d85870d2efef1a18b270fb0f4a8206c890b99a Mon Sep 17 00:00:00 2001 From: Simon Lamon Date: Sat, 20 Nov 2021 17:33:38 +0000 Subject: [PATCH 43/58] remove headless include in benchmark projects --- test/benchmark/tsconfig.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/benchmark/tsconfig.json b/test/benchmark/tsconfig.json index cac99d90..2ebe2ebe 100644 --- a/test/benchmark/tsconfig.json +++ b/test/benchmark/tsconfig.json @@ -21,8 +21,7 @@ }, "include": [ "./**/*", - "../../typings/xterm.d.ts", - "../../out/**/*" + "../../typings/xterm.d.ts" ], "exclude": [ "../../**/*test.ts" From d85a57118ebe3c21e21a139e584d3db278be0512 Mon Sep 17 00:00:00 2001 From: Simon Lamon Date: Sat, 20 Nov 2021 17:48:45 +0000 Subject: [PATCH 44/58] remove headless include in benchmark projects --- addons/xterm-addon-serialize/benchmark/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/xterm-addon-serialize/benchmark/tsconfig.json b/addons/xterm-addon-serialize/benchmark/tsconfig.json index 42aaaa1b..bf5e335c 100644 --- a/addons/xterm-addon-serialize/benchmark/tsconfig.json +++ b/addons/xterm-addon-serialize/benchmark/tsconfig.json @@ -14,7 +14,7 @@ "SerializeAddon": ["../src/SerializeAddon"] } }, - "include": ["../**/*", "../../../typings/xterm.d.ts", "../../../out/**/*"], + "include": ["../**/*", "../../../typings/xterm.d.ts"], "exclude": ["../../../**/*test.ts", "../../**/*api.ts"], "references": [ { "path": "../../../src/common" }, From 070afc64c817e728603b8088d63f84c502970850 Mon Sep 17 00:00:00 2001 From: Labhansh Agrawal Date: Wed, 24 Nov 2021 12:53:10 +0000 Subject: [PATCH 45/58] trycatch characterJoiner handlers --- src/browser/services/CharacterJoinerService.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/browser/services/CharacterJoinerService.ts b/src/browser/services/CharacterJoinerService.ts index ea65c29b..9cef9fea 100644 --- a/src/browser/services/CharacterJoinerService.ts +++ b/src/browser/services/CharacterJoinerService.ts @@ -176,10 +176,20 @@ export class CharacterJoinerService implements ICharacterJoinerService { // At this point we already know that there is at least one joiner so // we can just pull its value and assign it directly rather than // merging it into an empty array, which incurs unnecessary writes. - const joinedRanges: [number, number][] = this._characterJoiners[0].handler(text); + let joinedRanges: [number, number][] = []; + try { + joinedRanges = this._characterJoiners[0].handler(text); + } catch (error) { + console.error(error); + } for (let i = 1; i < this._characterJoiners.length; i++) { // We merge any overlapping ranges across the different joiners - const joinerRanges = this._characterJoiners[i].handler(text); + let joinerRanges: [number, number][] = []; + try { + joinerRanges = this._characterJoiners[i].handler(text); + } catch (error) { + console.error(error); + } for (let j = 0; j < joinerRanges.length; j++) { CharacterJoinerService._mergeRanges(joinedRanges, joinerRanges[j]); } From d10d5be222173c1d21409959bc92b97d8506fcd2 Mon Sep 17 00:00:00 2001 From: Labhansh Agrawal Date: Thu, 25 Nov 2021 00:11:44 +0530 Subject: [PATCH 46/58] make requested changes --- src/browser/services/CharacterJoinerService.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/browser/services/CharacterJoinerService.ts b/src/browser/services/CharacterJoinerService.ts index 9cef9fea..ca4f1984 100644 --- a/src/browser/services/CharacterJoinerService.ts +++ b/src/browser/services/CharacterJoinerService.ts @@ -176,26 +176,25 @@ export class CharacterJoinerService implements ICharacterJoinerService { // At this point we already know that there is at least one joiner so // we can just pull its value and assign it directly rather than // merging it into an empty array, which incurs unnecessary writes. - let joinedRanges: [number, number][] = []; + let allJoinedRanges: [number, number][] = []; try { - joinedRanges = this._characterJoiners[0].handler(text); + allJoinedRanges = this._characterJoiners[0].handler(text); } catch (error) { console.error(error); } for (let i = 1; i < this._characterJoiners.length; i++) { // We merge any overlapping ranges across the different joiners - let joinerRanges: [number, number][] = []; try { - joinerRanges = this._characterJoiners[i].handler(text); + const joinerRanges = this._characterJoiners[i].handler(text); + for (let j = 0; j < joinerRanges.length; j++) { + CharacterJoinerService._mergeRanges(allJoinedRanges, joinerRanges[j]); + } } catch (error) { console.error(error); } - for (let j = 0; j < joinerRanges.length; j++) { - CharacterJoinerService._mergeRanges(joinedRanges, joinerRanges[j]); - } } - this._stringRangesToCellRanges(joinedRanges, lineData, startCol); - return joinedRanges; + this._stringRangesToCellRanges(allJoinedRanges, lineData, startCol); + return allJoinedRanges; } /** From 1304fd8a72e7a37ab1db28a245f55c4fe11fb823 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 9 Dec 2021 20:30:38 +0000 Subject: [PATCH 47/58] Add tabIndex to xterm-accessibility See microsoft/vscode#135920 --- src/browser/AccessibilityManager.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/browser/AccessibilityManager.ts b/src/browser/AccessibilityManager.ts index 80092202..eda29c05 100644 --- a/src/browser/AccessibilityManager.ts +++ b/src/browser/AccessibilityManager.ts @@ -55,6 +55,7 @@ export class AccessibilityManager extends Disposable { this._accessibilityTreeRoot = document.createElement('div'); this._accessibilityTreeRoot.setAttribute('role', 'document'); this._accessibilityTreeRoot.classList.add('xterm-accessibility'); + this._accessibilityTreeRoot.tabIndex = 0; this._rowContainer = document.createElement('div'); this._rowContainer.setAttribute('role', 'list'); From b7c33974713263af7caaa686730817d8268c48b4 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 9 Dec 2021 13:14:43 -0800 Subject: [PATCH 48/58] Clear unprocessed dead key state on input or press Fixes #3573 --- src/browser/Terminal.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 23122f3f..130cb3db 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -1169,6 +1169,10 @@ export class Terminal extends CoreTerminal implements ITerminal { this._keyPressHandled = true; + // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow + // keys could be ignored + this._unprocessedDeadKey = false; + return true; } @@ -1186,6 +1190,10 @@ export class Terminal extends CoreTerminal implements ITerminal { return false; } + // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow + // keys could be ignored + this._unprocessedDeadKey = false; + const text = ev.data; this.coreService.triggerDataEvent(text, true); From ddc3d07bd49c1b6b4e7e89779f00cf9efd00996d Mon Sep 17 00:00:00 2001 From: Michael Chlebek Date: Wed, 15 Dec 2021 18:17:28 +0100 Subject: [PATCH 49/58] Added support for custom regex to WebLinkProvider --- addons/xterm-addon-web-links/src/WebLinksAddon.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/addons/xterm-addon-web-links/src/WebLinksAddon.ts b/addons/xterm-addon-web-links/src/WebLinksAddon.ts index dd1c1f17..d1f9d00b 100644 --- a/addons/xterm-addon-web-links/src/WebLinksAddon.ts +++ b/addons/xterm-addon-web-links/src/WebLinksAddon.ts @@ -43,6 +43,7 @@ function handleLink(event: MouseEvent, uri: string): void { interface ILinkProviderOptions { hover?(event: MouseEvent, text: string, location: IViewportRange): void; leave?(event: MouseEvent, text: string): void; + urlRegex: RegExp | undefined; } export class WebLinksAddon implements ITerminalAddon { @@ -62,7 +63,11 @@ export class WebLinksAddon implements ITerminalAddon { if (this._useLinkProvider && 'registerLinkProvider' in this._terminal) { const options = this._options as ILinkProviderOptions; - this._linkProvider = this._terminal.registerLinkProvider(new WebLinkProvider(this._terminal, strictUrlRegex, this._handler, options)); + let regex = strictUrlRegex; + if (options.urlRegex) { + regex = options.urlRegex; + } + this._linkProvider = this._terminal.registerLinkProvider(new WebLinkProvider(this._terminal, regex, this._handler, options)); } else { // TODO: This should be removed eventually const options = this._options as ILinkMatcherOptions; From 7663e4a4e3345fd42768f9a37f9631879c950fa3 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 15 Dec 2021 12:03:29 -0800 Subject: [PATCH 50/58] Simplify with || --- addons/xterm-addon-web-links/src/WebLinksAddon.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/addons/xterm-addon-web-links/src/WebLinksAddon.ts b/addons/xterm-addon-web-links/src/WebLinksAddon.ts index d1f9d00b..a9ce3cdc 100644 --- a/addons/xterm-addon-web-links/src/WebLinksAddon.ts +++ b/addons/xterm-addon-web-links/src/WebLinksAddon.ts @@ -63,10 +63,7 @@ export class WebLinksAddon implements ITerminalAddon { if (this._useLinkProvider && 'registerLinkProvider' in this._terminal) { const options = this._options as ILinkProviderOptions; - let regex = strictUrlRegex; - if (options.urlRegex) { - regex = options.urlRegex; - } + const regex = options.urlRegex || strictUrlRegex; this._linkProvider = this._terminal.registerLinkProvider(new WebLinkProvider(this._terminal, regex, this._handler, options)); } else { // TODO: This should be removed eventually From 7157b03a7e208a082a38d14145751ae426db73eb Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 15 Dec 2021 12:04:07 -0800 Subject: [PATCH 51/58] Change interface to use ? So it's not a breaking change --- addons/xterm-addon-web-links/src/WebLinksAddon.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/xterm-addon-web-links/src/WebLinksAddon.ts b/addons/xterm-addon-web-links/src/WebLinksAddon.ts index a9ce3cdc..6ba211fe 100644 --- a/addons/xterm-addon-web-links/src/WebLinksAddon.ts +++ b/addons/xterm-addon-web-links/src/WebLinksAddon.ts @@ -43,7 +43,7 @@ function handleLink(event: MouseEvent, uri: string): void { interface ILinkProviderOptions { hover?(event: MouseEvent, text: string, location: IViewportRange): void; leave?(event: MouseEvent, text: string): void; - urlRegex: RegExp | undefined; + urlRegex?: RegExp; } export class WebLinksAddon implements ITerminalAddon { From 0ddb43ac8af23516920a4c012343d345716776f6 Mon Sep 17 00:00:00 2001 From: Squitch <63391793+SquitchYT@users.noreply.github.com> Date: Sat, 18 Dec 2021 16:40:58 +0100 Subject: [PATCH 52/58] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93675f32..23d53802 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**WizardWebssh**](https://gitlab.com/mikeramsey/wizardwebssh): A terminal with Pyqt5 Widget for embedding, which can be used as an ssh client to connect to your ssh servers. It is written in Python, based on tornado, paramiko, and xterm.js. - [**Wizard Assistant**](https://wizardassistant.com/): Wizard Assistant comes with advanced automation tools, preloaded common and special time-saving commands, and a built-in SSH terminal. Now you can remotely administer, troubleshoot, and analyze any system with ease. - [**ucli**](https://github.com/tsadarsh/ucli): Command Line for everyone :family_man_woman_girl_boy: at [www.ucli.tech](https://www.ucli.tech). -- [**Tess**](https://github.com/SquitchYT/Tess/): Simple Terminal Fully Customizable for Everyone. +- [**Tess**](https://github.com/SquitchYT/Tess/): Simple Terminal Fully Customizable for Everyone. Discover more at [tessapp.dev](https://tessapp.dev) - [**HashiCorp Nomad**](https://www.nomadproject.io/): A container orchestrator with the ability to connect to remote tasks via a web interface using websockets and xterm.js. - [**TermPair**](https://github.com/cs01/termpair): View and control terminals from your browser with end-to-end encryption - [**gdbgui**](https://github.com/cs01/gdbgui): Browser-based frontend to gdb (gnu debugger) From 9a920a10f38b2102d48d7f45fde01e31a0c42837 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 20 Dec 2021 08:46:13 -0800 Subject: [PATCH 53/58] Have linkifier2 use screen element for link detection Fixes #3579 --- css/xterm.css | 3 ++- src/browser/Terminal.ts | 2 +- typings/xterm.d.ts | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/css/xterm.css b/css/xterm.css index 3fab18bd..38e27a00 100644 --- a/css/xterm.css +++ b/css/xterm.css @@ -133,7 +133,8 @@ cursor: default; } -.xterm.xterm-cursor-pointer { +.xterm.xterm-cursor-pointer, +.xterm .xterm-cursor-pointer { cursor: pointer; } diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 23122f3f..6ab17060 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -537,7 +537,7 @@ export class Terminal extends CoreTerminal implements ITerminal { this.register(this._mouseZoneManager); this.register(this.onScroll(() => this._mouseZoneManager!.clearAll())); this.linkifier.attachToDom(this.element, this._mouseZoneManager); - this.linkifier2.attachToDom(this.element, this._mouseService, this._renderService); + this.linkifier2.attachToDom(this.screenElement, this._mouseService, this._renderService); // This event listener must be registered aftre MouseZoneManager is created this.register(addDisposableDomListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.onMouseDown(e))); diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 18bc0b95..40583628 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -1265,12 +1265,12 @@ declare module 'xterm' { */ interface IBufferCellPosition { /** - * The x position within the buffer. + * The x position within the buffer (1-based). */ x: number; /** - * The y position within the buffer. + * The y position within the buffer (1-based). */ y: number; } From 65712980614eac68bed4b03040e3a13bf86ff673 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 20 Dec 2021 10:02:49 -0800 Subject: [PATCH 54/58] Mark IKeyboardEvent.keyCode as deprecated --- src/common/Types.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index 88497e4a..3af7e2dc 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -46,6 +46,7 @@ export interface IKeyboardEvent { ctrlKey: boolean; shiftKey: boolean; metaKey: boolean; + /** @deprecated See KeyboardEvent.keyCode */ keyCode: number; key: string; type: string; From 7535d2e527697b4c223280ed6e3a2256400961d3 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 21 Dec 2021 09:13:53 -0800 Subject: [PATCH 55/58] Move options test to Terminal.api.ts --- src/browser/public/Terminal.test.ts | 43 ----------------------------- test/api/Terminal.api.ts | 31 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 43 deletions(-) delete mode 100644 src/browser/public/Terminal.test.ts diff --git a/src/browser/public/Terminal.test.ts b/src/browser/public/Terminal.test.ts deleted file mode 100644 index f03945a0..00000000 --- a/src/browser/public/Terminal.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2016 The xterm.js authors. All rights reserved. - * @license MIT - */ - -import { Terminal } from 'browser/public/Terminal'; -import { assert } from 'chai'; -import { ITerminalOptions } from 'common/Types'; - -const INIT_COLS = 80; -const INIT_ROWS = 24; - -describe('Public Terminal', () => { - let term: Terminal; - const termOptions = { - cols: INIT_COLS, - rows: INIT_ROWS - }; - - describe('options', () => { - beforeEach(async () => { - term = new Terminal(termOptions); - }); - it('get options', () => { - const options: ITerminalOptions = term.options; - assert.equal(options.cols, 80); - assert.equal(options.rows, 24); - }); - it('set options', async () => { - const options: ITerminalOptions = term.options; - assert.throws(() => options.cols = 40); - assert.throws(() => options.rows = 20); - term.options.scrollback = 1; - assert.equal(term.options.scrollback, 1); - term.options= { - fontSize: 12, - fontFamily: 'Arial' - }; - assert.equal(term.options.fontSize, 12); - assert.equal(term.options.fontFamily, 'Arial'); - }); - }); -}); diff --git a/test/api/Terminal.api.ts b/test/api/Terminal.api.ts index 00598e47..7243e617 100644 --- a/test/api/Terminal.api.ts +++ b/test/api/Terminal.api.ts @@ -6,6 +6,7 @@ import { assert } from 'chai'; import { pollFor, timeout, writeSync, openTerminal, launchBrowser } from './TestUtils'; import { Browser, Page } from 'playwright'; +import { fail } from 'assert'; const APP = 'http://127.0.0.1:3001/test'; @@ -160,6 +161,36 @@ describe('API Integration Tests', function(): void { assert.equal(await page.evaluate(`window.term.getOption('rendererType')`), 'dom'); }); + describe('options', () => { + it('getter', async () => { + await openTerminal(page); + assert.equal(await page.evaluate(`window.term.options.rendererType`), 'canvas'); + assert.equal(await page.evaluate(`window.term.options.cols`), 80); + assert.equal(await page.evaluate(`window.term.options.rows`), 24); + }); + it('setter', async () => { + await openTerminal(page); + try { + await page.evaluate('window.term.options.cols = 40'); + fail(); + } catch {} + try { + await page.evaluate('window.term.options.rows = 20'); + fail(); + } catch {} + await page.evaluate('window.term.options.scrollback = 1'); + assert.equal(await page.evaluate(`window.term.options.scrollback`), 1); + await page.evaluate(` + window.term.options = { + fontSize: 30, + fontFamily: 'Arial' + }; + `); + assert.equal(await page.evaluate(`window.term.options.fontSize`), 30); + assert.equal(await page.evaluate(`window.term.options.fontFamily`), 'Arial'); + }); + }); + describe('renderer', () => { it('foreground', async () => { await openTerminal(page, { rendererType: 'dom' }); From 8c94c97a283e816242523f5d723a1c567aa7f3fe Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 21 Dec 2021 10:49:58 -0800 Subject: [PATCH 56/58] Don't include trailing EOL when selecting multiple lines Fixes #3552 --- src/browser/selection/SelectionModel.test.ts | 8 ++++++++ src/browser/selection/SelectionModel.ts | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/browser/selection/SelectionModel.test.ts b/src/browser/selection/SelectionModel.test.ts index c15cdd29..410902d7 100644 --- a/src/browser/selection/SelectionModel.test.ts +++ b/src/browser/selection/SelectionModel.test.ts @@ -122,5 +122,13 @@ describe('SelectionModel', () => { model.selectionEnd = [5, 2]; assert.deepEqual(model.finalSelectionEnd, [5, 2]); }); + it('should not include a trailing EOL when the selection ends at the end of a line', () => { + model.selectionStart = [0, 0]; + model.selectionStartLength = 80; + assert.deepEqual(model.finalSelectionEnd, [80, 0]); + model.selectionStart = [0, 0]; + model.selectionStartLength = 160; + assert.deepEqual(model.finalSelectionEnd, [80, 1]); + }); }); }); diff --git a/src/browser/selection/SelectionModel.ts b/src/browser/selection/SelectionModel.ts index 1420444e..1d84446a 100644 --- a/src/browser/selection/SelectionModel.ts +++ b/src/browser/selection/SelectionModel.ts @@ -79,6 +79,10 @@ export class SelectionModel { if (!this.selectionEnd || this.areSelectionValuesReversed()) { const startPlusLength = this.selectionStart[0] + this.selectionStartLength; if (startPlusLength > this._bufferService.cols) { + // Ensure the trailing EOL isn't included when the selection ends on the right edge + if (startPlusLength % this._bufferService.cols === 0) { + return [this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols) - 1]; + } return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)]; } return [startPlusLength, this.selectionStart[1]]; From 13b8c78947103c2415c3775f41a0490826ad25af Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 22 Dec 2021 08:55:39 -0800 Subject: [PATCH 57/58] Fix demo Fixes #3585 --- demo/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/client.ts b/demo/client.ts index cd0657a0..58d719a1 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -293,7 +293,7 @@ function initOptions(term: TerminalType): void { rendererType: ['dom', 'canvas'], wordSeparator: null }; - const options = Object.keys(term.options); + const options = Object.getOwnPropertyNames(term.options); const booleanOptions = []; const numberOptions = []; options.filter(o => blacklistedOptions.indexOf(o) === -1).forEach(o => { From 086ca58eceff7393f6655439f0f479b3ab5ee991 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 22 Dec 2021 09:10:12 -0800 Subject: [PATCH 58/58] Comment tweaks --- src/browser/Color.ts | 2 -- src/common/input/XParseColor.ts | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/browser/Color.ts b/src/browser/Color.ts index a4e415af..32e311db 100644 --- a/src/browser/Color.ts +++ b/src/browser/Color.ts @@ -6,8 +6,6 @@ import { IColor } from 'browser/Types'; import { IColorRGB } from 'common/Types'; -// FIXME: Move Color.ts lib to common? - /** * Helper functions where the source type is "channels" (individual color channels as numbers). */ diff --git a/src/common/input/XParseColor.ts b/src/common/input/XParseColor.ts index 922bf8a9..8c023a38 100644 --- a/src/common/input/XParseColor.ts +++ b/src/common/input/XParseColor.ts @@ -49,7 +49,10 @@ export function parseColor(data: string): [number, number, number] | undefined { return result; } } - // FIXME: Once #3530 is resolved, implement named colors. + + // Named colors are currently not supported due to the large addition to the xterm.js bundle size + // they would add. In order to support named colors, we would need some way of optionally loading + // additional payloads so startup/download time is not bloated (see #3530). } // pad hex output to requested bit width