matrix-rain
Advanced tools
+39
| module.exports = { | ||
| env: { | ||
| node: true, | ||
| es6: true, | ||
| }, | ||
| extends: `eslint:recommended`, | ||
| parserOptions: { | ||
| ecmaVersion: 2018, | ||
| sourceType: `module`, | ||
| }, | ||
| rules: { | ||
| 'no-debugger': [`warn`], | ||
| 'arrow-parens': [`error`, `as-needed`], | ||
| 'camelcase': [`error`, {'properties': `always`}], | ||
| 'comma-dangle': [`error`, `always-multiline`], | ||
| 'comma-spacing': [`error`, {'before': false, 'after': true}], | ||
| 'eol-last': [`error`], | ||
| 'eqeqeq': [`error`], | ||
| 'indent': [`error`, 2], | ||
| 'key-spacing': ['error', {beforeColon: false, afterColon: true, mode: `minimum`}], | ||
| 'keyword-spacing': [`error`], | ||
| 'linebreak-style': [`error`, `unix`], | ||
| 'no-multi-spaces': ['error'], | ||
| 'no-console': ['off'], | ||
| 'no-trailing-spaces': [`error`], | ||
| 'no-unused-expressions': [`warn`], | ||
| 'no-unused-vars': [`error`], | ||
| 'no-use-before-define': [`error`, {classes: false}], | ||
| 'object-curly-spacing': [`error`, `never`], | ||
| 'object-shorthand': [`error`, `always`], | ||
| 'quotes': [`error`, `backtick`], | ||
| 'semi': [`error`, `always`], | ||
| 'space-before-blocks': [`error`, `always`], | ||
| 'space-before-function-paren': [`error`, {anonymous: `never`, named: `never`, asyncArrow: `always`}] | ||
| }, | ||
| }; |
+38
| const ctlEsc = `\x1b[`; | ||
| const ansi = { | ||
| reset: () => `${ctlEsc}c`, | ||
| clearScreen: () => `${ctlEsc}2J`, | ||
| cursorHome: () => `${ctlEsc}H`, | ||
| cursorPos: (row, col) => `${ctlEsc}${row};${col}H`, | ||
| cursorVisible: () => `${ctlEsc}?25h`, | ||
| cursorInvisible: () => `${ctlEsc}?25l`, | ||
| useAltBuffer: () => `${ctlEsc}?47h`, | ||
| useNormalBuffer: () => `${ctlEsc}?47l`, | ||
| underline: () => `${ctlEsc}4m`, | ||
| off: () => `${ctlEsc}0m`, | ||
| bold: () => `${ctlEsc}1m`, | ||
| color: c => `${ctlEsc}${c};1m`, | ||
| colors: { | ||
| fgRgb: (r, g, b) => `${ctlEsc}38;2;${r};${g};${b}m`, | ||
| bgRgb: (r, g, b) => `${ctlEsc}48;2;${r};${g};${b}m`, | ||
| fgBlack: () => ansi.color(`30`), | ||
| fgRed: () => ansi.color(`31`), | ||
| fgGreen: () => ansi.color(`32`), | ||
| fgYellow: () => ansi.color(`33`), | ||
| fgBlue: () => ansi.color(`34`), | ||
| fgMagenta: () => ansi.color(`35`), | ||
| fgCyan: () => ansi.color(`36`), | ||
| fgWhite: () => ansi.color(`37`), | ||
| bgBlack: () => ansi.color(`40`), | ||
| bgRed: () => ansi.color(`41`), | ||
| bgGreen: () => ansi.color(`42`), | ||
| bgYellow: () => ansi.color(`43`), | ||
| bgBlue: () => ansi.color(`44`), | ||
| bgMagenta: () => ansi.color(`45`), | ||
| bgCyan: () => ansi.color(`46`), | ||
| bgWhite: () => ansi.color(`47`), | ||
| }, | ||
| }; | ||
| module.exports = ansi; |
+213
| #!/usr/bin/env node | ||
| const fs = require(`fs`); | ||
| const ArgumentParser = require(`argparse`).ArgumentParser; | ||
| const ansi = require(`./ansi`); | ||
| const argParser = new ArgumentParser({ | ||
| version: `2.0.0`, | ||
| description: `The famous Matrix rain effect of falling green characters as a cli command`, | ||
| }); | ||
| [ | ||
| { | ||
| flags: [ `-d`, `--direction` ], | ||
| opts: { | ||
| choices: [`h`, `v`], | ||
| defaultValue: `v`, | ||
| help: `Change direction of rain. h=horizontal, v=vertical`, | ||
| }, | ||
| }, | ||
| { | ||
| flags: [ `-c`, `--color` ], | ||
| opts: { | ||
| choices: [`green`, `red`, `blue`, `yellow`, `magenta`, `cyan`, `white`], | ||
| defaultValue: `green`, | ||
| dest: `color`, | ||
| help: `Rain color. NOTE: droplet start is always white`, | ||
| }, | ||
| }, | ||
| { | ||
| flags: [ `-k`, `--char-range` ], | ||
| opts: { | ||
| choices: [`ascii`, `binary`, `braille`, `emoji`, `kanji`], | ||
| defaultValue: `ascii`, | ||
| dest: `charRange`, | ||
| help: `Use rain characters from char-range`, | ||
| }, | ||
| }, | ||
| { | ||
| flags: [ `-f`, `--file-path` ], | ||
| opts: { | ||
| dest: `filePath`, | ||
| help: `Read characters from a file instead of random characters from char-range`, | ||
| }, | ||
| }, | ||
| ].forEach(({flags, opts}) => argParser.addArgument(flags, opts)); | ||
| // Simple string stream buffer + stdout flush at once | ||
| let outBuffer = []; | ||
| function write(chars) { | ||
| return outBuffer.push(chars); | ||
| } | ||
| function flush() { | ||
| process.stdout.write(outBuffer.join(``)); | ||
| return outBuffer = []; | ||
| } | ||
| function rand(start, end) { | ||
| return start + Math.floor(Math.random() * (end - start)); | ||
| } | ||
| class MatrixRain { | ||
| constructor(opts) { | ||
| this.transpose = opts.direction === `h`; | ||
| this.color = opts.color; | ||
| this.charRange = opts.charRange; | ||
| this.maxSpeed = 20; | ||
| this.colDroplets = []; | ||
| this.numCols = 0; | ||
| this.numRows = 0; | ||
| // handle reading from file | ||
| if (opts.filePath) { | ||
| if (!fs.existsSync(opts.filePath)) { | ||
| throw new Error(`${opts.filePath} doesn't exist`); | ||
| } | ||
| this.fileChars = fs.readFileSync(opts.filePath, `utf-8`).trim().split(``); | ||
| this.filePos = 0; | ||
| this.charRange = `file`; | ||
| } | ||
| } | ||
| generateChars(len, charRange) { | ||
| // by default charRange == ascii | ||
| let chars = new Array(len); | ||
| if (charRange === `ascii`) { | ||
| for (let i = 0; i < len; i++) { | ||
| chars[i] = String.fromCharCode(rand(0x21, 0x7E)); | ||
| } | ||
| } else if (charRange === `braille`) { | ||
| for (let i = 0; i < len; i++) { | ||
| chars[i] = String.fromCharCode(rand(0x2840, 0x28ff)); | ||
| } | ||
| } else if (charRange === `kanji`) { | ||
| for (let i = 0; i < len; i++) { | ||
| chars[i] = String.fromCharCode(rand(0x30a0, 0x30ff)); | ||
| } | ||
| } else if (charRange === `emoji`) { | ||
| // emojis are two character widths, so use a prefix | ||
| const emojiPrefix = String.fromCharCode(0xd83d); | ||
| for (let i = 0; i < len; i++) { | ||
| chars[i] = emojiPrefix + String.fromCharCode(rand(0xde01, 0xde4a)); | ||
| } | ||
| } else if (charRange === `file`) { | ||
| for (let i = 0; i < len; i++, this.filePos++) { | ||
| this.filePos = this.filePos < this.fileChars.length ? this.filePos : 0; | ||
| chars[i] = this.fileChars[this.filePos]; | ||
| } | ||
| } | ||
| return chars; | ||
| } | ||
| makeDroplet(col) { | ||
| return { | ||
| col, | ||
| alive: 0, | ||
| curRow: rand(0, this.numRows), | ||
| height: rand(this.numRows / 2, this.numRows), | ||
| speed: rand(1, this.maxSpeed), | ||
| chars: this.generateChars(this.numRows, this.charRange), | ||
| }; | ||
| } | ||
| resizeDroplets() { | ||
| [this.numCols, this.numRows] = process.stdout.getWindowSize(); | ||
| // transpose for direction | ||
| if (this.transpose) { | ||
| [this.numCols, this.numRows] = [this.numRows, this.numCols]; | ||
| } | ||
| // Create droplets per column | ||
| // add/remove droplets to match column size | ||
| if (this.numCols > this.colDroplets.length) { | ||
| for (let col = this.colDroplets.length; col < this.numCols; ++col) { | ||
| // make two droplets per row that start in random positions | ||
| this.colDroplets.push([this.makeDroplet(col), this.makeDroplet(col)]); | ||
| } | ||
| } else { | ||
| this.colDroplets.splice(this.numCols, this.colDroplets.length - this.numCols); | ||
| } | ||
| } | ||
| writeAt(row, col, str, color) { | ||
| // Only output if in viewport | ||
| if (row >=0 && row < this.numRows && col >=0 && col < this.numCols) { | ||
| const pos = this.transpose ? ansi.cursorPos(col, row) : ansi.cursorPos(row, col); | ||
| write(`${pos}${color || ``}${str || ``}`); | ||
| } | ||
| } | ||
| renderFrame() { | ||
| const ansiColor = ansi.colors[`fg${this.color.charAt(0).toUpperCase()}${this.color.substr(1)}`](); | ||
| for (const droplets of this.colDroplets) { | ||
| for (const droplet of droplets) { | ||
| const {curRow, col: curCol, height} = droplet; | ||
| droplet.alive++; | ||
| if (droplet.alive % droplet.speed === 0) { | ||
| this.writeAt(curRow - 1, curCol, droplet.chars[curRow - 1], ansiColor); | ||
| this.writeAt(curRow, curCol, droplet.chars[curRow], ansi.colors.fgWhite()); | ||
| this.writeAt(curRow - height, curCol, ` `); | ||
| droplet.curRow++; | ||
| } | ||
| if (curRow - height > this.numRows) { | ||
| // reset droplet | ||
| Object.assign(droplet, this.makeDroplet(droplet.col), {curRow: 0}); | ||
| } | ||
| } | ||
| } | ||
| flush(); | ||
| } | ||
| } | ||
| //// main //// | ||
| const args = argParser.parseArgs(); | ||
| const matrixRain = new MatrixRain(args); | ||
| function start() { | ||
| // clear terminal and use alt buffer | ||
| process.stdin.setRawMode(true); | ||
| write(ansi.useAltBuffer()); | ||
| write(ansi.cursorInvisible()); | ||
| write(ansi.colors.bgBlack()); | ||
| write(ansi.clearScreen()); | ||
| flush(); | ||
| matrixRain.resizeDroplets(); | ||
| } | ||
| function stop() { | ||
| write(ansi.cursorVisible()); | ||
| write(ansi.cursorHome()); | ||
| write(ansi.useNormalBuffer()); | ||
| flush(); | ||
| process.exit(); | ||
| } | ||
| process.on(`SIGINT`, () => stop()); | ||
| process.stdin.on(`data`, () => stop()); | ||
| process.stdout.on(`resize`, () => matrixRain.resizeDroplets()); | ||
| setInterval(() => matrixRain.renderFrame(), 16); // 60FPS | ||
| start(); |
+760
| # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. | ||
| # 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" | ||
| acorn-jsx@^5.0.0: | ||
| version "5.0.1" | ||
| resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" | ||
| integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== | ||
| acorn@^6.0.2: | ||
| version "6.0.4" | ||
| resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" | ||
| integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== | ||
| ajv@^6.5.3: | ||
| version "6.5.5" | ||
| resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" | ||
| integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== | ||
| dependencies: | ||
| fast-deep-equal "^2.0.1" | ||
| fast-json-stable-stringify "^2.0.0" | ||
| json-schema-traverse "^0.4.1" | ||
| uri-js "^4.2.2" | ||
| ansi-escapes@^3.0.0: | ||
| version "3.1.0" | ||
| resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" | ||
| integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== | ||
| ansi-regex@^3.0.0: | ||
| version "3.0.0" | ||
| resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" | ||
| integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= | ||
| ansi-styles@^3.2.1: | ||
| version "3.2.1" | ||
| resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" | ||
| integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== | ||
| dependencies: | ||
| color-convert "^1.9.0" | ||
| argparse@1.0.10, argparse@^1.0.7: | ||
| version "1.0.10" | ||
| resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" | ||
| integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== | ||
| dependencies: | ||
| sprintf-js "~1.0.2" | ||
| balanced-match@^1.0.0: | ||
| version "1.0.0" | ||
| resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" | ||
| integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= | ||
| brace-expansion@^1.1.7: | ||
| version "1.1.11" | ||
| resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" | ||
| integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== | ||
| dependencies: | ||
| balanced-match "^1.0.0" | ||
| concat-map "0.0.1" | ||
| caller-path@^0.1.0: | ||
| version "0.1.0" | ||
| resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" | ||
| integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= | ||
| dependencies: | ||
| callsites "^0.2.0" | ||
| callsites@^0.2.0: | ||
| version "0.2.0" | ||
| resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" | ||
| integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= | ||
| chalk@^2.0.0, chalk@^2.1.0: | ||
| version "2.4.1" | ||
| resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" | ||
| integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== | ||
| dependencies: | ||
| ansi-styles "^3.2.1" | ||
| escape-string-regexp "^1.0.5" | ||
| supports-color "^5.3.0" | ||
| chardet@^0.7.0: | ||
| version "0.7.0" | ||
| resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" | ||
| integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== | ||
| circular-json@^0.3.1: | ||
| version "0.3.3" | ||
| resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" | ||
| integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== | ||
| cli-cursor@^2.1.0: | ||
| version "2.1.0" | ||
| resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" | ||
| integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= | ||
| dependencies: | ||
| restore-cursor "^2.0.0" | ||
| cli-width@^2.0.0: | ||
| version "2.2.0" | ||
| resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" | ||
| integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= | ||
| color-convert@^1.9.0: | ||
| version "1.9.3" | ||
| resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" | ||
| integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== | ||
| dependencies: | ||
| color-name "1.1.3" | ||
| 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= | ||
| concat-map@0.0.1: | ||
| version "0.0.1" | ||
| resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" | ||
| integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= | ||
| cross-spawn@^6.0.5: | ||
| version "6.0.5" | ||
| resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" | ||
| integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== | ||
| dependencies: | ||
| nice-try "^1.0.4" | ||
| path-key "^2.0.1" | ||
| semver "^5.5.0" | ||
| shebang-command "^1.2.0" | ||
| which "^1.2.9" | ||
| debug@^4.0.1: | ||
| version "4.1.0" | ||
| resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" | ||
| integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== | ||
| dependencies: | ||
| ms "^2.1.1" | ||
| deep-is@~0.1.3: | ||
| version "0.1.3" | ||
| resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" | ||
| integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= | ||
| doctrine@^2.1.0: | ||
| version "2.1.0" | ||
| resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" | ||
| integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== | ||
| dependencies: | ||
| esutils "^2.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" | ||
| integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= | ||
| eslint-scope@^4.0.0: | ||
| version "4.0.0" | ||
| resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" | ||
| integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== | ||
| dependencies: | ||
| esrecurse "^4.1.0" | ||
| estraverse "^4.1.1" | ||
| eslint-utils@^1.3.1: | ||
| version "1.3.1" | ||
| resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" | ||
| integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== | ||
| eslint-visitor-keys@^1.0.0: | ||
| version "1.0.0" | ||
| resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" | ||
| integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== | ||
| eslint@^5.9.0: | ||
| version "5.9.0" | ||
| resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" | ||
| integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w== | ||
| dependencies: | ||
| "@babel/code-frame" "^7.0.0" | ||
| ajv "^6.5.3" | ||
| chalk "^2.1.0" | ||
| cross-spawn "^6.0.5" | ||
| debug "^4.0.1" | ||
| doctrine "^2.1.0" | ||
| eslint-scope "^4.0.0" | ||
| eslint-utils "^1.3.1" | ||
| eslint-visitor-keys "^1.0.0" | ||
| espree "^4.0.0" | ||
| esquery "^1.0.1" | ||
| esutils "^2.0.2" | ||
| file-entry-cache "^2.0.0" | ||
| functional-red-black-tree "^1.0.1" | ||
| glob "^7.1.2" | ||
| globals "^11.7.0" | ||
| ignore "^4.0.6" | ||
| imurmurhash "^0.1.4" | ||
| inquirer "^6.1.0" | ||
| is-resolvable "^1.1.0" | ||
| js-yaml "^3.12.0" | ||
| json-stable-stringify-without-jsonify "^1.0.1" | ||
| levn "^0.3.0" | ||
| lodash "^4.17.5" | ||
| minimatch "^3.0.4" | ||
| mkdirp "^0.5.1" | ||
| natural-compare "^1.4.0" | ||
| optionator "^0.8.2" | ||
| path-is-inside "^1.0.2" | ||
| pluralize "^7.0.0" | ||
| progress "^2.0.0" | ||
| regexpp "^2.0.1" | ||
| require-uncached "^1.0.3" | ||
| semver "^5.5.1" | ||
| strip-ansi "^4.0.0" | ||
| strip-json-comments "^2.0.1" | ||
| table "^5.0.2" | ||
| text-table "^0.2.0" | ||
| espree@^4.0.0: | ||
| version "4.1.0" | ||
| resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" | ||
| integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== | ||
| dependencies: | ||
| acorn "^6.0.2" | ||
| acorn-jsx "^5.0.0" | ||
| eslint-visitor-keys "^1.0.0" | ||
| esprima@^4.0.0: | ||
| version "4.0.1" | ||
| resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" | ||
| integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== | ||
| esquery@^1.0.1: | ||
| version "1.0.1" | ||
| resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" | ||
| integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== | ||
| dependencies: | ||
| estraverse "^4.0.0" | ||
| esrecurse@^4.1.0: | ||
| version "4.2.1" | ||
| resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" | ||
| integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== | ||
| dependencies: | ||
| estraverse "^4.1.0" | ||
| estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: | ||
| version "4.2.0" | ||
| resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" | ||
| integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= | ||
| esutils@^2.0.2: | ||
| version "2.0.2" | ||
| resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" | ||
| integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= | ||
| external-editor@^3.0.0: | ||
| version "3.0.3" | ||
| resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" | ||
| integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== | ||
| dependencies: | ||
| chardet "^0.7.0" | ||
| iconv-lite "^0.4.24" | ||
| tmp "^0.0.33" | ||
| fast-deep-equal@^2.0.1: | ||
| version "2.0.1" | ||
| resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" | ||
| integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= | ||
| fast-json-stable-stringify@^2.0.0: | ||
| version "2.0.0" | ||
| resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" | ||
| integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= | ||
| fast-levenshtein@~2.0.4: | ||
| version "2.0.6" | ||
| resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" | ||
| integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= | ||
| figures@^2.0.0: | ||
| version "2.0.0" | ||
| resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" | ||
| integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= | ||
| dependencies: | ||
| escape-string-regexp "^1.0.5" | ||
| file-entry-cache@^2.0.0: | ||
| version "2.0.0" | ||
| resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" | ||
| integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= | ||
| dependencies: | ||
| flat-cache "^1.2.1" | ||
| object-assign "^4.0.1" | ||
| flat-cache@^1.2.1: | ||
| version "1.3.4" | ||
| resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" | ||
| integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== | ||
| dependencies: | ||
| circular-json "^0.3.1" | ||
| graceful-fs "^4.1.2" | ||
| rimraf "~2.6.2" | ||
| write "^0.2.1" | ||
| fs.realpath@^1.0.0: | ||
| version "1.0.0" | ||
| resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" | ||
| integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= | ||
| functional-red-black-tree@^1.0.1: | ||
| version "1.0.1" | ||
| resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" | ||
| integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= | ||
| glob@^7.0.5, glob@^7.1.2: | ||
| version "7.1.3" | ||
| resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" | ||
| integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== | ||
| dependencies: | ||
| fs.realpath "^1.0.0" | ||
| inflight "^1.0.4" | ||
| inherits "2" | ||
| minimatch "^3.0.4" | ||
| once "^1.3.0" | ||
| path-is-absolute "^1.0.0" | ||
| globals@^11.7.0: | ||
| version "11.9.0" | ||
| resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" | ||
| integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== | ||
| graceful-fs@^4.1.2: | ||
| version "4.1.15" | ||
| resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" | ||
| integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== | ||
| has-flag@^3.0.0: | ||
| version "3.0.0" | ||
| resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" | ||
| integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= | ||
| iconv-lite@^0.4.24: | ||
| version "0.4.24" | ||
| resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" | ||
| integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== | ||
| dependencies: | ||
| safer-buffer ">= 2.1.2 < 3" | ||
| ignore@^4.0.6: | ||
| version "4.0.6" | ||
| resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" | ||
| integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== | ||
| imurmurhash@^0.1.4: | ||
| version "0.1.4" | ||
| resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" | ||
| integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= | ||
| inflight@^1.0.4: | ||
| version "1.0.6" | ||
| resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" | ||
| integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= | ||
| dependencies: | ||
| once "^1.3.0" | ||
| wrappy "1" | ||
| inherits@2: | ||
| version "2.0.3" | ||
| resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" | ||
| integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= | ||
| inquirer@^6.1.0: | ||
| version "6.2.0" | ||
| resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" | ||
| integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== | ||
| dependencies: | ||
| ansi-escapes "^3.0.0" | ||
| chalk "^2.0.0" | ||
| cli-cursor "^2.1.0" | ||
| cli-width "^2.0.0" | ||
| external-editor "^3.0.0" | ||
| figures "^2.0.0" | ||
| lodash "^4.17.10" | ||
| mute-stream "0.0.7" | ||
| run-async "^2.2.0" | ||
| rxjs "^6.1.0" | ||
| string-width "^2.1.0" | ||
| strip-ansi "^4.0.0" | ||
| through "^2.3.6" | ||
| is-fullwidth-code-point@^2.0.0: | ||
| version "2.0.0" | ||
| resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" | ||
| integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= | ||
| is-promise@^2.1.0: | ||
| version "2.1.0" | ||
| resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" | ||
| integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= | ||
| is-resolvable@^1.1.0: | ||
| version "1.1.0" | ||
| resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" | ||
| integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== | ||
| isexe@^2.0.0: | ||
| version "2.0.0" | ||
| resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" | ||
| integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= | ||
| 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.12.0: | ||
| version "3.12.0" | ||
| resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" | ||
| integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== | ||
| dependencies: | ||
| argparse "^1.0.7" | ||
| esprima "^4.0.0" | ||
| json-schema-traverse@^0.4.1: | ||
| version "0.4.1" | ||
| resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" | ||
| integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== | ||
| json-stable-stringify-without-jsonify@^1.0.1: | ||
| version "1.0.1" | ||
| resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" | ||
| integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= | ||
| levn@^0.3.0, levn@~0.3.0: | ||
| version "0.3.0" | ||
| resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" | ||
| integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= | ||
| dependencies: | ||
| prelude-ls "~1.1.2" | ||
| type-check "~0.3.2" | ||
| lodash@^4.17.10, lodash@^4.17.5: | ||
| version "4.17.11" | ||
| resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" | ||
| integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== | ||
| mimic-fn@^1.0.0: | ||
| version "1.2.0" | ||
| resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" | ||
| integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== | ||
| minimatch@^3.0.4: | ||
| version "3.0.4" | ||
| resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" | ||
| integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== | ||
| dependencies: | ||
| brace-expansion "^1.1.7" | ||
| minimist@0.0.8: | ||
| version "0.0.8" | ||
| resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" | ||
| integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= | ||
| mkdirp@^0.5.1: | ||
| version "0.5.1" | ||
| resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" | ||
| integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= | ||
| dependencies: | ||
| minimist "0.0.8" | ||
| ms@^2.1.1: | ||
| version "2.1.1" | ||
| resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" | ||
| integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== | ||
| mute-stream@0.0.7: | ||
| version "0.0.7" | ||
| resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" | ||
| integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= | ||
| natural-compare@^1.4.0: | ||
| version "1.4.0" | ||
| resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" | ||
| integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= | ||
| nice-try@^1.0.4: | ||
| version "1.0.5" | ||
| resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" | ||
| integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== | ||
| object-assign@^4.0.1: | ||
| version "4.1.1" | ||
| resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" | ||
| integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= | ||
| once@^1.3.0: | ||
| version "1.4.0" | ||
| resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" | ||
| integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= | ||
| dependencies: | ||
| wrappy "1" | ||
| onetime@^2.0.0: | ||
| version "2.0.1" | ||
| resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" | ||
| integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= | ||
| dependencies: | ||
| mimic-fn "^1.0.0" | ||
| optionator@^0.8.2: | ||
| version "0.8.2" | ||
| resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" | ||
| integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= | ||
| dependencies: | ||
| deep-is "~0.1.3" | ||
| fast-levenshtein "~2.0.4" | ||
| levn "~0.3.0" | ||
| prelude-ls "~1.1.2" | ||
| type-check "~0.3.2" | ||
| wordwrap "~1.0.0" | ||
| os-tmpdir@~1.0.2: | ||
| version "1.0.2" | ||
| resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" | ||
| integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= | ||
| path-is-absolute@^1.0.0: | ||
| version "1.0.1" | ||
| resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" | ||
| integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= | ||
| path-is-inside@^1.0.2: | ||
| version "1.0.2" | ||
| resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" | ||
| integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= | ||
| path-key@^2.0.1: | ||
| version "2.0.1" | ||
| resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" | ||
| integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= | ||
| pluralize@^7.0.0: | ||
| version "7.0.0" | ||
| resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" | ||
| integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== | ||
| prelude-ls@~1.1.2: | ||
| version "1.1.2" | ||
| resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" | ||
| integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= | ||
| progress@^2.0.0: | ||
| version "2.0.1" | ||
| resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" | ||
| integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== | ||
| punycode@^2.1.0: | ||
| version "2.1.1" | ||
| resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" | ||
| integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== | ||
| regexpp@^2.0.1: | ||
| version "2.0.1" | ||
| resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" | ||
| integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== | ||
| require-uncached@^1.0.3: | ||
| version "1.0.3" | ||
| resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" | ||
| integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= | ||
| dependencies: | ||
| caller-path "^0.1.0" | ||
| resolve-from "^1.0.0" | ||
| resolve-from@^1.0.0: | ||
| version "1.0.1" | ||
| resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" | ||
| integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= | ||
| restore-cursor@^2.0.0: | ||
| version "2.0.0" | ||
| resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" | ||
| integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= | ||
| dependencies: | ||
| onetime "^2.0.0" | ||
| signal-exit "^3.0.2" | ||
| rimraf@~2.6.2: | ||
| version "2.6.2" | ||
| resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" | ||
| integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== | ||
| dependencies: | ||
| glob "^7.0.5" | ||
| run-async@^2.2.0: | ||
| version "2.3.0" | ||
| resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" | ||
| integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= | ||
| dependencies: | ||
| is-promise "^2.1.0" | ||
| rxjs@^6.1.0: | ||
| version "6.3.3" | ||
| resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" | ||
| integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== | ||
| dependencies: | ||
| tslib "^1.9.0" | ||
| "safer-buffer@>= 2.1.2 < 3": | ||
| version "2.1.2" | ||
| resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" | ||
| integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== | ||
| semver@^5.5.0, semver@^5.5.1: | ||
| version "5.6.0" | ||
| resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" | ||
| integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== | ||
| shebang-command@^1.2.0: | ||
| version "1.2.0" | ||
| resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" | ||
| integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= | ||
| dependencies: | ||
| shebang-regex "^1.0.0" | ||
| shebang-regex@^1.0.0: | ||
| version "1.0.0" | ||
| resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" | ||
| integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= | ||
| signal-exit@^3.0.2: | ||
| version "3.0.2" | ||
| resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" | ||
| integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= | ||
| slice-ansi@1.0.0: | ||
| version "1.0.0" | ||
| resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" | ||
| integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== | ||
| dependencies: | ||
| is-fullwidth-code-point "^2.0.0" | ||
| sprintf-js@~1.0.2: | ||
| version "1.0.3" | ||
| resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" | ||
| integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= | ||
| string-width@^2.1.0, string-width@^2.1.1: | ||
| version "2.1.1" | ||
| resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" | ||
| integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== | ||
| dependencies: | ||
| is-fullwidth-code-point "^2.0.0" | ||
| strip-ansi "^4.0.0" | ||
| strip-ansi@^4.0.0: | ||
| version "4.0.0" | ||
| resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" | ||
| integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= | ||
| dependencies: | ||
| ansi-regex "^3.0.0" | ||
| strip-json-comments@^2.0.1: | ||
| version "2.0.1" | ||
| resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" | ||
| integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= | ||
| supports-color@^5.3.0: | ||
| version "5.5.0" | ||
| resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" | ||
| integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== | ||
| dependencies: | ||
| has-flag "^3.0.0" | ||
| table@^5.0.2: | ||
| version "5.1.0" | ||
| resolved "https://registry.yarnpkg.com/table/-/table-5.1.0.tgz#69a54644f6f01ad1628f8178715b408dc6bf11f7" | ||
| integrity sha512-e542in22ZLhD/fOIuXs/8yDZ9W61ltF8daM88rkRNtgTIct+vI2fTnAyu/Db2TCfEcI8i7mjZz6meLq0nW7TYg== | ||
| dependencies: | ||
| ajv "^6.5.3" | ||
| lodash "^4.17.10" | ||
| slice-ansi "1.0.0" | ||
| string-width "^2.1.1" | ||
| text-table@^0.2.0: | ||
| version "0.2.0" | ||
| resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" | ||
| integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= | ||
| through@^2.3.6: | ||
| version "2.3.8" | ||
| resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" | ||
| integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= | ||
| tmp@^0.0.33: | ||
| version "0.0.33" | ||
| resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" | ||
| integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== | ||
| dependencies: | ||
| os-tmpdir "~1.0.2" | ||
| tslib@^1.9.0: | ||
| version "1.9.3" | ||
| resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" | ||
| integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== | ||
| type-check@~0.3.2: | ||
| version "0.3.2" | ||
| resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" | ||
| integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= | ||
| dependencies: | ||
| prelude-ls "~1.1.2" | ||
| uri-js@^4.2.2: | ||
| version "4.2.2" | ||
| resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" | ||
| integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== | ||
| dependencies: | ||
| punycode "^2.1.0" | ||
| which@^1.2.9: | ||
| version "1.3.1" | ||
| resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" | ||
| integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== | ||
| dependencies: | ||
| isexe "^2.0.0" | ||
| wordwrap@~1.0.0: | ||
| version "1.0.0" | ||
| resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" | ||
| integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= | ||
| wrappy@1: | ||
| version "1.0.2" | ||
| resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" | ||
| integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= | ||
| write@^0.2.1: | ||
| version "0.2.1" | ||
| resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" | ||
| integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= | ||
| dependencies: | ||
| mkdirp "^0.5.1" |
+11
-5
| { | ||
| "name": "matrix-rain", | ||
| "version": "1.1.0", | ||
| "description": "Matrix Rain effect in cli. Characters from a file can also be used.", | ||
| "main": "matrixRain", | ||
| "version": "2.0.0", | ||
| "description": "The famous Matrix rain effect of falling green characters as a cli command", | ||
| "main": "index.js", | ||
| "preferGlobal": true, | ||
| "bin": { | ||
| "matrix-rain": "matrixRain" | ||
| "matrix-rain": "index.js" | ||
| }, | ||
@@ -27,3 +27,9 @@ "repository": { | ||
| }, | ||
| "homepage": "https://github.com/nojvek/matrix-rain" | ||
| "homepage": "https://github.com/nojvek/matrix-rain", | ||
| "dependencies": { | ||
| "argparse": "1.0.10" | ||
| }, | ||
| "devDependencies": { | ||
| "eslint": "^5.9.0" | ||
| } | ||
| } |
+24
-24
@@ -1,3 +0,5 @@ | ||
| # Matrix Rain in terminal with node | ||
| # Matrix Rain | ||
| The famous Matrix rain effect of falling green characters in a terminal with node. | ||
| ## Installation | ||
@@ -12,7 +14,20 @@ | ||
| ``` | ||
| matrix-rain --help | ||
| Usage: matrix-rain opts? filePath? | ||
| opts: --direction=v|h = change direction. If reading from file direction is h (horizontal) | ||
| filePath: Read characters from file and set direction=h | ||
| By default generate random ascii chars in v (vertical) direction | ||
| usage: matrix-rain [-h] [-v] [-d {h,v}] | ||
| [-c {green,red,blue,yellow,magenta,cyan,white}] | ||
| [-k {ascii,binary,braille,emoji,kanji}] [-f FILEPATH] | ||
| The famous Matrix rain effect of falling green characters as a cli command | ||
| Optional arguments: | ||
| -h, --help Show this help message and exit. | ||
| -d, --direction {h,v} | ||
| Change direction of rain. h=horizontal, v=vertical | ||
| -c , --color {green,red,blue,yellow,magenta,cyan,white} | ||
| Rain color. NOTE: droplet start is always white | ||
| -k, --char-range {ascii,binary,braille,emoji,kanji} | ||
| Use rain characters from char-range | ||
| -f, --file-path FILEPATH | ||
| Read characters from a file instead of random | ||
| characters from char-range | ||
| ``` | ||
@@ -26,22 +41,7 @@ ## Screenshots | ||
| ## Story Time | ||
| On christmas eve I watched the The Matrix (1999) and was inspired by the matrix effect. I was curious to see if I could replicate this effect without using other node modules. | ||
| On 2016 christmas eve, I watched the The Matrix (1999) and was inspired by the matrix rain effect. I was curious to see if I could replicate this effect in nodejs. | ||
| There's [blessed](https://github.com/chjj/blessed) and [node-ncurses](https://github.com/mscdex/node-ncurses) which would have helped but rather than using the library I wanted to learn how console cursor manipulation works behind the scenes. I browsed through the source code of [colors.js](https://github.com/marak/colors.js/) and got a few pointers. Thank you github. | ||
| There's [blessed](https://github.com/chjj/blessed) and [node-ncurses](https://github.com/mscdex/node-ncurses) which would have helped but rather than using the library I wanted to learn how console cursor manipulation works behind the scenes. I browsed through the source code of [colors.js](https://github.com/marak/colors.js/) and got a few pointers. On that day I discovered terminal escape codes [VT100 ANSI codes table](http://ascii-table.com/ansi-escape-sequences-vt-100.php) | ||
| I've been programming for 6 years full time but on that day I discovered terminal escape codes. I googled around and found [VT100 ANSI codes table](http://ascii-table.com/ansi-escape-sequences-vt-100.php) | ||
| Node's process.stdout has a columns and rows property. It also fires resize events like the browser. With escape codes I can treat the terminal as a canvas and paint on it. I discovered a new medium to show my art. | ||
| I disovered process.stdout has a columns and rows property. It also fires a resize even when console is resized. With escape codes I can clear the screen, move the cursor to any position in the screen, change colors and do really cool things which previously I thought was vodoo magic. There's even support for 8 bit colors in console. Whoah! All I have to do is write the appropriate escape code sequence in stdout and that is it. | ||
|  | ||
| I learned a couple of things | ||
| * Its faster if I flush commands to stdout when I have finished rendering a frame rather than doing it immediately | ||
| * Writing utf-8 is slower than ascii. I tried random kanji characters but it was about twice as slow. Not sure why. | ||
| * Rather than clearing entire screen and drawing the everything again, its much faster to only modify parts of screen that have changed. | ||
| Initial algorithm somewhat worked. I wondered what else I could do. I used a trick to change swap numRows and numCols and I could render the matrix horizontally. Rather than generate random ascii characters, what if I could read characters from a file. | ||
| This had an interesting side effect that it was a great visualization of the source code. It looked like the computer was programming itself in parallel. I changed the code so it uses jquery.js and voila! I was reading snippets of jquery source code. While I took my dog for a run, I left it running. My wife (non-technical) sent me a message "Hey your computer is in the matrix, its really cool!". Younger noj would be very impressed of older noj. | ||
| The source code matrixRain.coffee is < 200 lines of code. |
-5
| build: | ||
| coffee -bc --no-header matrixRain.coffee | ||
| echo '#!/usr/bin/env node' | cat - matrixRain.js > matrixRain | ||
| rm matrixRain.js | ||
| chmod a+x matrixRain |
Sorry, the diff of this file is not supported yet
| #!/usr/bin/env coffee | ||
| fs = require 'fs' | ||
| c = console | ||
| stdout = process.stdout | ||
| numRows = stdout.rows | ||
| numCols = stdout.columns | ||
| maxDroplets = 0 | ||
| dropletCount = 0 | ||
| shuffledCols = [] | ||
| droplets = [] | ||
| direction = "v" | ||
| updateMs = 30 | ||
| updateCount = 0 | ||
| maxSpeed = 20 | ||
| colorDropPropability = 0.001 | ||
| filePath = null | ||
| filePos = 0 | ||
| fileContents = null | ||
| # http://ascii-table.com/ansi-escape-sequences-vt-100.php | ||
| tty = | ||
| clearScreen: "\x1b[2J", | ||
| moveCursorToHome: "\x1b[H" | ||
| moveCursorTo: (row,col) -> "\x1b[#{row};#{col}H" | ||
| cursorVisible: '\x1b[?25h' | ||
| cursorInvisible: '\x1b[?25l' | ||
| fgColor: (c) -> "\x1b[38;5;#{c}m" | ||
| bgColor: (c) -> "\x1b[48;5;#{c}m" | ||
| underline: "\x1b[4m" | ||
| bold: "\x1b[1m" | ||
| off: "\x1b[0m" | ||
| reset: "\x1bc" | ||
| outBuffer = "" | ||
| # perf is improved if we write to stdout in batches | ||
| write = (chars) -> outBuffer += chars | ||
| flush = -> | ||
| stdout.write(outBuffer) | ||
| outBuffer = "" | ||
| # on resize | ||
| stdout.on 'resize', -> | ||
| refreshDropletParams() | ||
| # on exit | ||
| process.on 'SIGINT', -> | ||
| write tty.reset | ||
| write tty.cursorVisible | ||
| flush() | ||
| process.exit() | ||
| refreshDropletParams = -> | ||
| numCols = stdout.columns | ||
| numRows = stdout.rows | ||
| # invert rows and columns | ||
| if direction == "h" | ||
| [numCols, numRows] = [numRows, numCols] | ||
| if not tty.moveCursorTo.proxied | ||
| moveCursorTo = tty.moveCursorTo | ||
| tty.moveCursorTo = (row, col) -> moveCursorTo(col, row) | ||
| tty.moveCursorTo.proxied = true | ||
| minLength = numRows | ||
| maxLength = numRows | ||
| maxDroplets = numCols * 2 | ||
| #create shuffled cols array | ||
| shuffledCols = [0...numCols] | ||
| for i in [0...numCols] | ||
| rnd = rand(0, numCols) | ||
| [shuffledCols[i], shuffledCols[rnd]] = [shuffledCols[rnd], shuffledCols[i]] | ||
| createDroplet = () -> | ||
| droplet = | ||
| col: shuffledCols[dropletCount++ % numCols] | ||
| row: 0 | ||
| length: numRows | ||
| speed: rand(1, maxSpeed) | ||
| droplet.chars = getChars(droplet.length) | ||
| droplets.push droplet | ||
| return | ||
| updateDroplets = -> | ||
| updateCount++ | ||
| remainingDroplets = [] | ||
| for drop in droplets | ||
| # remove out of bounds drops | ||
| if (drop.row - drop.length) >= numRows or drop.col >= numCols | ||
| continue | ||
| else | ||
| remainingDroplets.push(drop) | ||
| # process drop speed | ||
| if (updateCount % drop.speed) == 0 | ||
| # update old head | ||
| if drop.row > 0 and drop.row <= (numRows + 1) | ||
| write tty.moveCursorTo(drop.row - 1, drop.col) | ||
| if Math.random() < colorDropPropability | ||
| write tty.fgColor(rand(1,255)) | ||
| write drop.headChar | ||
| write tty.off | ||
| else | ||
| # change head back to default | ||
| write drop.headChar | ||
| if drop.row <= numRows | ||
| # write new head | ||
| write tty.moveCursorTo(drop.row, drop.col) | ||
| write tty.fgColor(7) #white | ||
| #write tty.underline | ||
| drop.headChar = drop.chars.charAt(drop.row) | ||
| write drop.headChar | ||
| write tty.off | ||
| if (drop.row - drop.length) >= 0 | ||
| # remove tail | ||
| write tty.moveCursorTo(drop.row - drop.length, drop.col) | ||
| write " " | ||
| drop.row++ | ||
| droplets = remainingDroplets | ||
| if droplets.length < maxDroplets | ||
| createDroplet() | ||
| flush() | ||
| rand = (start, end) -> | ||
| start + Math.floor(Math.random() * (end - start)) | ||
| getChars = (len) -> | ||
| chars = "" | ||
| for i in [0...len] by 1 | ||
| chars += String.fromCharCode(rand(0x21, 0x7E)) | ||
| return chars | ||
| getFileChars = (len) -> | ||
| chars = fileContents.substr(filePos, len) | ||
| if chars.length isnt len | ||
| filePos = len - chars.length | ||
| chars += fileContents.substr(0, filePos) | ||
| else | ||
| filePos += len | ||
| return chars | ||
| readFileContents = -> | ||
| if filePath | ||
| fileContents = fs.readFileSync(filePath, "utf-8") | ||
| fileContents = fileContents.replace(/^\s+|\r|\n/gm, " ") | ||
| getChars = getFileChars | ||
| parseCliParams = -> | ||
| args = process.argv.splice(2) | ||
| for arg in args | ||
| if arg == "--help" | ||
| c.log "Usage: matrix-rain opts? filePath?" | ||
| c.log "opts: --direction=v|h = change direction. If reading from file direction is h (horizontal)" | ||
| c.log "filePath: Read characters from file and set direction=h" | ||
| c.log "By default generate random ascii chars in v (vertical) direction" | ||
| process.exit(0) | ||
| if arg.indexOf("--direction") == 0 | ||
| match = arg.match(/^\-\-direction=(v|h)/) | ||
| if match | ||
| direction = match[1] | ||
| else | ||
| c.error "unrecognized direction arg", arg | ||
| process.exit(1) | ||
| else #default fileArg | ||
| filePath = arg | ||
| if not fs.existsSync(filePath) | ||
| c.error "Can't find", filePath | ||
| process.exit(1) | ||
| if args.length == 1 | ||
| direction = "h" | ||
| return | ||
| # initialize | ||
| parseCliParams() | ||
| write tty.clearScreen | ||
| write tty.cursorInvisible | ||
| flush() | ||
| readFileContents() | ||
| refreshDropletParams() | ||
| setInterval updateDroplets, 10 |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
43348
186.41%7
16.67%255
Infinity%1
Infinity%1
Infinity%+ Added
+ Added
+ Added