From e05ae83d6a0255de50440202ddbe488c186d683f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Thu, 6 Jun 2019 02:31:41 +0200 Subject: [PATCH 01/28] inital integration of xterm-benchmark --- benchmark.json | 11 + bin/benchmark.js | 53 +++ package.json | 6 +- .../parser/EscapeSequenceParser.benchmark.ts | 251 ++++++++++ yarn.lock | 441 +++++++++++++++++- 5 files changed, 756 insertions(+), 6 deletions(-) create mode 100644 benchmark.json create mode 100644 bin/benchmark.js create mode 100644 src/core/parser/EscapeSequenceParser.benchmark.ts diff --git a/benchmark.json b/benchmark.json new file mode 100644 index 0000000000..4d70f0ab59 --- /dev/null +++ b/benchmark.json @@ -0,0 +1,11 @@ +{ + "evalConfig": { + "tolerance": { + "*": [0.75, 1.5] + }, + "skip": [ + "*.median", + "*.runs" + ] + } +} \ No newline at end of file diff --git a/bin/benchmark.js b/bin/benchmark.js new file mode 100644 index 0000000000..a03f6e16a8 --- /dev/null +++ b/bin/benchmark.js @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2019 The xterm.js authors. All rights reserved. + * @license MIT + */ + +const cp = require('child_process'); +const path = require('path'); +const glob = require('glob'); + +// Add `out` to the NODE_PATH so absolute paths can be resolved. +const env = { ...process.env }; +env.NODE_PATH = path.resolve(__dirname, '../out'); + +/** + * Default commands for yarn: + * yarn benchmark single single run of all benchmarks without statistics + * yarn benchmark baseline 10 runs of all benchmarks with baseline statistics + * yarn benchmark eval 10 runs of all benchmarks with eval against last baseline + */ +const commands = { + single : '-c benchmark.json', + baseline: '--baseline -r 10 -c benchmark.json', + eval : '--eval -r 10 -c benchmark.json' +} + +let testFiles = [ + './out/**/*benchmark.js' +]; + +// allow overriding cmdline args (see yarn benchmark --help) +if (process.argv.length === 3 && process.argv[2] in commands) { + testFiles.push(commands[process.argv[2]]); +} else if (process.argv.length > 2) { + testFiles = process.argv.slice(2); +} + +cp.spawnSync( + path.resolve(__dirname, '../node_modules/.bin/xterm-benchmark'), + testFiles.reduce((accu, cur) => { + const expanded = glob.sync(cur); + if (!expanded.length) { + accu.push(cur); + return accu; + } + return accu.concat(expanded); + }, []), + { + cwd: path.resolve(__dirname, '..'), + env, + stdio: 'inherit', + shell: true + } +); diff --git a/package.json b/package.json index 16ebca92fe..8ad844e92c 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "prepare": "npm run build", "prepublishOnly": "npm run package", "watch": "tsc -b -w ./tsconfig.all.json --preserveWatchOutput", - "clean": "rm -rf lib out addons/*/lib" + "clean": "rm -rf lib out addons/*/lib", + "benchmark": "node ./bin/benchmark.js" }, "devDependencies": { "@types/chai": "^3.4.34", @@ -47,6 +48,7 @@ "utf8": "^3.0.0", "webpack": "^4.17.1", "webpack-cli": "^3.1.0", - "ws": "^7.0.0" + "ws": "^7.0.0", + "xterm-benchmark": "../xterm-benchmark" } } diff --git a/src/core/parser/EscapeSequenceParser.benchmark.ts b/src/core/parser/EscapeSequenceParser.benchmark.ts new file mode 100644 index 0000000000..9494f6cf4a --- /dev/null +++ b/src/core/parser/EscapeSequenceParser.benchmark.ts @@ -0,0 +1,251 @@ +import { perfContext, before, beforeEach, ThroughputRuntimeCase } from 'xterm-benchmark'; + +import { EscapeSequenceParser } from 'core/parser/EscapeSequenceParser'; +import { C0, C1 } from 'common/data/EscapeSequences'; +import { IDcsHandler } from './Types'; + + +function toUtf32(s: string) { + const result = new Uint32Array(s.length); + for (let i = 0; i < s.length; ++i) { + result[i] = s.charCodeAt(i); + } + return result; +} + + +perfContext('Parser performance - 50MB data', () => { + let content; + let taContent: Uint32Array; + let parser: EscapeSequenceParser; + let dcsHandler: IDcsHandler = { + hook: (collect, params, flag) => {}, + put: (data, start, end) => {}, + unhook: () => {} + }; + beforeEach(() => { + parser = new EscapeSequenceParser(); + parser.setPrintHandler((data, start, end) => {}); + parser.setCsiHandler('@', (params, collect) => {}); + parser.setCsiHandler('A', (params, collect) => {}); + parser.setCsiHandler('B', (params, collect) => {}); + parser.setCsiHandler('C', (params, collect) => {}); + parser.setCsiHandler('D', (params, collect) => {}); + parser.setCsiHandler('E', (params, collect) => {}); + parser.setCsiHandler('F', (params, collect) => {}); + parser.setCsiHandler('G', (params, collect) => {}); + parser.setCsiHandler('H', (params, collect) => {}); + parser.setCsiHandler('I', (params, collect) => {}); + parser.setCsiHandler('J', (params, collect) => {}); + parser.setCsiHandler('K', (params, collect) => {}); + parser.setCsiHandler('L', (params, collect) => {}); + parser.setCsiHandler('M', (params, collect) => {}); + parser.setCsiHandler('P', (params, collect) => {}); + parser.setCsiHandler('S', (params, collect) => {}); + parser.setCsiHandler('T', (params, collect) => {}); + parser.setCsiHandler('X', (params, collect) => {}); + parser.setCsiHandler('Z', (params, collect) => {}); + parser.setCsiHandler('`', (params, collect) => {}); + parser.setCsiHandler('a', (params, collect) => {}); + parser.setCsiHandler('b', (params, collect) => {}); + parser.setCsiHandler('c', (params, collect) => {}); + parser.setCsiHandler('d', (params, collect) => {}); + parser.setCsiHandler('e', (params, collect) => {}); + parser.setCsiHandler('f', (params, collect) => {}); + parser.setCsiHandler('g', (params, collect) => {}); + parser.setCsiHandler('h', (params, collect) => {}); + parser.setCsiHandler('l', (params, collect) => {}); + parser.setCsiHandler('m', (params, collect) => {}); + parser.setCsiHandler('n', (params, collect) => {}); + parser.setCsiHandler('p', (params, collect) => {}); + parser.setCsiHandler('q', (params, collect) => {}); + parser.setCsiHandler('r', (params, collect) => {}); + parser.setCsiHandler('s', (params, collect) => {}); + parser.setCsiHandler('u', (params, collect) => {}); + parser.setExecuteHandler(C0.BEL, () => {}); + parser.setExecuteHandler(C0.LF, () => {}); + parser.setExecuteHandler(C0.VT, () => {}); + parser.setExecuteHandler(C0.FF, () => {}); + parser.setExecuteHandler(C0.CR, () => {}); + parser.setExecuteHandler(C0.BS, () => {}); + parser.setExecuteHandler(C0.HT, () => {}); + parser.setExecuteHandler(C0.SO, () => {}); + parser.setExecuteHandler(C0.SI, () => {}); + parser.setExecuteHandler(C1.IND, () => {}); + parser.setExecuteHandler(C1.NEL, () => {}); + parser.setExecuteHandler(C1.HTS, () => {}); + parser.setOscHandler(0, (data) => {}); + parser.setOscHandler(2, (data) => {}); + parser.setEscHandler('7', () => {}); + parser.setEscHandler('8', () => {}); + parser.setEscHandler('D', () => {}); + parser.setEscHandler('E', () => {}); + parser.setEscHandler('H', () => {}); + parser.setEscHandler('M', () => {}); + parser.setEscHandler('=', () => {}); + parser.setEscHandler('>', () => {}); + parser.setEscHandler('c', () => {}); + parser.setEscHandler('n', () => {}); + parser.setEscHandler('o', () => {}); + parser.setEscHandler('|', () => {}); + parser.setEscHandler('}', () => {}); + parser.setEscHandler('~', () => {}); + parser.setEscHandler('%@', () => {}); + parser.setEscHandler('%G', () => {}); + parser.setDcsHandler('q', dcsHandler); + }); + + perfContext('print - a', () => { + before(() => { + let data = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', async () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('execute - \\n', () => { + before(() => { + let data = '\n\n\n\n\n\n\n'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('escape - ESC E', () => { + before(() => { + let data = '\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('escape with collect - ESC % G', () => { + before(() => { + let data = '\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('simple csi - CSI A', () => { + before(() => { + let data = '\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('csi with collect - CSI ? p', () => { + before(() => { + let data = '\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('csi with params - CSI 1;2 m', () => { + before(() => { + let data = '\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('osc (small payload) - OSC 0;hi ST', () => { + before(() => { + let data = '\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\x1b]0;hi\x1b\\'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('osc (big payload) - OSC 0; ST', () => { + before(() => { + let data = '\x1b]0;Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\x1b\\'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('DCS (small payload)', () => { + before(() => { + let data = '\x1bPq~~\x1b\\'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', async () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('DCS (big payload)', () => { + before(() => { + let data = '\x1bPq#0;2;0;0;0#1;2;100;100;0#2;2;0;100;0#1~~@@vv@@~~@@~~$#2??}}GG}}??}}??-#1!14@\x1b\\'; + content = ''; + while (content.length < 50000000) + content += data; + taContent = toUtf32(content); + }); + new ThroughputRuntimeCase('throughput', async () => { + parser.parse(taContent, taContent.length); + return {payloadSize: taContent.length}; + }, {fork: true}).showAverageThroughput(); + }); +}); diff --git a/yarn.lock b/yarn.lock index 61a7062987..a6857edf8c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,22 @@ # yarn lockfile v1 +"@babel/code-frame@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + "@fimbul/bifrost@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@fimbul/bifrost/-/bifrost-0.11.0.tgz#83cacc21464198b12e3cc1c2204ae6c6d7afd158" @@ -21,16 +37,33 @@ reflect-metadata "^0.1.12" tslib "^1.8.1" +"@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@^3.4.34": version "3.5.2" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-3.5.2.tgz#c11cd2817d3a401b7ba0f5a420f35c56139b1c1e" integrity sha1-wRzSgX06QBt7oPWkIPNcVhObHB4= +"@types/cli-table@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@types/cli-table/-/cli-table-0.3.0.tgz#f1857156bf5fd115c6a2db260ba0be1f8fc5671c" + integrity sha512-QnZUISJJXyhyD6L1e5QwXDV/A5i2W1/gl6D6YMc8u0ncPepbv/B4w3S+izVvtAg60m6h+JP09+Y/0zF2mojlFQ== + "@types/events@*": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== +"@types/fs-extra@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-7.0.0.tgz#9c4ad9e1339e7448a76698829def1f159c1b636c" + integrity sha512-ndoMMbGyuToTy4qB6Lex/inR98nPiNHacsgMPvy+zqMLgSxbt8VtWpDArpGp69h1fEDQHn1KB+9DWD++wgbwYA== + dependencies: + "@types/node" "*" + "@types/glob@^5.0.35": version "5.0.35" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a" @@ -49,6 +82,13 @@ "@types/tough-cookie" "*" parse5 "^3.0.2" +"@types/mathjs@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@types/mathjs/-/mathjs-5.0.1.tgz#b98e163ea396b4f27bec20ee25ffb8fe9e656af8" + integrity sha512-EFBuueI+BRed9bnUO6/9my55b4FH+VQIvqMm58h9JGbtaGCkqr3YSDhnmVbM1SJjF//8SURERSypzNwejOk7lA== + dependencies: + decimal.js "^10.0.0" + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -59,6 +99,11 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.48.tgz#3523b126a0b049482e1c3c11877460f76622ffab" integrity sha512-nlK/iyETgafGli8Zh9zJVCTicvU3iajSkRwOh3Hhiva598CMqNJ4NcVCGMTGKpGpTYj/9R8RLzS9NAykSSCqGw== +"@types/mocha@^5.2.7": + version "5.2.7" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" + integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== + "@types/node@*": version "10.5.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.2.tgz#f19f05314d5421fe37e74153254201a7bf00a707" @@ -69,6 +114,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.108.tgz#852e8496bcfc5e74cae83a5eb3b30e5661e9b7b9" integrity sha512-5q14jNJCPW+Iwk6Y1JxtA7T5ov1aVRS2VA2PvRgFMZtCjoIo8WT1WO56dSV0MSiHR7BEoe2QNuXigBQNqbWdAw== +"@types/node@^12.0.4": + version "12.0.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.5.tgz#ac14404c33d1a789973c45379a67f7f7e58a01b9" + integrity sha512-CFLSALoE+93+Hcb5pFjp0J1uMrrbLRe+L1+gFwerJ776R3TACSF0kTVRQ7AvRa7aFx70nqYHAc7wQPlt9kY2Mg== + "@types/puppeteer@^1.12.4": version "1.12.4" resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-1.12.4.tgz#8388efdb0b30a54a7e7c4831ca0d709191d77ff1" @@ -389,6 +439,11 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" +app-root-path@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a" + integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA== + aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -492,6 +547,13 @@ async@^2.5.0: dependencies: lodash "^4.17.10" +async@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" + integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== + dependencies: + lodash "^4.17.11" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -815,6 +877,25 @@ chownr@^1.0.1: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" integrity sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE= +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.12: + version "0.0.12" + resolved "https://registry.yarnpkg.com/chrome-timeline/-/chrome-timeline-0.0.12.tgz#1516223b4bf289750b4b244c3f88d0095b10f914" + integrity sha512-lDVZGV2VYVS7kTmoLxwOmoTvKLxBHRiBQqGNvD87Bky+uIsnK6ThwESqIj+rsjx218Vq9tU5H6Bv2u6IsafS/g== + dependencies: + "@types/app-root-path" "^1.2.4" + "@types/fs-extra" "^7.0.0" + "@types/puppeteer" "^1.12.4" + app-root-path "^2.2.1" + devtools-timeline-model "^1.4.0" + puppeteer "^1.17.0" + simple-git "^1.113.0" + winston "^3.2.1" + chrome-trace-event@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" @@ -847,6 +928,13 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" +cli-table@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" + integrity sha1-9TsFJmqLGguTSz0IIebi3FkUriM= + dependencies: + colors "1.0.3" + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -861,6 +949,11 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -886,11 +979,75 @@ color-convert@^1.9.0: dependencies: color-name "1.1.1" +color-convert@^1.9.1: + 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== + dependencies: + color-name "1.1.3" + color-name@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" integrity sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok= +color-name@1.1.3: + version "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: + 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.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + 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" + +colornames@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" + integrity sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y= + +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.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + +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" + integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs= + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + combined-stream@1.0.6, combined-stream@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" @@ -903,6 +1060,11 @@ commander@^2.12.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.16.0.tgz#f16390593996ceb4f3eeb020b31d78528f7f8a50" integrity sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew== +commander@^2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" @@ -913,6 +1075,11 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= +complex.js@2.0.11: + version "2.0.11" + resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.11.tgz#09a873fbf15ffd8c18c9c2201ccef425c32b8bf1" + integrity sha512-6IArJLApNtdg1P1dFtn3dnyzoZBEF0MwMnrfF1exSBRpZYoy4yieMkpZhQDC0uwctw48vii0CFVyHfpgZ/DfGw== + component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" @@ -1119,7 +1286,7 @@ debug@^3.1.0: dependencies: ms "2.0.0" -debug@^4.1.0: +debug@^4.0.1, debug@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -1145,6 +1312,11 @@ decamelize@^2.0.0: dependencies: xregexp "4.0.0" +decimal.js@10.2.0, decimal.js@^10.0.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.0.tgz#39466113a9e036111d02f82489b5fd6b0b5ed231" + integrity sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -1167,6 +1339,13 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -1229,6 +1408,23 @@ detect-libc@^1.0.2: resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= +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" + +diagnostics@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" + integrity sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ== + dependencies: + colorspace "1.1.x" + enabled "1.0.x" + kuler "1.0.x" + diff@3.5.0, diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -1300,6 +1496,13 @@ emojis-list@^2.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= +enabled@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93" + integrity sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M= + dependencies: + env-variable "0.0.x" + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" @@ -1316,6 +1519,11 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: memory-fs "^0.4.0" tapable "^1.0.0" +env-variable@0.0.x: + version "0.0.5" + resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88" + integrity sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA== + errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" @@ -1361,6 +1569,11 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= +escape-latex@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.2.0.tgz#07c03818cf7dac250cce517f4fda1b001ef2bca1" + integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw== + escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -1591,6 +1804,11 @@ fast-levenshtein@~2.0.4: 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.6" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2" + integrity sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg== + fd-slicer@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" @@ -1598,6 +1816,11 @@ fd-slicer@~1.0.1: dependencies: pend "~1.2.0" +fecha@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" + integrity sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg== + figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -1687,6 +1910,11 @@ forwarded@~0.1.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= +fraction.js@4.0.12: + version "4.0.12" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.12.tgz#0526d47c65a5fb4854df78bc77f7bec708d7b8c3" + integrity sha512-8Z1K0VTG4hzYY7kA/1sj4/r1/RWLBD3xwReT/RCrUCbzPszjNQCCsy3ktkU/eaEqX3MYa4pY37a52eiBlPMlhA== + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -2112,6 +2340,11 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.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-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -2289,12 +2522,22 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +javascript-natural-sort@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" + integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k= + js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@3.13.1: +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@3.13.1, js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -2411,6 +2654,13 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== +kuler@1.0.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6" + integrity sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ== + dependencies: + colornames "^1.1.1" + lcid@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" @@ -2495,6 +2745,17 @@ log-symbols@2.2.0: dependencies: chalk "^2.0.1" +logform@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.1.2.tgz#957155ebeb67a13164069825ce67ddb5bb2dd360" + integrity sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ== + dependencies: + colors "^1.2.1" + fast-safe-stringify "^2.0.4" + fecha "^2.3.3" + ms "^2.1.1" + triple-beam "^1.3.0" + long@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" @@ -2544,6 +2805,20 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +mathjs@^5.10.3: + version "5.10.3" + resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-5.10.3.tgz#e998885f932ea8886db8b40f7f5b199f89b427f1" + integrity sha512-ySjg30BC3dYjQm73ILZtwcWzFJde0VU6otkXW/57IjjuYRa3Qaf0Kb8pydEuBZYtqW2OxreAtsricrAmOj3jIw== + dependencies: + complex.js "2.0.11" + decimal.js "10.2.0" + escape-latex "1.2.0" + fraction.js "4.0.12" + javascript-natural-sort "0.7.1" + seed-random "2.2.0" + tiny-emitter "2.1.0" + typed-function "1.1.0" + md5.js@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" @@ -3015,6 +3290,11 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +one-time@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e" + integrity sha1-+M33eISCb+Tf+T46nMN7HkSAdC4= + onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" @@ -3376,6 +3656,20 @@ puppeteer@^1.15.0: rimraf "^2.6.1" ws "^6.1.0" +puppeteer@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.17.0.tgz#371957d227a2f450fa74b78e78a2dadb2be7f14f" + integrity sha512-3EXZSximCzxuVKpIHtyec8Wm2dWZn1fc5tQi34qWfiUgubEVYHjUvr0GOJojqf3mifI6oyKnCdrGxaOI+lWReA== + dependencies: + debug "^4.1.0" + extract-zip "^1.6.6" + https-proxy-agent "^2.2.1" + mime "^2.0.3" + progress "^2.0.1" + proxy-from-env "^1.0.0" + rimraf "^2.6.1" + ws "^6.1.0" + qs@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/qs/-/qs-4.0.0.tgz#c31d9b74ec27df75e543a86c78728ed8d4623607" @@ -3439,6 +3733,15 @@ rc@^1.2.7: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.1.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" + integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -3551,6 +3854,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +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.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" @@ -3637,6 +3945,11 @@ schema-utils@^0.4.4, schema-utils@^0.4.5: ajv "^6.1.0" ajv-keywords "^3.1.0" +seed-random@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54" + integrity sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ= + semver@^5.0.1: version "5.5.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" @@ -3762,6 +4075,20 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +simple-git@^1.113.0: + version "1.113.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.113.0.tgz#668989728a1e9cf4ec6c72b69ea2eecc93489bea" + integrity sha512-i9WVsrK2u0G/cASI9nh7voxOk9mhanWY9eGtWBDSYql6m49Yk5/Fan6uZsDr/xmzv8n+eQ8ahKCoEr8cvU3h+g== + dependencies: + debug "^4.0.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" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -3866,6 +4193,11 @@ ssri@^5.2.4: dependencies: safe-buffer "^5.1.1" +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= + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -3954,6 +4286,13 @@ string_decoder@^1.0.0, string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +string_decoder@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" + strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -4034,6 +4373,11 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" +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== + through2@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -4054,6 +4398,11 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +tiny-emitter@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -4113,6 +4462,11 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +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@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-4.5.0.tgz#a1ce70b2dc799941fb2197605f0d67874097859b" @@ -4138,6 +4492,25 @@ tslint-consistent-codestyle@^1.13.0: tslib "^1.7.1" tsutils "^2.27.0" +tslint@^5.17.0: + version "5.17.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.17.0.tgz#f9f0ce2011d8e90debaa6e9b4975f24cd16852b8" + integrity sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w== + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.1" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.29.0" + tslint@^5.9.1: version "5.10.0" resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.10.0.tgz#11e26bccb88afa02dd0d9956cae3d4540b5f54c3" @@ -4163,6 +4536,13 @@ tsutils@^2.12.1, tsutils@^2.24.0, tsutils@^2.27.0: dependencies: tslib "^1.8.1" +tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -4205,12 +4585,17 @@ type-is@~1.6.6: media-typer "0.3.0" mime-types "~2.1.18" +typed-function@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-1.1.0.tgz#ea149706e0fb42aca1791c053a6d94ccd6c4fdcb" + integrity sha512-TuQzwiT4DDg19beHam3E66oRXhyqlyfgjHB/5fcvsRXbfmWPJfto9B4a0TBdTrQAPGlGmXh/k7iUI+WsObgORA== + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@3.5: +typescript@3.5, typescript@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.1.tgz#ba72a6a600b2158139c5dd8850f700e231464202" integrity sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw== @@ -4316,7 +4701,7 @@ 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, 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= @@ -4387,6 +4772,13 @@ watchpack@^1.5.0: graceful-fs "^4.1.2" neo-async "^2.5.0" +wcwidth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -4496,6 +4888,29 @@ wide-align@1.1.3, wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +winston-transport@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.3.0.tgz#df68c0c202482c448d9b47313c07304c2d7c2c66" + integrity sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A== + dependencies: + readable-stream "^2.3.6" + triple-beam "^1.2.0" + +winston@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.2.1.tgz#63061377976c73584028be2490a1846055f77f07" + integrity sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw== + dependencies: + async "^2.6.1" + diagnostics "^1.1.1" + is-stream "^1.1.0" + logform "^2.1.1" + one-time "0.0.4" + readable-stream "^3.1.1" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.3.0" + wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -4566,6 +4981,24 @@ xtend@^4.0.0, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= +xterm-benchmark@../xterm-benchmark: + version "0.1.2" + dependencies: + "@types/app-root-path" "^1.2.4" + "@types/cli-table" "^0.3.0" + "@types/mathjs" "^5.0.1" + "@types/mocha" "^5.2.7" + "@types/node" "^12.0.4" + app-root-path "^2.2.1" + chrome-timeline "0.0.12" + cli-table "^0.3.1" + columnify "^1.5.4" + commander "^2.20.0" + mathjs "^5.10.3" + mocha "^6.1.4" + tslint "^5.17.0" + typescript "^3.5.1" + "y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" From 06949df56057cfdd6d2f7cf588a28646a2f9b768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Thu, 6 Jun 2019 02:43:22 +0200 Subject: [PATCH 02/28] make linter happy --- .../parser/EscapeSequenceParser.benchmark.ts | 59 +++++++++++-------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/core/parser/EscapeSequenceParser.benchmark.ts b/src/core/parser/EscapeSequenceParser.benchmark.ts index 9494f6cf4a..3680f60caa 100644 --- a/src/core/parser/EscapeSequenceParser.benchmark.ts +++ b/src/core/parser/EscapeSequenceParser.benchmark.ts @@ -5,7 +5,7 @@ import { C0, C1 } from 'common/data/EscapeSequences'; import { IDcsHandler } from './Types'; -function toUtf32(s: string) { +function toUtf32(s: string): Uint32Array { const result = new Uint32Array(s.length); for (let i = 0; i < s.length; ++i) { result[i] = s.charCodeAt(i); @@ -18,7 +18,7 @@ perfContext('Parser performance - 50MB data', () => { let content; let taContent: Uint32Array; let parser: EscapeSequenceParser; - let dcsHandler: IDcsHandler = { + const dcsHandler: IDcsHandler = { hook: (collect, params, flag) => {}, put: (data, start, end) => {}, unhook: () => {} @@ -97,10 +97,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('print - a', () => { before(() => { - let data = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; + const data = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', async () => { @@ -111,10 +112,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('execute - \\n', () => { before(() => { - let data = '\n\n\n\n\n\n\n'; + const data = '\n\n\n\n\n\n\n'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', () => { @@ -125,10 +127,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('escape - ESC E', () => { before(() => { - let data = '\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE'; + const data = '\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', () => { @@ -139,10 +142,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('escape with collect - ESC % G', () => { before(() => { - let data = '\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G'; + const data = '\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', () => { @@ -153,10 +157,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('simple csi - CSI A', () => { before(() => { - let data = '\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A'; + const data = '\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', () => { @@ -167,10 +172,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('csi with collect - CSI ? p', () => { before(() => { - let data = '\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p'; + const data = '\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', () => { @@ -181,10 +187,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('csi with params - CSI 1;2 m', () => { before(() => { - let data = '\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m'; + const data = '\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', () => { @@ -195,10 +202,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('osc (small payload) - OSC 0;hi ST', () => { before(() => { - let data = '\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\x1b]0;hi\x1b\\'; + const data = '\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\x1b]0;hi\x1b\\'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', () => { @@ -209,10 +217,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('osc (big payload) - OSC 0; ST', () => { before(() => { - let data = '\x1b]0;Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\x1b\\'; + const data = '\x1b]0;Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\x1b\\'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', () => { @@ -223,10 +232,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('DCS (small payload)', () => { before(() => { - let data = '\x1bPq~~\x1b\\'; + const data = '\x1bPq~~\x1b\\'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', async () => { @@ -237,10 +247,11 @@ perfContext('Parser performance - 50MB data', () => { perfContext('DCS (big payload)', () => { before(() => { - let data = '\x1bPq#0;2;0;0;0#1;2;100;100;0#2;2;0;100;0#1~~@@vv@@~~@@~~$#2??}}GG}}??}}??-#1!14@\x1b\\'; + const data = '\x1bPq#0;2;0;0;0#1;2;100;100;0#2;2;0;100;0#1~~@@vv@@~~@@~~$#2??}}GG}}??}}??-#1!14@\x1b\\'; content = ''; - while (content.length < 50000000) + while (content.length < 50000000) { content += data; + } taContent = toUtf32(content); }); new ThroughputRuntimeCase('throughput', async () => { From e1f7c8a2dfd0ff6138dbe834d7f1cfac5f9c58c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Thu, 6 Jun 2019 02:59:42 +0200 Subject: [PATCH 03/28] link against npm package --- package.json | 2 +- yarn.lock | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 8ad844e92c..6b14d216fa 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,6 @@ "webpack": "^4.17.1", "webpack-cli": "^3.1.0", "ws": "^7.0.0", - "xterm-benchmark": "../xterm-benchmark" + "xterm-benchmark": "^0.1.3" } } diff --git a/yarn.lock b/yarn.lock index a6857edf8c..ab7f1bbb41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4981,8 +4981,10 @@ xtend@^4.0.0, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= -xterm-benchmark@../xterm-benchmark: - version "0.1.2" +xterm-benchmark@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/xterm-benchmark/-/xterm-benchmark-0.1.3.tgz#c637d078f7b73f77a4342299e706b4d0e52ab46a" + integrity sha512-HBSeUOFlr9JVMFNkL5w8EkuWccczkfZAX6adK5fSot1sRRAFJS9NZcXH/yRLZp9S24qOUBJznMZGa9CjWB3h3g== dependencies: "@types/app-root-path" "^1.2.4" "@types/cli-table" "^0.3.0" From 3ff3a5d78de10ab95654d7ac13c8ba2cff302422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Thu, 6 Jun 2019 15:46:52 +0200 Subject: [PATCH 04/28] add benchmark for write and writeUtf8 --- benchmark.json | 13 +++++-- bin/benchmark.js | 4 +-- src/Terminal.benchmark.ts | 75 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 src/Terminal.benchmark.ts diff --git a/benchmark.json b/benchmark.json index 4d70f0ab59..7d8e222333 100644 --- a/benchmark.json +++ b/benchmark.json @@ -1,11 +1,18 @@ { "evalConfig": { "tolerance": { - "*": [0.75, 1.5] + "*": [0.75, 1.5], + "*.dev": [0.01, 1.5], + "*.cv": [0.01, 1.5], + "EscapeSequenceParser.benchmark.js.*.averageThroughput.mean": [0.9, 5] }, "skip": [ "*.median", - "*.runs" + "*.runs", + "*.dev", + "*.cv", + "EscapeSequenceParser.benchmark.js.*.averageRuntime", + "Terminal.benchmark.js.*.averageRuntime" ] } -} \ No newline at end of file +} diff --git a/bin/benchmark.js b/bin/benchmark.js index a03f6e16a8..894d98db44 100644 --- a/bin/benchmark.js +++ b/bin/benchmark.js @@ -19,8 +19,8 @@ env.NODE_PATH = path.resolve(__dirname, '../out'); */ const commands = { single : '-c benchmark.json', - baseline: '--baseline -r 10 -c benchmark.json', - eval : '--eval -r 10 -c benchmark.json' + baseline: '--baseline -r 5 -c benchmark.json', + eval : '--eval -r 5 -c benchmark.json' } let testFiles = [ diff --git a/src/Terminal.benchmark.ts b/src/Terminal.benchmark.ts new file mode 100644 index 0000000000..fafd85cf12 --- /dev/null +++ b/src/Terminal.benchmark.ts @@ -0,0 +1,75 @@ +import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark'; + +import { Terminal } from 'Terminal'; +import { spawn } from 'node-pty'; +import { Utf8ToUtf32, stringFromCodePoint } from '../out/core/input/TextDecoder'; + + +class TestTerminal extends Terminal { + writeSync(data: string): void { + this.writeBuffer.push(data); + this._innerWrite(); + } + writeSyncUtf8(data: Uint8Array): void { + this.writeBufferUtf8.push(data); + this._innerWriteUtf8(); + } +} + +perfContext('Terminal: ls -lR /usr', () => { + let content = ''; + let contentUtf8: Uint8Array; + + before(async () => { + // grab output from "ls -lR /usr" + const p = spawn('ls', ['--color=auto', '-lR', '/usr'], { + name: 'xterm-color', + cols: 80, + rows: 25, + cwd: process.env.HOME, + env: process.env, + encoding: null + }); + const chunks: Buffer[] = []; + let length = 0; + p.on('data', data => { + chunks.push(data as unknown as Buffer); + length += data.length; + }); + await new Promise(resolve => p.on('exit', () => resolve())); + contentUtf8 = Buffer.concat(chunks, length); + // translate to content string + const buffer = new Uint32Array(contentUtf8.length); + const decoder = new Utf8ToUtf32(); + const codepoints = decoder.decode(contentUtf8, buffer); + for (let i = 0; i < codepoints; ++i) { + content += stringFromCodePoint(buffer[i]); + // peek into content to force flat repr in v8 + if (!(i % 10000000)) { + content[i]; + } + } + }); + + perfContext('write', () => { + let terminal: TestTerminal; + before(() => { + terminal = new TestTerminal({cols: 80, rows: 25, scrollback: 1000}); + }); + new ThroughputRuntimeCase('', () => { + terminal.writeSync(content); + return {payloadSize: contentUtf8.length}; + }, {fork: false}).showAverageThroughput(); + }); + + perfContext('writeUtf8', () => { + let terminal: TestTerminal; + before(() => { + terminal = new TestTerminal({cols: 80, rows: 25, scrollback: 1000}); + }); + new ThroughputRuntimeCase('', () => { + terminal.writeSyncUtf8(contentUtf8); + return {payloadSize: contentUtf8.length}; + }, {fork: false}).showAverageThroughput(); + }); +}); From b17164520cba7ac5e29deea4d43bae3f035e9b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Fri, 7 Jun 2019 19:14:04 +0200 Subject: [PATCH 05/28] skip benchmark folders in git --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index cd350bb8b6..01c17961f3 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,7 @@ package-lock.json # Keep bundled code out of Git dist/ demo/dist/ + +# dont commit benahcmark folders +benchmark/ +timeline/ From ce91fba1d9d61fc6235aa1789bbbb2fa8ba5fe74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Fri, 7 Jun 2019 19:14:52 +0200 Subject: [PATCH 06/28] fix typo --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 01c17961f3..f221a5bcb5 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,6 @@ package-lock.json dist/ demo/dist/ -# dont commit benahcmark folders +# dont commit benchmark folders benchmark/ timeline/ From 8e1ebe42b1a407289241d13faafb0603a55abc05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Fri, 7 Jun 2019 21:39:07 +0200 Subject: [PATCH 07/28] fix import, set copyright note --- src/Terminal.benchmark.ts | 9 +++++++-- src/core/parser/EscapeSequenceParser.benchmark.ts | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Terminal.benchmark.ts b/src/Terminal.benchmark.ts index fafd85cf12..650ed6558a 100644 --- a/src/Terminal.benchmark.ts +++ b/src/Terminal.benchmark.ts @@ -1,8 +1,13 @@ +/** + * Copyright (c) 2019 The xterm.js authors. All rights reserved. + * @license MIT + */ + import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark'; import { Terminal } from 'Terminal'; import { spawn } from 'node-pty'; -import { Utf8ToUtf32, stringFromCodePoint } from '../out/core/input/TextDecoder'; +import { Utf8ToUtf32, stringFromCodePoint } from 'core/input/TextDecoder'; class TestTerminal extends Terminal { @@ -23,7 +28,7 @@ perfContext('Terminal: ls -lR /usr', () => { before(async () => { // grab output from "ls -lR /usr" const p = spawn('ls', ['--color=auto', '-lR', '/usr'], { - name: 'xterm-color', + name: 'xterm-256color', cols: 80, rows: 25, cwd: process.env.HOME, diff --git a/src/core/parser/EscapeSequenceParser.benchmark.ts b/src/core/parser/EscapeSequenceParser.benchmark.ts index 3680f60caa..392774dd2f 100644 --- a/src/core/parser/EscapeSequenceParser.benchmark.ts +++ b/src/core/parser/EscapeSequenceParser.benchmark.ts @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2019 The xterm.js authors. All rights reserved. + * @license MIT + */ import { perfContext, before, beforeEach, ThroughputRuntimeCase } from 'xterm-benchmark'; import { EscapeSequenceParser } from 'core/parser/EscapeSequenceParser'; From 674914bbb70437b421a48ec7e5c9f24a95b7d055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 9 Jun 2019 14:51:44 +0200 Subject: [PATCH 08/28] moving benchmarks out of './src': Harder than I thought for several reasons: - need access to common to tests the subparts, thus the unified tsconfig in tests does not work (need the path translation to those parts) - moving next to src I cannot use direct imports anymore (source files are out of rootDir), thus have to rely on d.ts files in out which is quite suboptimal as many parts do not expose the declaration files (can only type Terminal as any atm) - compiler output has to resemble the '../out/..' import logic of the TS files or require fails, thus moved the ouput to './benchmark' for now Conclusion: Not yet there, maybe not a good idea at all to move those tests out of './src' as they heavily rely on not exported internals. Needs more fiddling with the repo structure. --- .../EscapeSequenceParser.benchmark.ts | 6 ++--- .../Terminal.benchmark.ts | 15 ++++++----- benchmark-tests/benchmark.json | 18 +++++++++++++ benchmark-tests/tsconfig.json | 27 +++++++++++++++++++ tsconfig.all.json | 5 +++- 5 files changed, 61 insertions(+), 10 deletions(-) rename {src/core/parser => benchmark-tests}/EscapeSequenceParser.benchmark.ts (97%) rename {src => benchmark-tests}/Terminal.benchmark.ts (84%) create mode 100644 benchmark-tests/benchmark.json create mode 100644 benchmark-tests/tsconfig.json diff --git a/src/core/parser/EscapeSequenceParser.benchmark.ts b/benchmark-tests/EscapeSequenceParser.benchmark.ts similarity index 97% rename from src/core/parser/EscapeSequenceParser.benchmark.ts rename to benchmark-tests/EscapeSequenceParser.benchmark.ts index 392774dd2f..d64f581279 100644 --- a/src/core/parser/EscapeSequenceParser.benchmark.ts +++ b/benchmark-tests/EscapeSequenceParser.benchmark.ts @@ -4,9 +4,9 @@ */ import { perfContext, before, beforeEach, ThroughputRuntimeCase } from 'xterm-benchmark'; -import { EscapeSequenceParser } from 'core/parser/EscapeSequenceParser'; -import { C0, C1 } from 'common/data/EscapeSequences'; -import { IDcsHandler } from './Types'; +import { EscapeSequenceParser } from '../out/common/parser/EscapeSequenceParser'; +import { C0, C1 } from '../out/common/data/EscapeSequences'; +import { IDcsHandler } from '../out/common/parser/Types'; function toUtf32(s: string): Uint32Array { diff --git a/src/Terminal.benchmark.ts b/benchmark-tests/Terminal.benchmark.ts similarity index 84% rename from src/Terminal.benchmark.ts rename to benchmark-tests/Terminal.benchmark.ts index 650ed6558a..9e5e10bc2a 100644 --- a/src/Terminal.benchmark.ts +++ b/benchmark-tests/Terminal.benchmark.ts @@ -5,19 +5,22 @@ import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark'; -import { Terminal } from 'Terminal'; import { spawn } from 'node-pty'; -import { Utf8ToUtf32, stringFromCodePoint } from 'core/input/TextDecoder'; +import { Utf8ToUtf32, stringFromCodePoint } from '../out/common/input/TextDecoder'; +const Terminal: any = require('../out/Terminal').Terminal; class TestTerminal extends Terminal { + constructor(opts: any) { + super(opts); + } writeSync(data: string): void { this.writeBuffer.push(data); - this._innerWrite(); + (this as any)._innerWrite(); } writeSyncUtf8(data: Uint8Array): void { - this.writeBufferUtf8.push(data); - this._innerWriteUtf8(); + (this as any).writeBufferUtf8.push(data); + (this as any)._innerWriteUtf8(); } } @@ -33,7 +36,7 @@ perfContext('Terminal: ls -lR /usr', () => { rows: 25, cwd: process.env.HOME, env: process.env, - encoding: null + encoding: (null as unknown as string) // needs to be fixed in node-pty }); const chunks: Buffer[] = []; let length = 0; diff --git a/benchmark-tests/benchmark.json b/benchmark-tests/benchmark.json new file mode 100644 index 0000000000..7d8e222333 --- /dev/null +++ b/benchmark-tests/benchmark.json @@ -0,0 +1,18 @@ +{ + "evalConfig": { + "tolerance": { + "*": [0.75, 1.5], + "*.dev": [0.01, 1.5], + "*.cv": [0.01, 1.5], + "EscapeSequenceParser.benchmark.js.*.averageThroughput.mean": [0.9, 5] + }, + "skip": [ + "*.median", + "*.runs", + "*.dev", + "*.cv", + "EscapeSequenceParser.benchmark.js.*.averageRuntime", + "Terminal.benchmark.js.*.averageRuntime" + ] + } +} diff --git a/benchmark-tests/tsconfig.json b/benchmark-tests/tsconfig.json new file mode 100644 index 0000000000..02079d2b23 --- /dev/null +++ b/benchmark-tests/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "lib": [ + "dom", + "es6", + ], + "rootDir": ".", + "outDir": "../benchmark", + "types": [ + "../node_modules/@types/node" + ], + "sourceMap": true, + "removeComments": true, + "pretty": true, + "strict": true, + "baseUrl": ".", + "paths": { + "common/*": [ "./../out/common/*" ], + "browser/*": [ "./../out/browser/*" ] + }, + "declaration": true + }, + "include": [ + "./**/*", + "../typings/xterm.d.ts" + ] +} diff --git a/tsconfig.all.json b/tsconfig.all.json index d2670811ac..d8d8d20b0e 100644 --- a/tsconfig.all.json +++ b/tsconfig.all.json @@ -7,6 +7,9 @@ { "path": "./addons/xterm-addon-attach/src" }, { "path": "./addons/xterm-addon-fit/src" }, { "path": "./addons/xterm-addon-search/src" }, - { "path": "./addons/xterm-addon-web-links/src" } + { "path": "./addons/xterm-addon-web-links/src" }, + + // currently depends on out, thus must run as last? + { "path": "./benchmark-tests" }, ] } From 3204d9d7c9015db856ff29225f1a949e47b05072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 9 Jun 2019 15:19:48 +0200 Subject: [PATCH 09/28] fix benchmark script --- benchmark-tests/tsconfig.json | 5 ++--- bin/benchmark.js | 10 ++++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/benchmark-tests/tsconfig.json b/benchmark-tests/tsconfig.json index 02079d2b23..9012ee4d26 100644 --- a/benchmark-tests/tsconfig.json +++ b/benchmark-tests/tsconfig.json @@ -17,11 +17,10 @@ "paths": { "common/*": [ "./../out/common/*" ], "browser/*": [ "./../out/browser/*" ] - }, - "declaration": true + } }, "include": [ "./**/*", "../typings/xterm.d.ts" - ] + ], } diff --git a/bin/benchmark.js b/bin/benchmark.js index 894d98db44..077febe451 100644 --- a/bin/benchmark.js +++ b/bin/benchmark.js @@ -18,13 +18,13 @@ env.NODE_PATH = path.resolve(__dirname, '../out'); * yarn benchmark eval 10 runs of all benchmarks with eval against last baseline */ const commands = { - single : '-c benchmark.json', - baseline: '--baseline -r 5 -c benchmark.json', - eval : '--eval -r 5 -c benchmark.json' + single : '-r 5 -c ./benchmark-tests/benchmark.json', + baseline: '--baseline -r 5 -c ./benchmark-tests/benchmark.json', + eval : '--eval -r 5 -c ./benchmark-tests/benchmark.json' } let testFiles = [ - './out/**/*benchmark.js' + './benchmark/*benchmark.js' ]; // allow overriding cmdline args (see yarn benchmark --help) @@ -32,6 +32,8 @@ if (process.argv.length === 3 && process.argv[2] in commands) { testFiles.push(commands[process.argv[2]]); } else if (process.argv.length > 2) { testFiles = process.argv.slice(2); +} else if (process.argv.length === 2) { + testFiles.push(commands['single']); } cp.spawnSync( From e920f1db86e69040720eee1cc33a901a3f79f64a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 9 Jun 2019 17:31:57 +0200 Subject: [PATCH 10/28] cleaner approach --- benchmark-tests/benchmark.json | 18 ------ benchmark-tests/tsconfig.json | 26 --------- bin/benchmark.js | 55 ------------------- package.json | 4 +- .../EscapeSequenceParser.benchmark.d.ts | 1 + .../EscapeSequenceParser.benchmark.ts | 6 +- src/benchmark-tests/Terminal.benchmark.d.ts | 1 + .../benchmark-tests}/Terminal.benchmark.ts | 8 +-- src/benchmark-tests/tsconfig.json | 23 ++++++++ tsconfig.all.json | 4 +- 10 files changed, 34 insertions(+), 112 deletions(-) delete mode 100644 benchmark-tests/benchmark.json delete mode 100644 benchmark-tests/tsconfig.json delete mode 100644 bin/benchmark.js create mode 100644 src/benchmark-tests/EscapeSequenceParser.benchmark.d.ts rename {benchmark-tests => src/benchmark-tests}/EscapeSequenceParser.benchmark.ts (97%) create mode 100644 src/benchmark-tests/Terminal.benchmark.d.ts rename {benchmark-tests => src/benchmark-tests}/Terminal.benchmark.ts (92%) create mode 100644 src/benchmark-tests/tsconfig.json diff --git a/benchmark-tests/benchmark.json b/benchmark-tests/benchmark.json deleted file mode 100644 index 7d8e222333..0000000000 --- a/benchmark-tests/benchmark.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "evalConfig": { - "tolerance": { - "*": [0.75, 1.5], - "*.dev": [0.01, 1.5], - "*.cv": [0.01, 1.5], - "EscapeSequenceParser.benchmark.js.*.averageThroughput.mean": [0.9, 5] - }, - "skip": [ - "*.median", - "*.runs", - "*.dev", - "*.cv", - "EscapeSequenceParser.benchmark.js.*.averageRuntime", - "Terminal.benchmark.js.*.averageRuntime" - ] - } -} diff --git a/benchmark-tests/tsconfig.json b/benchmark-tests/tsconfig.json deleted file mode 100644 index 9012ee4d26..0000000000 --- a/benchmark-tests/tsconfig.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "compilerOptions": { - "lib": [ - "dom", - "es6", - ], - "rootDir": ".", - "outDir": "../benchmark", - "types": [ - "../node_modules/@types/node" - ], - "sourceMap": true, - "removeComments": true, - "pretty": true, - "strict": true, - "baseUrl": ".", - "paths": { - "common/*": [ "./../out/common/*" ], - "browser/*": [ "./../out/browser/*" ] - } - }, - "include": [ - "./**/*", - "../typings/xterm.d.ts" - ], -} diff --git a/bin/benchmark.js b/bin/benchmark.js deleted file mode 100644 index 077febe451..0000000000 --- a/bin/benchmark.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2019 The xterm.js authors. All rights reserved. - * @license MIT - */ - -const cp = require('child_process'); -const path = require('path'); -const glob = require('glob'); - -// Add `out` to the NODE_PATH so absolute paths can be resolved. -const env = { ...process.env }; -env.NODE_PATH = path.resolve(__dirname, '../out'); - -/** - * Default commands for yarn: - * yarn benchmark single single run of all benchmarks without statistics - * yarn benchmark baseline 10 runs of all benchmarks with baseline statistics - * yarn benchmark eval 10 runs of all benchmarks with eval against last baseline - */ -const commands = { - single : '-r 5 -c ./benchmark-tests/benchmark.json', - baseline: '--baseline -r 5 -c ./benchmark-tests/benchmark.json', - eval : '--eval -r 5 -c ./benchmark-tests/benchmark.json' -} - -let testFiles = [ - './benchmark/*benchmark.js' -]; - -// allow overriding cmdline args (see yarn benchmark --help) -if (process.argv.length === 3 && process.argv[2] in commands) { - testFiles.push(commands[process.argv[2]]); -} else if (process.argv.length > 2) { - testFiles = process.argv.slice(2); -} else if (process.argv.length === 2) { - testFiles.push(commands['single']); -} - -cp.spawnSync( - path.resolve(__dirname, '../node_modules/.bin/xterm-benchmark'), - testFiles.reduce((accu, cur) => { - const expanded = glob.sync(cur); - if (!expanded.length) { - accu.push(cur); - return accu; - } - return accu.concat(expanded); - }, []), - { - cwd: path.resolve(__dirname, '..'), - env, - stdio: 'inherit', - shell: true - } -); diff --git a/package.json b/package.json index 6b14d216fa..52fd70018f 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ "prepublishOnly": "npm run package", "watch": "tsc -b -w ./tsconfig.all.json --preserveWatchOutput", "clean": "rm -rf lib out addons/*/lib", - "benchmark": "node ./bin/benchmark.js" + "benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmark.json", + "benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmark.json --baseline out/benchmark-tests/*benchmark.js", + "benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmark.json --eval out/benchmark-tests/*benchmark.js" }, "devDependencies": { "@types/chai": "^3.4.34", diff --git a/src/benchmark-tests/EscapeSequenceParser.benchmark.d.ts b/src/benchmark-tests/EscapeSequenceParser.benchmark.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/src/benchmark-tests/EscapeSequenceParser.benchmark.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/benchmark-tests/EscapeSequenceParser.benchmark.ts b/src/benchmark-tests/EscapeSequenceParser.benchmark.ts similarity index 97% rename from benchmark-tests/EscapeSequenceParser.benchmark.ts rename to src/benchmark-tests/EscapeSequenceParser.benchmark.ts index d64f581279..57f8329c8d 100644 --- a/benchmark-tests/EscapeSequenceParser.benchmark.ts +++ b/src/benchmark-tests/EscapeSequenceParser.benchmark.ts @@ -4,9 +4,9 @@ */ import { perfContext, before, beforeEach, ThroughputRuntimeCase } from 'xterm-benchmark'; -import { EscapeSequenceParser } from '../out/common/parser/EscapeSequenceParser'; -import { C0, C1 } from '../out/common/data/EscapeSequences'; -import { IDcsHandler } from '../out/common/parser/Types'; +import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser'; +import { C0, C1 } from 'common/data/EscapeSequences'; +import { IDcsHandler } from 'common/parser/Types'; function toUtf32(s: string): Uint32Array { diff --git a/src/benchmark-tests/Terminal.benchmark.d.ts b/src/benchmark-tests/Terminal.benchmark.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/src/benchmark-tests/Terminal.benchmark.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/benchmark-tests/Terminal.benchmark.ts b/src/benchmark-tests/Terminal.benchmark.ts similarity index 92% rename from benchmark-tests/Terminal.benchmark.ts rename to src/benchmark-tests/Terminal.benchmark.ts index 9e5e10bc2a..a9e5bca703 100644 --- a/benchmark-tests/Terminal.benchmark.ts +++ b/src/benchmark-tests/Terminal.benchmark.ts @@ -6,14 +6,10 @@ import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark'; import { spawn } from 'node-pty'; -import { Utf8ToUtf32, stringFromCodePoint } from '../out/common/input/TextDecoder'; - -const Terminal: any = require('../out/Terminal').Terminal; +import { Utf8ToUtf32, stringFromCodePoint } from 'common/input/TextDecoder'; +import { Terminal } from 'Terminal'; class TestTerminal extends Terminal { - constructor(opts: any) { - super(opts); - } writeSync(data: string): void { this.writeBuffer.push(data); (this as any)._innerWrite(); diff --git a/src/benchmark-tests/tsconfig.json b/src/benchmark-tests/tsconfig.json new file mode 100644 index 0000000000..2c59a5009c --- /dev/null +++ b/src/benchmark-tests/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../tsconfig-library-base", + "compilerOptions": { + "lib": [ + "dom", + "es6", + ], + "outDir": "../../out", + "types": [ + "../../node_modules/@types/node" + ], + "baseUrl": "..", + "strict": false + }, + "include": [ + "./**/*", + "../**/*", + "../../typings/xterm.d.ts" + ], + "exclude": [ + "../**/*test.ts" + ] +} diff --git a/tsconfig.all.json b/tsconfig.all.json index d8d8d20b0e..6985b64d4f 100644 --- a/tsconfig.all.json +++ b/tsconfig.all.json @@ -8,8 +8,6 @@ { "path": "./addons/xterm-addon-fit/src" }, { "path": "./addons/xterm-addon-search/src" }, { "path": "./addons/xterm-addon-web-links/src" }, - - // currently depends on out, thus must run as last? - { "path": "./benchmark-tests" }, + { "path": "./src/benchmark-tests" }, ] } From fc7411c80756718ffb604262fcdd8a76259e7bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 9 Jun 2019 17:35:25 +0200 Subject: [PATCH 11/28] remove wrong d.ts --- src/benchmark-tests/Terminal.benchmark.d.ts | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/benchmark-tests/Terminal.benchmark.d.ts diff --git a/src/benchmark-tests/Terminal.benchmark.d.ts b/src/benchmark-tests/Terminal.benchmark.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/src/benchmark-tests/Terminal.benchmark.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; From 03839f06b8ed0b08181231060740a8bb349d867a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 9 Jun 2019 18:02:17 +0200 Subject: [PATCH 12/28] remove remnants --- src/benchmark-tests/EscapeSequenceParser.benchmark.d.ts | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/benchmark-tests/EscapeSequenceParser.benchmark.d.ts diff --git a/src/benchmark-tests/EscapeSequenceParser.benchmark.d.ts b/src/benchmark-tests/EscapeSequenceParser.benchmark.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/src/benchmark-tests/EscapeSequenceParser.benchmark.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; From e0d69db23e0d28d9568edea7a37c6ee0cfc0dec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 9 Jun 2019 21:53:24 +0200 Subject: [PATCH 13/28] better separation of benchmarks --- .gitignore | 2 +- .../EscapeSequenceParser.benchmark.ts | 0 .../Terminal.benchmark.ts | 6 ++-- benchmark.json => benchmarks/benchmark.json | 1 + benchmarks/tsconfig.json | 32 +++++++++++++++++++ package.json | 6 ++-- src/benchmark-tests/tsconfig.json | 23 ------------- src/tsconfig.json | 1 + tsconfig.all.json | 2 +- 9 files changed, 42 insertions(+), 31 deletions(-) rename {src/benchmark-tests => benchmarks}/EscapeSequenceParser.benchmark.ts (100%) rename {src/benchmark-tests => benchmarks}/Terminal.benchmark.ts (95%) rename benchmark.json => benchmarks/benchmark.json (93%) create mode 100644 benchmarks/tsconfig.json delete mode 100644 src/benchmark-tests/tsconfig.json diff --git a/.gitignore b/.gitignore index f221a5bcb5..e386a725e3 100644 --- a/.gitignore +++ b/.gitignore @@ -21,5 +21,5 @@ dist/ demo/dist/ # dont commit benchmark folders -benchmark/ +.benchmark/ timeline/ diff --git a/src/benchmark-tests/EscapeSequenceParser.benchmark.ts b/benchmarks/EscapeSequenceParser.benchmark.ts similarity index 100% rename from src/benchmark-tests/EscapeSequenceParser.benchmark.ts rename to benchmarks/EscapeSequenceParser.benchmark.ts diff --git a/src/benchmark-tests/Terminal.benchmark.ts b/benchmarks/Terminal.benchmark.ts similarity index 95% rename from src/benchmark-tests/Terminal.benchmark.ts rename to benchmarks/Terminal.benchmark.ts index a9e5bca703..996c998523 100644 --- a/src/benchmark-tests/Terminal.benchmark.ts +++ b/benchmarks/Terminal.benchmark.ts @@ -12,11 +12,11 @@ import { Terminal } from 'Terminal'; class TestTerminal extends Terminal { writeSync(data: string): void { this.writeBuffer.push(data); - (this as any)._innerWrite(); + this._innerWrite(); } writeSyncUtf8(data: Uint8Array): void { - (this as any).writeBufferUtf8.push(data); - (this as any)._innerWriteUtf8(); + this.writeBufferUtf8.push(data); + this._innerWriteUtf8(); } } diff --git a/benchmark.json b/benchmarks/benchmark.json similarity index 93% rename from benchmark.json rename to benchmarks/benchmark.json index 7d8e222333..f8b99b5565 100644 --- a/benchmark.json +++ b/benchmarks/benchmark.json @@ -1,4 +1,5 @@ { + "APP_PATH": ".benchmark", "evalConfig": { "tolerance": { "*": [0.75, 1.5], diff --git a/benchmarks/tsconfig.json b/benchmarks/tsconfig.json new file mode 100644 index 0000000000..4dcf9b650e --- /dev/null +++ b/benchmarks/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "lib": [ + "dom", + "es6", + ], + "outDir": "../out/test", + "types": [ + "../../node_modules/@types/node" + ], + "baseUrl": "..", + "strict": true, + "baseUrl": ".", + "paths": { + "common/*": [ "../src/common/*" ], + "browser/*": [ "../src/browser/*" ], + "Terminal": [ "../src/Terminal" ] + }, + }, + "include": [ + "./**/*", + "../typings/xterm.d.ts" + ], + "exclude": [ + "../**/*test.ts" + ], + "references": [ + { "path": "../src/common" }, + { "path": "../src/browser" }, + { "path": "../src" }, + ] +} diff --git a/package.json b/package.json index 52fd70018f..9cb9e1aa09 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,9 @@ "prepublishOnly": "npm run package", "watch": "tsc -b -w ./tsconfig.all.json --preserveWatchOutput", "clean": "rm -rf lib out addons/*/lib", - "benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmark.json", - "benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmark.json --baseline out/benchmark-tests/*benchmark.js", - "benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmark.json --eval out/benchmark-tests/*benchmark.js" + "benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmarks/benchmark.json", + "benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmarks/benchmark.json --baseline out/test/*benchmark.js", + "benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmarks/benchmark.json --eval out/test/*benchmark.js" }, "devDependencies": { "@types/chai": "^3.4.34", diff --git a/src/benchmark-tests/tsconfig.json b/src/benchmark-tests/tsconfig.json deleted file mode 100644 index 2c59a5009c..0000000000 --- a/src/benchmark-tests/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "extends": "../tsconfig-library-base", - "compilerOptions": { - "lib": [ - "dom", - "es6", - ], - "outDir": "../../out", - "types": [ - "../../node_modules/@types/node" - ], - "baseUrl": "..", - "strict": false - }, - "include": [ - "./**/*", - "../**/*", - "../../typings/xterm.d.ts" - ], - "exclude": [ - "../**/*test.ts" - ] -} diff --git a/src/tsconfig.json b/src/tsconfig.json index 975766683f..afaabfbb88 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -11,6 +11,7 @@ ], "rootDir": ".", "outDir": "../out", + "composite": true, "baseUrl": ".", "paths": { "common/*": [ "./common/*" ], diff --git a/tsconfig.all.json b/tsconfig.all.json index 6985b64d4f..aa368d5b70 100644 --- a/tsconfig.all.json +++ b/tsconfig.all.json @@ -4,10 +4,10 @@ "references": [ { "path": "./src" }, { "path": "./test" }, + { "path": "./benchmarks" }, { "path": "./addons/xterm-addon-attach/src" }, { "path": "./addons/xterm-addon-fit/src" }, { "path": "./addons/xterm-addon-search/src" }, { "path": "./addons/xterm-addon-web-links/src" }, - { "path": "./src/benchmark-tests" }, ] } From 1794532cb13a609331238c7a0431438f6a3b3de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 9 Jun 2019 22:08:41 +0200 Subject: [PATCH 14/28] test pipeline --- azure-pipelines.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e8b23d347e..cb04f7852b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -83,6 +83,25 @@ jobs: yarn test-api --headless displayName: 'Integration tests' +- job: BenchmarkTests + pool: + vmImage: 'ubuntu-16.04' + steps: + - task: NodeTool@0 + inputs: + versionSpec: '8.x' + displayName: 'Install Node.js' + - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 + inputs: + versionSpec: "1.9.4" + displayName: 'Install Yarn' + - script: | + yarn + displayName: 'Install dependencies and build' + - script: | + yarn benchmark-baseline + displayName: 'Benchmark tests' + - job: Release dependsOn: - Linux From b559a5a39b0c612d3c556c55d6da40f8258b346b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 9 Jun 2019 22:23:15 +0200 Subject: [PATCH 15/28] lower resources needed for test --- azure-pipelines.yml | 4 ++-- benchmarks/Terminal.benchmark.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index cb04f7852b..af4160b2f0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -83,7 +83,7 @@ jobs: yarn test-api --headless displayName: 'Integration tests' -- job: BenchmarkTests +- job: Benchmarks pool: vmImage: 'ubuntu-16.04' steps: @@ -100,7 +100,7 @@ jobs: displayName: 'Install dependencies and build' - script: | yarn benchmark-baseline - displayName: 'Benchmark tests' + displayName: 'Benchmarks' - job: Release dependsOn: diff --git a/benchmarks/Terminal.benchmark.ts b/benchmarks/Terminal.benchmark.ts index 996c998523..a0b8fd298c 100644 --- a/benchmarks/Terminal.benchmark.ts +++ b/benchmarks/Terminal.benchmark.ts @@ -20,13 +20,13 @@ class TestTerminal extends Terminal { } } -perfContext('Terminal: ls -lR /usr', () => { +perfContext('Terminal: ls -lR /usr/lib', () => { let content = ''; let contentUtf8: Uint8Array; before(async () => { // grab output from "ls -lR /usr" - const p = spawn('ls', ['--color=auto', '-lR', '/usr'], { + const p = spawn('ls', ['--color=auto', '-lR', '/usr/lib'], { name: 'xterm-256color', cols: 80, rows: 25, From e77969372bbd1e31cec3a633a6c83cd04119510f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 9 Jun 2019 23:00:11 +0200 Subject: [PATCH 16/28] setup benchmark pipeline with eval run --- azure-pipelines.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index af4160b2f0..33c3e10009 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -100,7 +100,14 @@ jobs: displayName: 'Install dependencies and build' - script: | yarn benchmark-baseline - displayName: 'Benchmarks' + displayName: 'Baseline data' + - script: | + git checkout + yarn clean && yarn + displayName: 'Checkout target' + - script: | + yarn benchmark-eval + displayName: 'Eval changes' - job: Release dependsOn: From a28761bf3ed12aa2eee1c1e0d8dc761e7aecab0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Wed, 19 Jun 2019 00:07:09 +0200 Subject: [PATCH 17/28] restructured test folder --- benchmarks/tsconfig.json | 32 ----------------- package.json | 8 ++--- src/tsconfig.json | 1 - test/{ => api}/CharWidth.api.ts | 0 test/{ => api}/InputHandler.api.ts | 0 test/{ => api}/Terminal.api.ts | 0 test/{ => api}/tsconfig.json | 6 ++-- .../EscapeSequenceParser.benchmark.ts | 0 .../benchmark}/Terminal.benchmark.ts | 0 {benchmarks => test/benchmark}/benchmark.json | 0 test/benchmark/tsconfig.json | 34 +++++++++++++++++++ tsconfig.all.json | 4 +-- 12 files changed, 43 insertions(+), 42 deletions(-) delete mode 100644 benchmarks/tsconfig.json rename test/{ => api}/CharWidth.api.ts (100%) rename test/{ => api}/InputHandler.api.ts (100%) rename test/{ => api}/Terminal.api.ts (100%) rename test/{ => api}/tsconfig.json (69%) rename {benchmarks => test/benchmark}/EscapeSequenceParser.benchmark.ts (100%) rename {benchmarks => test/benchmark}/Terminal.benchmark.ts (100%) rename {benchmarks => test/benchmark}/benchmark.json (100%) create mode 100644 test/benchmark/tsconfig.json diff --git a/benchmarks/tsconfig.json b/benchmarks/tsconfig.json deleted file mode 100644 index 4dcf9b650e..0000000000 --- a/benchmarks/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "lib": [ - "dom", - "es6", - ], - "outDir": "../out/test", - "types": [ - "../../node_modules/@types/node" - ], - "baseUrl": "..", - "strict": true, - "baseUrl": ".", - "paths": { - "common/*": [ "../src/common/*" ], - "browser/*": [ "../src/browser/*" ], - "Terminal": [ "../src/Terminal" ] - }, - }, - "include": [ - "./**/*", - "../typings/xterm.d.ts" - ], - "exclude": [ - "../**/*test.ts" - ], - "references": [ - { "path": "../src/common" }, - { "path": "../src/browser" }, - { "path": "../src" }, - ] -} diff --git a/package.json b/package.json index 5d7cb5b42b..118578aa8d 100644 --- a/package.json +++ b/package.json @@ -14,16 +14,16 @@ "lint": "tslint 'src/**/*.ts' './demo/**/*.ts' './addons/**/*.ts'", "test": "npm run test-unit", "posttest": "npm run lint", - "test-api": "mocha \"**/*.api.js\"", + "test-api": "mocha \"./out-test/api/*.api.js\"", "test-unit": "node ./bin/test.js", "build": "tsc -b ./tsconfig.all.json", "prepare": "npm run build", "prepublishOnly": "npm run package", "watch": "tsc -b -w ./tsconfig.all.json --preserveWatchOutput", "clean": "rm -rf lib out addons/*/lib", - "benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmarks/benchmark.json", - "benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmarks/benchmark.json --baseline out/test/*benchmark.js", - "benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c benchmarks/benchmark.json --eval out/test/*benchmark.js" + "benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json", + "benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark/test/benchmark/*benchmark.js", + "benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark/test/benchmark/*benchmark.js" }, "devDependencies": { "@types/chai": "^3.4.34", diff --git a/src/tsconfig.json b/src/tsconfig.json index afaabfbb88..975766683f 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -11,7 +11,6 @@ ], "rootDir": ".", "outDir": "../out", - "composite": true, "baseUrl": ".", "paths": { "common/*": [ "./common/*" ], diff --git a/test/CharWidth.api.ts b/test/api/CharWidth.api.ts similarity index 100% rename from test/CharWidth.api.ts rename to test/api/CharWidth.api.ts diff --git a/test/InputHandler.api.ts b/test/api/InputHandler.api.ts similarity index 100% rename from test/InputHandler.api.ts rename to test/api/InputHandler.api.ts diff --git a/test/Terminal.api.ts b/test/api/Terminal.api.ts similarity index 100% rename from test/Terminal.api.ts rename to test/api/Terminal.api.ts diff --git a/test/tsconfig.json b/test/api/tsconfig.json similarity index 69% rename from test/tsconfig.json rename to test/api/tsconfig.json index fce9a1baac..2bd0a92b59 100644 --- a/test/tsconfig.json +++ b/test/api/tsconfig.json @@ -5,9 +5,9 @@ "es6", ], "rootDir": ".", - "outDir": "../out/test", + "outDir": "../../out-test/api", "types": [ - "../node_modules/@types/mocha" + "../../node_modules/@types/mocha" ], "sourceMap": true, "removeComments": true, @@ -16,6 +16,6 @@ }, "include": [ "./**/*", - "../typings/xterm.d.ts" + "../../typings/xterm.d.ts" ] } diff --git a/benchmarks/EscapeSequenceParser.benchmark.ts b/test/benchmark/EscapeSequenceParser.benchmark.ts similarity index 100% rename from benchmarks/EscapeSequenceParser.benchmark.ts rename to test/benchmark/EscapeSequenceParser.benchmark.ts diff --git a/benchmarks/Terminal.benchmark.ts b/test/benchmark/Terminal.benchmark.ts similarity index 100% rename from benchmarks/Terminal.benchmark.ts rename to test/benchmark/Terminal.benchmark.ts diff --git a/benchmarks/benchmark.json b/test/benchmark/benchmark.json similarity index 100% rename from benchmarks/benchmark.json rename to test/benchmark/benchmark.json diff --git a/test/benchmark/tsconfig.json b/test/benchmark/tsconfig.json new file mode 100644 index 0000000000..8b93dcb13c --- /dev/null +++ b/test/benchmark/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "lib": [ + "dom", + "es6", + ], + "outDir": "../../out-test/benchmark", + "types": [ + "../../node_modules/@types/node" + ], + "moduleResolution": "node", + "strict": false, + "target": "es2015", + "module": "commonjs", + "baseUrl": ".", + "paths": { + "common/*": [ "../../src/common/*" ], + "browser/*": [ "../../src/browser/*" ], + "Terminal": [ "../../src/Terminal" ] + }, + }, + "include": [ + "./**/*", + "../../typings/xterm.d.ts", + "../../out/**/*" + ], + "exclude": [ + "../../**/*test.ts" + ], + "references": [ + { "path": "../../src/common" }, + { "path": "../../src/browser" }, + ] +} \ No newline at end of file diff --git a/tsconfig.all.json b/tsconfig.all.json index aa368d5b70..a6ea0e28d5 100644 --- a/tsconfig.all.json +++ b/tsconfig.all.json @@ -3,8 +3,8 @@ "include": [], "references": [ { "path": "./src" }, - { "path": "./test" }, - { "path": "./benchmarks" }, + { "path": "./test/api" }, + { "path": "./test/benchmark" }, { "path": "./addons/xterm-addon-attach/src" }, { "path": "./addons/xterm-addon-fit/src" }, { "path": "./addons/xterm-addon-search/src" }, From 1dc4e3697206e33c47e52cb83e1e0cd5fff8c400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Wed, 19 Jun 2019 00:42:20 +0200 Subject: [PATCH 18/28] fix CSI bug, cleanup test --- .../EscapeSequenceParser.benchmark.ts | 168 ++++++++++-------- 1 file changed, 92 insertions(+), 76 deletions(-) diff --git a/test/benchmark/EscapeSequenceParser.benchmark.ts b/test/benchmark/EscapeSequenceParser.benchmark.ts index 57f8329c8d..f92afc8054 100644 --- a/test/benchmark/EscapeSequenceParser.benchmark.ts +++ b/test/benchmark/EscapeSequenceParser.benchmark.ts @@ -17,16 +17,17 @@ function toUtf32(s: string): Uint32Array { return result; } +class DcsHandler implements IDcsHandler { + hook(collect: string, params: number[], flag: number) : void {} + put(data: Uint32Array, start: number, end: number) : void {} + unhook() :void {} +} + -perfContext('Parser performance - 50MB data', () => { - let content; - let taContent: Uint32Array; +perfContext('Parser throughput - 50MB data', () => { + let parsed: Uint32Array; let parser: EscapeSequenceParser; - const dcsHandler: IDcsHandler = { - hook: (collect, params, flag) => {}, - put: (data, start, end) => {}, - unhook: () => {} - }; + beforeEach(() => { parser = new EscapeSequenceParser(); parser.setPrintHandler((data, start, end) => {}); @@ -96,171 +97,186 @@ perfContext('Parser performance - 50MB data', () => { parser.setEscHandler('~', () => {}); parser.setEscHandler('%@', () => {}); parser.setEscHandler('%G', () => {}); - parser.setDcsHandler('q', dcsHandler); + parser.setDcsHandler('q', new DcsHandler()); }); - perfContext('print - a', () => { + perfContext('PRINT - a', () => { before(() => { const data = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; - content = ''; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', async () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', async () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); - perfContext('execute - \\n', () => { + perfContext('EXECUTE - \\n', () => { before(() => { const data = '\n\n\n\n\n\n\n'; - content = ''; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); - perfContext('escape - ESC E', () => { + perfContext('ESCAPE - ESC E', () => { before(() => { const data = '\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE'; - content = ''; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); - perfContext('escape with collect - ESC % G', () => { + perfContext('ESCAPE with collect - ESC % G', () => { before(() => { const data = '\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G'; - content = ''; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); - perfContext('simple csi - CSI A', () => { + perfContext('CSI - CSI A', () => { before(() => { const data = '\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A'; - content = ''; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); - perfContext('csi with collect - CSI ? p', () => { + perfContext('CSI with collect - CSI ? p', () => { before(() => { const data = '\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p'; - content = ''; + let content = ''; + while (content.length < 50000000) { + content += data; + } + parsed = toUtf32(content); + }); + new ThroughputRuntimeCase('', () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; + }, {fork: true}).showAverageThroughput(); + }); + + perfContext('CSI with params (short) - CSI 1;2 m', () => { + before(() => { + const data = '\x1b[1;2m\x1b[1;2m\x1b[1;2m\x1b[1;2m\x1b[1;2m\x1b[1;2m\x1b[1;2m\x1b[1;2m\x1b[1;2m\x1b[1;2m'; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); - perfContext('csi with params - CSI 1;2 m', () => { + perfContext('CSI with params (long) - CSI 1;2;3;4;5;6;7;8;9;0 m', () => { before(() => { - const data = '\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m'; - content = ''; + const data = '\x1b[1;2;3;4;5;6;7;8;9;0m\x1b[1;2;3;4;5;6;7;8;9;0m\x1b[1;2;3;4;5;6;7;8;9;0m'; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); - perfContext('osc (small payload) - OSC 0;hi ST', () => { + perfContext('OSC (short) - OSC 0;hi ST', () => { before(() => { const data = '\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\x1b]0;hi\x1b\\'; - content = ''; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); - perfContext('osc (big payload) - OSC 0; ST', () => { + perfContext('OSC (long) - OSC 0; ST', () => { before(() => { const data = '\x1b]0;Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\x1b\\'; - content = ''; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); - perfContext('DCS (small payload)', () => { + perfContext('DCS (short)', () => { before(() => { const data = '\x1bPq~~\x1b\\'; - content = ''; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', async () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', async () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); - perfContext('DCS (big payload)', () => { + perfContext('DCS (long)', () => { before(() => { const data = '\x1bPq#0;2;0;0;0#1;2;100;100;0#2;2;0;100;0#1~~@@vv@@~~@@~~$#2??}}GG}}??}}??-#1!14@\x1b\\'; - content = ''; + let content = ''; while (content.length < 50000000) { content += data; } - taContent = toUtf32(content); + parsed = toUtf32(content); }); - new ThroughputRuntimeCase('throughput', async () => { - parser.parse(taContent, taContent.length); - return {payloadSize: taContent.length}; + new ThroughputRuntimeCase('', async () => { + parser.parse(parsed, parsed.length); + return {payloadSize: parsed.length}; }, {fork: true}).showAverageThroughput(); }); }); From 00d4c8162d56d61e7288cbcf5f4cd0d59bb75fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 24 Jun 2019 22:53:13 +0200 Subject: [PATCH 19/28] remove azure job, change api test path --- azure-pipelines.yml | 26 -------------------------- package.json | 2 +- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 33c3e10009..e8b23d347e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -83,32 +83,6 @@ jobs: yarn test-api --headless displayName: 'Integration tests' -- job: Benchmarks - pool: - vmImage: 'ubuntu-16.04' - steps: - - task: NodeTool@0 - inputs: - versionSpec: '8.x' - displayName: 'Install Node.js' - - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 - inputs: - versionSpec: "1.9.4" - displayName: 'Install Yarn' - - script: | - yarn - displayName: 'Install dependencies and build' - - script: | - yarn benchmark-baseline - displayName: 'Baseline data' - - script: | - git checkout - yarn clean && yarn - displayName: 'Checkout target' - - script: | - yarn benchmark-eval - displayName: 'Eval changes' - - job: Release dependsOn: - Linux diff --git a/package.json b/package.json index 9e965a0f72..f26c010f02 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "lint": "tslint 'src/**/*.ts' './demo/**/*.ts' './addons/**/*.ts'", "test": "npm run test-unit", "posttest": "npm run lint", - "test-api": "mocha \"./out-test/api/*.api.js\"", + "test-api": "mocha \"**/*.api.js\"", "test-unit": "node ./bin/test.js", "build": "tsc -b ./tsconfig.all.json", "prepare": "npm run build", From 5459c48525c63e142f84e9250064738502486df3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 24 Jun 2019 20:20:08 -0700 Subject: [PATCH 20/28] Add wordSeparator to demo --- demo/client.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/demo/client.ts b/demo/client.ts index 005d171d04..e2259841f7 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -235,7 +235,8 @@ function initOptions(term: TerminalType): void { fontFamily: null, fontWeight: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], fontWeightBold: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], - rendererType: ['dom', 'canvas'] + rendererType: ['dom', 'canvas'], + wordSeparator: null }; const options = Object.keys((term)._core.options); const booleanOptions = []; From 6c8f88754bdbd146172ce255a50d878206239bb9 Mon Sep 17 00:00:00 2001 From: Vadim Zakondyrin Date: Thu, 27 Jun 2019 10:21:58 +0600 Subject: [PATCH 21/28] Include CSS into the package --- .npmignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.npmignore b/.npmignore index 856b84ab3b..13dc7b4463 100644 --- a/.npmignore +++ b/.npmignore @@ -6,6 +6,9 @@ !*.js !*.json +# Whitelist - css/ +!css/**/*.css + # Whitelist - dist/ !dist/**/*.js !dist/**/*.js.map From a96734220ae586acc848cb7719a8630157b6cd90 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 27 Jun 2019 11:31:36 -0700 Subject: [PATCH 22/28] Use TS declarationMap This will make go to definition go to the implementation instead of the .d.ts file --- src/tsconfig-library-base.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tsconfig-library-base.json b/src/tsconfig-library-base.json index 66b61f09e1..7a9eedf3d0 100644 --- a/src/tsconfig-library-base.json +++ b/src/tsconfig-library-base.json @@ -2,6 +2,7 @@ "extends": "./tsconfig-base.json", "compilerOptions": { "composite": true, - "strict": true + "strict": true, + "declarationMap": true } } From 7f4e1a7e97308a432142561803de75a311649322 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 27 Jun 2019 11:39:20 -0700 Subject: [PATCH 23/28] Add explicit blacklist entry for .d.ts.map --- .npmignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.npmignore b/.npmignore index 13dc7b4463..7ff2ec0e99 100644 --- a/.npmignore +++ b/.npmignore @@ -36,6 +36,7 @@ !typings/*.d.ts # Blacklist - (normal behavior) these will override any whitelist +*.d.ts.map *.test.ts *.test.d.ts *.test.js From 8cf5a7ee40bb525271d4830388e64393f5a48f0b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 27 Jun 2019 18:26:02 -0700 Subject: [PATCH 24/28] Git ignore out-test --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e386a725e3..64273dda93 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ node_modules/ .lock-wscript lib/ out/ +out-test/ Makefile.gyp *.Makefile *.target.gyp.mk From 10fedf4ccfc53b07e21f78df266d8a4bb7515c30 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 27 Jun 2019 18:36:44 -0700 Subject: [PATCH 25/28] Enforce underscore prefix for protected members --- .../src/renderLayer/BaseRenderLayer.ts | 22 +++++++++---------- .../src/renderLayer/CursorRenderLayer.ts | 12 +++++----- .../src/renderLayer/LinkRenderLayer.ts | 14 ++++++------ src/Linkifier.test.ts | 2 +- src/Linkifier.ts | 20 ++++++++--------- src/renderer/BaseRenderLayer.ts | 22 +++++++++---------- src/renderer/CursorRenderLayer.ts | 12 +++++----- src/renderer/LinkRenderLayer.ts | 14 ++++++------ src/renderer/SelectionRenderLayer.ts | 12 +++++----- src/renderer/TextRenderLayer.ts | 16 +++++++------- tslint.json | 4 +--- yarn.lock | 2 +- 12 files changed, 75 insertions(+), 77 deletions(-) diff --git a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts index 999d94f43c..0422440e7b 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts @@ -66,7 +66,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._ctx = this._canvas.getContext('2d', {alpha: this._alpha}); // Draw the background if this is an opaque layer if (!this._alpha) { - this.clearAll(); + this._clearAll(); } } @@ -81,7 +81,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._refreshCharAtlas(terminal, colorSet); } - protected setTransparency(terminal: Terminal, alpha: boolean): void { + protected _setTransparency(terminal: Terminal, alpha: boolean): void { // Do nothing when alpha doesn't change if (alpha === this._alpha) { return; @@ -127,7 +127,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { // Draw the background if this is an opaque layer if (!this._alpha) { - this.clearAll(); + this._clearAll(); } this._refreshCharAtlas(terminal, this._colors); @@ -142,7 +142,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param width The number of columns to fill. * @param height The number of rows to fill. */ - protected fillCells(x: number, y: number, width: number, height: number): void { + protected _fillCells(x: number, y: number, width: number, height: number): void { this._ctx.fillRect( x * this._scaledCellWidth, y * this._scaledCellHeight, @@ -156,7 +156,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param x The column to fill. * @param y The row to fill. */ - protected fillBottomLineAtCells(x: number, y: number, width: number = 1): void { + protected _fillBottomLineAtCells(x: number, y: number, width: number = 1): void { this._ctx.fillRect( x * this._scaledCellWidth, (y + 1) * this._scaledCellHeight - window.devicePixelRatio - 1 /* Ensure it's drawn within the cell */, @@ -170,7 +170,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param x The column to fill. * @param y The row to fill. */ - protected fillLeftLineAtCell(x: number, y: number): void { + protected _fillLeftLineAtCell(x: number, y: number): void { this._ctx.fillRect( x * this._scaledCellWidth, y * this._scaledCellHeight, @@ -184,7 +184,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param x The column to fill. * @param y The row to fill. */ - protected strokeRectAtCell(x: number, y: number, width: number, height: number): void { + protected _strokeRectAtCell(x: number, y: number, width: number, height: number): void { this._ctx.lineWidth = window.devicePixelRatio; this._ctx.strokeRect( x * this._scaledCellWidth + window.devicePixelRatio / 2, @@ -196,7 +196,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { /** * Clears the entire canvas. */ - protected clearAll(): void { + protected _clearAll(): void { if (this._alpha) { this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); } else { @@ -212,7 +212,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param width The number of columns to clear. * @param height The number of rows to clear. */ - protected clearCells(x: number, y: number, width: number, height: number): void { + protected _clearCells(x: number, y: number, width: number, height: number): void { if (this._alpha) { this._ctx.clearRect( x * this._scaledCellWidth, @@ -239,7 +239,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param y The row to draw at. * @param color The color of the character. */ - protected fillCharTrueColor(terminal: Terminal, cell: CellData, x: number, y: number): void { + protected _fillCharTrueColor(terminal: Terminal, cell: CellData, x: number, y: number): void { this._ctx.font = this._getFont(terminal, false, false); this._ctx.textBaseline = 'middle'; this._clipRow(terminal, y); @@ -263,7 +263,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * This is used to validate whether a cached image can be used. * @param bold Whether the text is bold. */ - protected drawChars(terminal: Terminal, cell: ICellData, x: number, y: number): void { + protected _drawChars(terminal: Terminal, cell: ICellData, x: number, y: number): void { // skip cache right away if we draw in RGB // Note: to avoid bad runtime JoinedCellData will be skipped diff --git a/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts index b0bf581f33..09abe82ae7 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts @@ -182,7 +182,7 @@ export class CursorRenderLayer extends BaseRenderLayer { private _clearCursor(): void { if (this._state) { - this.clearCells(this._state.x, this._state.y, this._state.width, 1); + this._clearCells(this._state.x, this._state.y, this._state.width, 1); this._state = { x: null, y: null, @@ -196,30 +196,30 @@ export class CursorRenderLayer extends BaseRenderLayer { private _renderBarCursor(terminal: Terminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; - this.fillLeftLineAtCell(x, y); + this._fillLeftLineAtCell(x, y); this._ctx.restore(); } private _renderBlockCursor(terminal: Terminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; - this.fillCells(x, y, cell.getWidth(), 1); + this._fillCells(x, y, cell.getWidth(), 1); this._ctx.fillStyle = this._colors.cursorAccent.css; - this.fillCharTrueColor(terminal, cell, x, y); + this._fillCharTrueColor(terminal, cell, x, y); this._ctx.restore(); } private _renderUnderlineCursor(terminal: Terminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; - this.fillBottomLineAtCells(x, y); + this._fillBottomLineAtCells(x, y); this._ctx.restore(); } private _renderBlurCursor(terminal: Terminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.strokeStyle = this._colors.cursor.css; - this.strokeRectAtCell(x, y, cell.getWidth(), 1); + this._strokeRectAtCell(x, y, cell.getWidth(), 1); this._ctx.restore(); } } diff --git a/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts index d37f264082..7c79ddcc73 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts @@ -32,12 +32,12 @@ export class LinkRenderLayer extends BaseRenderLayer { private _clearCurrentLink(): void { if (this._state) { - this.clearCells(this._state.x1, this._state.y1, this._state.cols - this._state.x1, 1); + this._clearCells(this._state.x1, this._state.y1, this._state.cols - this._state.x1, 1); const middleRowCount = this._state.y2 - this._state.y1 - 1; if (middleRowCount > 0) { - this.clearCells(0, this._state.y1 + 1, this._state.cols, middleRowCount); + this._clearCells(0, this._state.y1 + 1, this._state.cols, middleRowCount); } - this.clearCells(0, this._state.y2, this._state.x2, 1); + this._clearCells(0, this._state.y2, this._state.x2, 1); this._state = null; } } @@ -54,14 +54,14 @@ export class LinkRenderLayer extends BaseRenderLayer { if (e.y1 === e.y2) { // Single line link - this.fillBottomLineAtCells(e.x1, e.y1, e.x2 - e.x1); + this._fillBottomLineAtCells(e.x1, e.y1, e.x2 - e.x1); } else { // Multi-line link - this.fillBottomLineAtCells(e.x1, e.y1, e.cols - e.x1); + this._fillBottomLineAtCells(e.x1, e.y1, e.cols - e.x1); for (let y = e.y1 + 1; y < e.y2; y++) { - this.fillBottomLineAtCells(0, y, e.cols); + this._fillBottomLineAtCells(0, y, e.cols); } - this.fillBottomLineAtCells(0, e.y2, e.x2); + this._fillBottomLineAtCells(0, e.y2, e.x2); } this._state = e; } diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index 1ccae7fcb0..9e6588af84 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -15,7 +15,7 @@ import { CellData } from 'common/buffer/CellData'; class TestLinkifier extends Linkifier { constructor(terminal: ITerminal) { super(terminal); - (Linkifier).TIME_BEFORE_LINKIFY = 0; + Linkifier._timeBeforeLatency = 0; } public get linkMatchers(): ILinkMatcher[] { return this._linkMatchers; } diff --git a/src/Linkifier.ts b/src/Linkifier.ts index c11849ded3..ded6f87a95 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -9,6 +9,13 @@ import { MouseZone } from './MouseZoneManager'; import { getStringCellWidth } from 'common/CharWidth'; import { EventEmitter, IEvent } from 'common/EventEmitter'; +/** + * Limit of the unwrapping line expansion (overscan) at the top and bottom + * of the actual viewport in ASCII characters. + * A limit of 2000 should match most sane urls. + */ +const OVERSCAN_CHAR_LIMIT = 2000; + /** * The Linkifier applies links to rows shortly after they have been refreshed. */ @@ -18,14 +25,7 @@ export class Linkifier implements ILinkifier { * the costly operation of searching every row multiple times, potentially a * huge amount of times. */ - protected static readonly TIME_BEFORE_LINKIFY = 200; - - /** - * Limit of the unwrapping line expansion (overscan) at the top and bottom - * of the actual viewport in ASCII characters. - * A limit of 2000 should match most sane urls. - */ - protected static readonly OVERSCAN_CHAR_LIMIT = 2000; + protected static _timeBeforeLatency = 200; protected _linkMatchers: ILinkMatcher[] = []; @@ -85,7 +85,7 @@ export class Linkifier implements ILinkifier { if (this._rowsTimeoutId) { clearTimeout(this._rowsTimeoutId); } - this._rowsTimeoutId = setTimeout(() => this._linkifyRows(), Linkifier.TIME_BEFORE_LINKIFY); + this._rowsTimeoutId = setTimeout(() => this._linkifyRows(), Linkifier._timeBeforeLatency); } /** @@ -114,7 +114,7 @@ export class Linkifier implements ILinkifier { // the viewport to +OVERSCAN_CHAR_LIMIT chars (overscan) at top and bottom. // This comes with the tradeoff that matches longer than OVERSCAN_CHAR_LIMIT // chars will not match anymore at the viewport borders. - const overscanLineLimit = Math.ceil(Linkifier.OVERSCAN_CHAR_LIMIT / this._terminal.cols); + const overscanLineLimit = Math.ceil(OVERSCAN_CHAR_LIMIT / this._terminal.cols); const iterator = this._terminal.buffer.iterator( false, absoluteRowIndexStart, absoluteRowIndexEnd, overscanLineLimit, overscanLineLimit); while (iterator.hasNext()) { diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index b47434e2fc..767ef08c08 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -66,7 +66,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._ctx = this._canvas.getContext('2d', {alpha: this._alpha}); // Draw the background if this is an opaque layer if (!this._alpha) { - this.clearAll(); + this._clearAll(); } } @@ -81,7 +81,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._refreshCharAtlas(terminal, colorSet); } - protected setTransparency(terminal: ITerminal, alpha: boolean): void { + protected _setTransparency(terminal: ITerminal, alpha: boolean): void { // Do nothing when alpha doesn't change if (alpha === this._alpha) { return; @@ -127,7 +127,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { // Draw the background if this is an opaque layer if (!this._alpha) { - this.clearAll(); + this._clearAll(); } this._refreshCharAtlas(terminal, this._colors); @@ -142,7 +142,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param width The number of columns to fill. * @param height The number of rows to fill. */ - protected fillCells(x: number, y: number, width: number, height: number): void { + protected _fillCells(x: number, y: number, width: number, height: number): void { this._ctx.fillRect( x * this._scaledCellWidth, y * this._scaledCellHeight, @@ -156,7 +156,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param x The column to fill. * @param y The row to fill. */ - protected fillBottomLineAtCells(x: number, y: number, width: number = 1): void { + protected _fillBottomLineAtCells(x: number, y: number, width: number = 1): void { this._ctx.fillRect( x * this._scaledCellWidth, (y + 1) * this._scaledCellHeight - window.devicePixelRatio - 1 /* Ensure it's drawn within the cell */, @@ -170,7 +170,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param x The column to fill. * @param y The row to fill. */ - protected fillLeftLineAtCell(x: number, y: number): void { + protected _fillLeftLineAtCell(x: number, y: number): void { this._ctx.fillRect( x * this._scaledCellWidth, y * this._scaledCellHeight, @@ -184,7 +184,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param x The column to fill. * @param y The row to fill. */ - protected strokeRectAtCell(x: number, y: number, width: number, height: number): void { + protected _strokeRectAtCell(x: number, y: number, width: number, height: number): void { this._ctx.lineWidth = window.devicePixelRatio; this._ctx.strokeRect( x * this._scaledCellWidth + window.devicePixelRatio / 2, @@ -196,7 +196,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { /** * Clears the entire canvas. */ - protected clearAll(): void { + protected _clearAll(): void { if (this._alpha) { this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); } else { @@ -212,7 +212,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param width The number of columns to clear. * @param height The number of rows to clear. */ - protected clearCells(x: number, y: number, width: number, height: number): void { + protected _clearCells(x: number, y: number, width: number, height: number): void { if (this._alpha) { this._ctx.clearRect( x * this._scaledCellWidth, @@ -239,7 +239,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param y The row to draw at. * @param color The color of the character. */ - protected fillCharTrueColor(terminal: ITerminal, cell: CellData, x: number, y: number): void { + protected _fillCharTrueColor(terminal: ITerminal, cell: CellData, x: number, y: number): void { this._ctx.font = this._getFont(terminal, false, false); this._ctx.textBaseline = 'middle'; this._clipRow(terminal, y); @@ -263,7 +263,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * This is used to validate whether a cached image can be used. * @param bold Whether the text is bold. */ - protected drawChars(terminal: ITerminal, cell: ICellData, x: number, y: number): void { + protected _drawChars(terminal: ITerminal, cell: ICellData, x: number, y: number): void { // skip cache right away if we draw in RGB // Note: to avoid bad runtime JoinedCellData will be skipped diff --git a/src/renderer/CursorRenderLayer.ts b/src/renderer/CursorRenderLayer.ts index b2d856d1c8..b0e43fdce6 100644 --- a/src/renderer/CursorRenderLayer.ts +++ b/src/renderer/CursorRenderLayer.ts @@ -180,7 +180,7 @@ export class CursorRenderLayer extends BaseRenderLayer { private _clearCursor(): void { if (this._state) { - this.clearCells(this._state.x, this._state.y, this._state.width, 1); + this._clearCells(this._state.x, this._state.y, this._state.width, 1); this._state = { x: null, y: null, @@ -194,30 +194,30 @@ export class CursorRenderLayer extends BaseRenderLayer { private _renderBarCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; - this.fillLeftLineAtCell(x, y); + this._fillLeftLineAtCell(x, y); this._ctx.restore(); } private _renderBlockCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; - this.fillCells(x, y, cell.getWidth(), 1); + this._fillCells(x, y, cell.getWidth(), 1); this._ctx.fillStyle = this._colors.cursorAccent.css; - this.fillCharTrueColor(terminal, cell, x, y); + this._fillCharTrueColor(terminal, cell, x, y); this._ctx.restore(); } private _renderUnderlineCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; - this.fillBottomLineAtCells(x, y); + this._fillBottomLineAtCells(x, y); this._ctx.restore(); } private _renderBlurCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.strokeStyle = this._colors.cursor.css; - this.strokeRectAtCell(x, y, cell.getWidth(), 1); + this._strokeRectAtCell(x, y, cell.getWidth(), 1); this._ctx.restore(); } } diff --git a/src/renderer/LinkRenderLayer.ts b/src/renderer/LinkRenderLayer.ts index 8c6976d79c..f32b5ad93f 100644 --- a/src/renderer/LinkRenderLayer.ts +++ b/src/renderer/LinkRenderLayer.ts @@ -31,12 +31,12 @@ export class LinkRenderLayer extends BaseRenderLayer { private _clearCurrentLink(): void { if (this._state) { - this.clearCells(this._state.x1, this._state.y1, this._state.cols - this._state.x1, 1); + this._clearCells(this._state.x1, this._state.y1, this._state.cols - this._state.x1, 1); const middleRowCount = this._state.y2 - this._state.y1 - 1; if (middleRowCount > 0) { - this.clearCells(0, this._state.y1 + 1, this._state.cols, middleRowCount); + this._clearCells(0, this._state.y1 + 1, this._state.cols, middleRowCount); } - this.clearCells(0, this._state.y2, this._state.x2, 1); + this._clearCells(0, this._state.y2, this._state.x2, 1); this._state = null; } } @@ -53,14 +53,14 @@ export class LinkRenderLayer extends BaseRenderLayer { if (e.y1 === e.y2) { // Single line link - this.fillBottomLineAtCells(e.x1, e.y1, e.x2 - e.x1); + this._fillBottomLineAtCells(e.x1, e.y1, e.x2 - e.x1); } else { // Multi-line link - this.fillBottomLineAtCells(e.x1, e.y1, e.cols - e.x1); + this._fillBottomLineAtCells(e.x1, e.y1, e.cols - e.x1); for (let y = e.y1 + 1; y < e.y2; y++) { - this.fillBottomLineAtCells(0, y, e.cols); + this._fillBottomLineAtCells(0, y, e.cols); } - this.fillBottomLineAtCells(0, e.y2, e.x2); + this._fillBottomLineAtCells(0, e.y2, e.x2); } this._state = e; } diff --git a/src/renderer/SelectionRenderLayer.ts b/src/renderer/SelectionRenderLayer.ts index 7c297fd830..20b86a3f4f 100644 --- a/src/renderer/SelectionRenderLayer.ts +++ b/src/renderer/SelectionRenderLayer.ts @@ -41,7 +41,7 @@ export class SelectionRenderLayer extends BaseRenderLayer { public reset(terminal: ITerminal): void { if (this._state.start && this._state.end) { this._clearState(); - this.clearAll(); + this._clearAll(); } } @@ -52,7 +52,7 @@ export class SelectionRenderLayer extends BaseRenderLayer { } // Remove all selections - this.clearAll(); + this._clearAll(); // Selection does not exist if (!start || !end) { @@ -77,22 +77,22 @@ export class SelectionRenderLayer extends BaseRenderLayer { const startCol = start[0]; const width = end[0] - startCol; const height = viewportCappedEndRow - viewportCappedStartRow + 1; - this.fillCells(startCol, viewportCappedStartRow, width, height); + this._fillCells(startCol, viewportCappedStartRow, width, height); } else { // Draw first row const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0; const startRowEndCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : terminal.cols; - this.fillCells(startCol, viewportCappedStartRow, startRowEndCol - startCol, 1); + this._fillCells(startCol, viewportCappedStartRow, startRowEndCol - startCol, 1); // Draw middle rows const middleRowsCount = Math.max(viewportCappedEndRow - viewportCappedStartRow - 1, 0); - this.fillCells(0, viewportCappedStartRow + 1, terminal.cols, middleRowsCount); + this._fillCells(0, viewportCappedStartRow + 1, terminal.cols, middleRowsCount); // Draw final row if (viewportCappedStartRow !== viewportCappedEndRow) { // Only draw viewportEndRow if it's not the same as viewportStartRow const endCol = viewportEndRow === viewportCappedEndRow ? end[0] : terminal.cols; - this.fillCells(0, viewportCappedEndRow, endCol, 1); + this._fillCells(0, viewportCappedEndRow, endCol, 1); } } diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 96678a5d2b..03e5c11246 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -52,7 +52,7 @@ export class TextRenderLayer extends BaseRenderLayer { public reset(terminal: ITerminal): void { this._state.clear(); - this.clearAll(); + this._clearAll(); } private _forEachCell( @@ -179,13 +179,13 @@ export class TextRenderLayer extends BaseRenderLayer { } if (y !== startY) { // our row changed, draw the previous row ctx.fillStyle = prevFillStyle; - this.fillCells(startX, startY, cols - startX, 1); + this._fillCells(startX, startY, cols - startX, 1); startX = x; startY = y; } else if (prevFillStyle !== nextFillStyle) { // our color changed, draw the previous characters in this row ctx.fillStyle = prevFillStyle; - this.fillCells(startX, startY, x - startX, 1); + this._fillCells(startX, startY, x - startX, 1); startX = x; startY = y; } @@ -196,7 +196,7 @@ export class TextRenderLayer extends BaseRenderLayer { // flush the last color we encountered if (prevFillStyle !== null) { ctx.fillStyle = prevFillStyle; - this.fillCells(startX, startY, cols - startX, 1); + this._fillCells(startX, startY, cols - startX, 1); } ctx.restore(); @@ -207,7 +207,7 @@ export class TextRenderLayer extends BaseRenderLayer { if (cell.isInvisible()) { return; } - this.drawChars(terminal, cell, x, y); + this._drawChars(terminal, cell, x, y); if (cell.isUnderline()) { this._ctx.save(); @@ -233,7 +233,7 @@ export class TextRenderLayer extends BaseRenderLayer { } } - this.fillBottomLineAtCells(x, y, cell.getWidth()); + this._fillBottomLineAtCells(x, y, cell.getWidth()); this._ctx.restore(); } }); @@ -249,13 +249,13 @@ export class TextRenderLayer extends BaseRenderLayer { this._charAtlas.beginFrame(); } - this.clearCells(0, firstRow, terminal.cols, lastRow - firstRow + 1); + this._clearCells(0, firstRow, terminal.cols, lastRow - firstRow + 1); this._drawBackground(terminal, firstRow, lastRow); this._drawForeground(terminal, firstRow, lastRow); } public onOptionsChanged(terminal: ITerminal): void { - this.setTransparency(terminal, terminal.options.allowTransparency); + this._setTransparency(terminal, terminal.options.allowTransparency); } /** diff --git a/tslint.json b/tslint.json index f6f1f46c6f..a18111bfde 100644 --- a/tslint.json +++ b/tslint.json @@ -96,9 +96,7 @@ {"type": "type", "format": "PascalCase"}, {"type": "class", "format": "PascalCase"}, {"type": "property", "modifiers": ["const"], "format": ["camelCase", "UPPER_CASE"]}, - {"type": "member", "modifiers": ["protected"], "format": "camelCase", "leadingUnderscore": "allow"}, - // TODO: Change allow to require when there aren't many PRs out - // {"type": "member", "modifiers": ["protected"], "format": "camelCase", "leadingUnderscore": "require"}, + {"type": "member", "modifiers": ["protected"], "format": "camelCase", "leadingUnderscore": "require"}, {"type": "member", "modifiers": ["private"], "format": "camelCase", "leadingUnderscore": "require"}, {"type": "variable", "modifiers": ["const"], "format": ["camelCase", "UPPER_CASE"]}, {"type": "interface", "prefix": "I"} diff --git a/yarn.lock b/yarn.lock index 9a7bfe1ec5..1ac3af130f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2537,7 +2537,7 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.13.1, js-yaml@^3.13.1: +js-yaml@3.13.1, js-yaml@^3.13.1, js-yaml@^3.7.0: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== From d8099f7fe99a34f20317aec92d9dacb600edf999 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 28 Jun 2019 12:46:57 -0700 Subject: [PATCH 26/28] Lower z-indexes Canvas layers: 0-4 Helpers: 5 A11y tree: 10 Fixes #2275 --- css/xterm.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/css/xterm.css b/css/xterm.css index 5448b5a5ab..b3d8d4f210 100644 --- a/css/xterm.css +++ b/css/xterm.css @@ -55,7 +55,7 @@ * The z-index of the helpers must be higher than the canvases in order for * IMEs to appear on top. */ - z-index: 10; + z-index: 5; } .xterm .xterm-helper-textarea { @@ -69,7 +69,7 @@ top: 0; width: 0; height: 0; - z-index: -10; + z-index: -5; /** Prevent wrapping so the IME appears against the textarea at the correct position */ white-space: nowrap; overflow: hidden; @@ -150,7 +150,7 @@ top: 0; bottom: 0; right: 0; - z-index: 100; + z-index: 10; color: transparent; } From b4886df7967bd338b95aa10ee5eafd4270d68506 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 28 Jun 2019 16:42:42 -0700 Subject: [PATCH 27/28] Guard integer only APIs when floats are used Fixes #2261 --- src/public/Terminal.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/public/Terminal.ts b/src/public/Terminal.ts index 4a19db9f1f..646d44a2de 100644 --- a/src/public/Terminal.ts +++ b/src/public/Terminal.ts @@ -44,6 +44,7 @@ export class Terminal implements ITerminalApi { this._core.focus(); } public resize(columns: number, rows: number): void { + this._verifyIntegers(columns, rows); this._core.resize(columns, rows); } public writeln(data: string): void { @@ -74,12 +75,14 @@ export class Terminal implements ITerminalApi { this._core.deregisterCharacterJoiner(joinerId); } public addMarker(cursorYOffset: number): IMarker { + this._verifyIntegers(cursorYOffset); return this._core.addMarker(cursorYOffset); } public hasSelection(): boolean { return this._core.hasSelection(); } public select(column: number, row: number, length: number): void { + this._verifyIntegers(column, row, length); this._core.select(column, row, length); } public getSelection(): string { @@ -95,6 +98,7 @@ export class Terminal implements ITerminalApi { this._core.selectAll(); } public selectLines(start: number, end: number): void { + this._verifyIntegers(start, end); this._core.selectLines(start, end); } public dispose(): void { @@ -102,9 +106,11 @@ export class Terminal implements ITerminalApi { this._core.dispose(); } public scrollLines(amount: number): void { + this._verifyIntegers(amount); this._core.scrollLines(amount); } public scrollPages(pageCount: number): void { + this._verifyIntegers(pageCount); this._core.scrollPages(pageCount); } public scrollToTop(): void { @@ -114,6 +120,7 @@ export class Terminal implements ITerminalApi { this._core.scrollToBottom(); } public scrollToLine(line: number): void { + this._verifyIntegers(line); this._core.scrollToLine(line); } public clear(): void { @@ -149,6 +156,7 @@ export class Terminal implements ITerminalApi { this._core.optionsService.setOption(key, value); } public refresh(start: number, end: number): void { + this._verifyIntegers(start, end); this._core.refresh(start, end); } public reset(): void { @@ -163,6 +171,14 @@ export class Terminal implements ITerminalApi { public static get strings(): ILocalizableStrings { return Strings; } + + private _verifyIntegers(...values: number[]): void { + values.forEach(value => { + if (value % 1 !== 0) { + throw new Error('This API does not accept floating point numbers'); + } + }); + } } class BufferApiView implements IBufferApi { From f9e83341418d88ab5b3c9247f57f76ca4aeb8bff Mon Sep 17 00:00:00 2001 From: Max Risuhin Date: Sat, 29 Jun 2019 15:21:37 +0300 Subject: [PATCH 28/28] Reset isWrapped line flag. --- src/WindowsMode.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/WindowsMode.ts b/src/WindowsMode.ts index 33b4972b21..0838cae20e 100644 --- a/src/WindowsMode.ts +++ b/src/WindowsMode.ts @@ -22,9 +22,7 @@ export function applyWindowsMode(terminal: ITerminal): IDisposable { const line = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y - 1); const lastChar = line.get(terminal.cols - 1); - if (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE) { - const nextLine = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y); - nextLine.isWrapped = true; - } + const nextLine = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y); + nextLine.isWrapped = (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE); }); }