├── .npmignore ├── package.json ├── test ├── lib │ └── file-upload.js └── test.js ├── LICENSE ├── .gitignore ├── README.md ├── index.js └── yarn.lock /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "string-to-file-stream", 3 | "version": "2.0.0", 4 | "description": "Create file stream from string.", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "npx mocha" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/ayqy/string-to-file-stream.git" 15 | }, 16 | "keywords": [ 17 | "nodejs", 18 | "string2file", 19 | "string2filestream", 20 | "covert", 21 | "string", 22 | "to", 23 | "file", 24 | "stream" 25 | ], 26 | "author": "ayqy", 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/ayqy/string-to-file-stream/issues" 30 | }, 31 | "homepage": "https://github.com/ayqy/string-to-file-stream#readme", 32 | "devDependencies": { 33 | "form-data": "^2.5.0", 34 | "formidable": "^1.2.1", 35 | "is-file-stream": "^1.0.0", 36 | "mocha": "^8.2.1" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/lib/file-upload.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | const formidable = require('formidable'); 3 | const fs = require('fs'); 4 | 5 | const server = http.createServer(function (req, res) { 6 | if (req.url === '/fileupload') { 7 | const form = new formidable.IncomingForm(); 8 | form.parse(req, function (err, fields, files) { 9 | const content = fs.readFileSync(files.filetoupload.path, 'utf-8'); 10 | res.write(JSON.stringify({ 11 | filename: files.filetoupload.name, 12 | content 13 | })); 14 | res.end(); 15 | }); 16 | } 17 | else { 18 | res.writeHead(200, {'Content-Type': 'text/html'}); 19 | res.write('
'); 20 | res.write('
'); 21 | res.write(''); 22 | res.write('
'); 23 | return res.end(); 24 | } 25 | }).listen(8123, () => { 26 | process.send('SERVER_READY'); 27 | }); 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 黯羽轻扬 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | const { Writable } = require('stream'); 2 | const assert = require('assert'); 3 | const childProcess = require('child_process'); 4 | const FormData = require('form-data'); 5 | const path = require('path'); 6 | const string2fileStream = require('../index.js'); 7 | const isFileStream = require('is-file-stream'); 8 | 9 | const input = 'success'; 10 | 11 | describe('Type', () => { 12 | describe(`#isFileStream(fakeFileStream)`, () => { 13 | it(`should be true like exactly FileStream by default`, () => { 14 | const fakeFileStream = string2fileStream(input); 15 | assert.equal(isFileStream(fakeFileStream), true); 16 | }); 17 | }); 18 | }); 19 | 20 | describe('Methods', () => { 21 | describe(`#pipe`, () => { 22 | it(`should pipe as normal stream`, (done) => { 23 | const s = string2fileStream(input); 24 | const outStream = new Writable({ 25 | write(chunk, encoding, callback) { 26 | assert.equal(chunk.toString(), input); 27 | done(); 28 | callback(); 29 | } 30 | }); 31 | s.pipe(outStream); 32 | }); 33 | }); 34 | }); 35 | 36 | describe('Events', () => { 37 | describe(`#on('data')`, () => { 38 | it(`should return '${input}' when the value is '${input}'`, (done) => { 39 | const s = string2fileStream(input); 40 | s.on('data', (chunk) => { 41 | assert.equal(chunk.toString(), input); 42 | done(); 43 | }); 44 | }); 45 | }); 46 | }); 47 | 48 | describe('Complex Scenarios', () => { 49 | let server; 50 | before(() => { 51 | server = childProcess.fork(path.resolve(__dirname, './lib/file-upload.js')); 52 | }); 53 | 54 | describe(`upload file`, () => { 55 | it(`should upload and parse successfully`, (done) => { 56 | const file = { 57 | filename: 'no-this-file.txt', 58 | content: 'my-string-data' 59 | }; 60 | const formData = new FormData(); 61 | formData.append('filetoupload', string2fileStream(file.content, { path: file.filename })); 62 | // waiting server ready 63 | server.on('message', (msg) => { 64 | if (msg === 'SERVER_READY') { 65 | formData.submit('http://127.0.0.1:8123/fileupload', function(err, res) { 66 | assert.equal(err, null); 67 | assert.equal(res.statusCode, 200); 68 | res.on('data', function (chunk) { 69 | const data = JSON.parse(chunk.toString()); 70 | assert.equal(data.filename, file.filename); 71 | assert.equal(data.content, file.content); 72 | done(); 73 | }); 74 | }); 75 | } 76 | }); 77 | }); 78 | }); 79 | 80 | after(() => { 81 | server.kill(); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Target 2 | 3 | Create a file stream from a string. 4 | 5 | That is: 6 | 7 | ```js 8 | string2fileStream('string-content') === fs.createReadStream(/* path to a text file with content 'string-content' */) 9 | ``` 10 | 11 | ## Implementation 12 | 13 | Rewrite [](https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_class_fs_readstream), and **replace all file operations with equivalent string operations.** 14 | 15 | ## Installation & Usage 16 | 17 | ```bash 18 | npm install string-to-file-stream --save 19 | ``` 20 | 21 | Then, follow your intuitive feelings: 22 | 23 | ```js 24 | const string2fileStream = require('string-to-file-stream'); 25 | const assert = require('assert'); 26 | 27 | const input = 'Oh, my great data!'; 28 | const s = string2fileStream(input); 29 | s.on('data', (chunk) => { 30 | assert.equal(chunk.toString(), input); 31 | }); 32 | ``` 33 | 34 | Or the more useful example, upload a fake file: 35 | 36 | ```js 37 | const string2fileStream = require('string-to-file-stream'); 38 | const FormData = require('form-data'); 39 | 40 | const formData = new FormData(); 41 | formData.append('filetoupload', string2fileStream('my-string-data', { path: 'no-this-file.txt' })); 42 | form.submit('http://127.0.0.1:8123/fileupload', function(err, res) { 43 | console.log(res.statusCode); 44 | }); 45 | ``` 46 | 47 | See [Test Cases](https://github.com/ayqy/string-to-file-stream/blob/master/test/test.js) for more details. 48 | 49 | ## API Details 50 | 51 | ```js 52 | /** 53 | * @typedef {Object} FileStreamOptions 54 | * @property {string} [flags = 'r'] 55 | * @property {string} [encoding = 'utf8'] String encoding, 'utf8' by default. 56 | * @property {number} [fd = null] 57 | * @property {number} [mode = 0o666] 58 | * @property {number} [autoClose = true] 59 | * @property {number} [start = 0] Read bytes from specified position, start counting at 0. 60 | * @property {number} [end] Byte length of the input string. 61 | * @property {number} [highWaterMark = 64 * 1024] 62 | * @property {string} [path = 'no-this-file.txt'] Fake file path, which can be relative or absolute path, null by default. 63 | */ 64 | 65 | /** 66 | * Create file stream from a string. 67 | * @param {*} str The input string. 68 | * @param {FileStreamOptions} options Other options, including 'encoding', 'path' etc. 69 | * @return {fs.ReadStream} https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_class_fs_readstream 70 | */ 71 | function string2fileStream(str, options) { 72 | return new ReadStream(str, options); 73 | } 74 | ``` 75 | 76 | P.S.Above option fileds without description are the same as `options` for [fs.createReadStream(path[, options])](https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_fs_createreadstream_path_options). 77 | 78 | ## Contribution 79 | 80 | ```bash 81 | git clone https://github.com/ayqy/string-to-file-stream.git 82 | cd string-to-file-stream 83 | npm install 84 | npm test 85 | ``` 86 | 87 | ## Changelog 88 | 89 | ### v2.0.0 90 | 91 | - fix: Node.js >= 18 supports ([#9](https://github.com/ayqy/string-to-file-stream/pull/9)) 92 | 93 | ### v1.3.0 94 | 95 | - feat: Node.js < 9.3.0 supports ([#4](https://github.com/ayqy/string-to-file-stream/pull/4)) 96 | 97 | ### v1.2.0 98 | 99 | - feat: attach fake file path by default 100 | 101 | ### v1.1.0 102 | 103 | Initial release. 104 | 105 | ## License 106 | 107 | MIT 108 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { Buffer } = require('buffer'); 4 | const { Readable } = require('stream'); 5 | const util = require('util'); 6 | 7 | const kMinPoolSpace = 128; 8 | 9 | let pool; 10 | // It can happen that we expect to read a large chunk of data, and reserve 11 | // a large chunk of the pool accordingly, but the read() call only filled 12 | // a portion of it. If a concurrently executing read() then uses the same pool, 13 | // the "reserved" portion cannot be used, so we allow it to be re-used as a 14 | // new pool later. 15 | const poolFragments = []; 16 | 17 | function allocNewPool(poolSize) { 18 | if (poolFragments.length > 0) 19 | pool = poolFragments.pop(); 20 | else 21 | pool = Buffer.allocUnsafe(poolSize); 22 | pool.used = 0; 23 | } 24 | 25 | function ReadStream(input, options) { 26 | if (!(this instanceof ReadStream)) 27 | return new ReadStream(input, options); 28 | 29 | // a little bit bigger buffer and water marks by default 30 | options = Object.assign(options || {}); 31 | if (options.highWaterMark === undefined) 32 | options.highWaterMark = 64 * 1024; 33 | 34 | // for backwards compat do not emit close on destroy. 35 | options.emitClose = false; 36 | 37 | Readable.call(this, options); 38 | 39 | if (this.readableHighWaterMark === undefined) 40 | this.readableHighWaterMark = options.highWaterMark 41 | 42 | this.input = Buffer.from(input || '', options.encoding || 'utf8'); 43 | // fake current file position 44 | this.input._position = 0; 45 | // path will be ignored when fd is specified, so it can be falsy 46 | // https://github.com/nodejs/node/blob/v10.16.3/lib/internal/url.js#L1384 47 | this.path = options.path || 'no-this-file.txt'; 48 | this.fd = options.fd === undefined ? null : options.fd; 49 | this.flags = options.flags === undefined ? 'r' : options.flags; 50 | this.mode = options.mode === undefined ? 0o666 : options.mode; 51 | 52 | this.start = options.start || 0; 53 | this.end = options.end; 54 | this.autoClose = options.autoClose === undefined ? true : options.autoClose; 55 | this.pos = undefined; 56 | this.bytesRead = 0; 57 | 58 | if (this.start !== undefined) { 59 | if (typeof this.start !== 'number' || Number.isNaN(this.start)) { 60 | throw new Error(`The start must be a number. Received type ${typeof this.start}`); 61 | } 62 | if (this.end === undefined) { 63 | this.end = this.input.byteLength - 1; 64 | } else if (typeof this.end !== 'number' || Number.isNaN(this.end)) { 65 | throw new Error(`The end must be a number. Received type ${typeof this.end}`); 66 | } 67 | 68 | if (this.start > this.end) { 69 | const errVal = `{start: ${this.start}, end: ${this.end}}`; 70 | throw new Error(`The value of "start" is out of range. It must be <= "end". Received ${errVal}`); 71 | } 72 | 73 | this.pos = this.start; 74 | } 75 | 76 | // Backwards compatibility: Make sure `end` is a number regardless of `start`. 77 | // TODO(addaleax): Make the above typecheck not depend on `start` instead. 78 | // (That is a semver-major change). 79 | if (typeof this.end !== 'number') 80 | this.end = Infinity; 81 | else if (Number.isNaN(this.end)) 82 | throw new Error(`The end must be a number, Received type ${typeof this.end}`); 83 | 84 | if (typeof this.fd !== 'number') 85 | this.open(); 86 | 87 | this.on('end', function() { 88 | if (this.autoClose) { 89 | this.destroy(); 90 | } 91 | }); 92 | } 93 | util.inherits(ReadStream, Readable); 94 | 95 | ReadStream.prototype.open = function() { 96 | // fake open file async 97 | setTimeout((fd = Infinity) => { 98 | // fake file descriptor 99 | this.fd = fd; 100 | this.emit('open', fd); 101 | this.emit('ready'); 102 | // start the flow of data. 103 | this.read(); 104 | }, 0); 105 | }; 106 | 107 | ReadStream.prototype._read = function(n) { 108 | if (typeof this.fd !== 'number') { 109 | return this.once('open', function() { 110 | this._read(n); 111 | }); 112 | } 113 | 114 | if (this.destroyed) 115 | return; 116 | 117 | if (!pool || pool.length - pool.used < kMinPoolSpace) { 118 | // discard the old pool. 119 | allocNewPool(this.readableHighWaterMark); 120 | } 121 | 122 | // Grab another reference to the pool in the case that while we're 123 | // in the thread pool another read() finishes up the pool, and 124 | // allocates a new one. 125 | const thisPool = pool; 126 | let toRead = Math.min(pool.length - pool.used, n); 127 | const start = pool.used; 128 | 129 | if (this.pos !== undefined) 130 | toRead = Math.min(this.end - this.pos + 1, toRead); 131 | else 132 | toRead = Math.min(this.end - this.bytesRead + 1, toRead); 133 | 134 | // already read everything we were supposed to read! 135 | // treat as EOF. 136 | if (toRead <= 0) 137 | return this.push(null); 138 | 139 | // the actual read. 140 | // fake read file content 141 | this._fakeReadFile(this.fd, pool, pool.used, toRead, this.pos, (bytesRead) => { 142 | let b = null; 143 | // Now that we know how much data we have actually read, re-wind the 144 | // 'used' field if we can, and otherwise allow the remainder of our 145 | // reservation to be used as a new pool later. 146 | if (start + toRead === thisPool.used && thisPool === pool) 147 | thisPool.used += bytesRead - toRead; 148 | else if (toRead - bytesRead > kMinPoolSpace) 149 | poolFragments.push(thisPool.slice(start + bytesRead, start + toRead)); 150 | 151 | if (bytesRead > 0) { 152 | this.bytesRead += bytesRead; 153 | b = thisPool.slice(start, start + bytesRead); 154 | } 155 | 156 | this.push(b); 157 | }); 158 | 159 | // move the pool positions, and internal position for reading. 160 | if (this.pos !== undefined) 161 | this.pos += toRead; 162 | pool.used += toRead; 163 | }; 164 | 165 | // https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_fs_read_fd_buffer_offset_length_position_callback 166 | ReadStream.prototype._fakeReadFile = function(_, buffer, offset, length, position, cb) { 167 | position = position || this.input._position; 168 | // fake read file async 169 | setTimeout(() => { 170 | let bytesRead = 0; 171 | if (position < this.input.byteLength) { 172 | bytesRead = this.input.copy(buffer, offset, position, position + length); 173 | this.input._position += bytesRead; 174 | } 175 | cb(bytesRead); 176 | }, 0); 177 | }; 178 | 179 | ReadStream.prototype._destroy = function(err, cb) { 180 | if (typeof this.fd !== 'number') { 181 | this.once('open', closeFsStream.bind(null, this, cb, err)); 182 | return; 183 | } 184 | 185 | closeFsStream(this, cb, err); 186 | this.fd = null; 187 | }; 188 | 189 | function closeFsStream(stream, cb, err) { 190 | setTimeout(() => { 191 | stream.emit('close'); 192 | }, 0); 193 | } 194 | 195 | ReadStream.prototype.close = function(cb) { 196 | this.destroy(null, cb); 197 | }; 198 | 199 | Object.defineProperty(ReadStream.prototype, 'pending', { 200 | get() { return this.fd === null; }, 201 | configurable: true 202 | }); 203 | 204 | 205 | /** 206 | * @typedef {Object} FileStreamOptions 207 | * @property {string} [flags = 'r'] 208 | * @property {string} [encoding = 'utf8'] String encoding, 'utf8' by default. 209 | * @property {number} [fd = null] 210 | * @property {number} [mode = 0o666] 211 | * @property {number} [autoClose = true] 212 | * @property {number} [start = 0] Read bytes from specified position, start counting at 0. 213 | * @property {number} [end] Byte length of the input string. 214 | * @property {number} [highWaterMark = 64 * 1024] 215 | * @property {string} [path = 'no-this-file.txt'] Fake file path, which can be relative or absolute path, null by default. 216 | */ 217 | 218 | /** 219 | * Create file stream from a string. 220 | * @param {*} str The input string. 221 | * @param {FileStreamOptions} options Other options, including 'encoding', 'path' etc. 222 | * @return {fs.ReadStream} https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_class_fs_readstream 223 | */ 224 | function string2fileStream(str, options) { 225 | return new ReadStream(str, options); 226 | } 227 | 228 | module.exports = string2fileStream; 229 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@ungap/promise-all-settled@1.1.2": 6 | version "1.1.2" 7 | resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" 8 | integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== 9 | 10 | ansi-colors@4.1.1: 11 | version "4.1.1" 12 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 13 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 14 | 15 | ansi-regex@^3.0.0: 16 | version "3.0.0" 17 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 18 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= 19 | 20 | ansi-regex@^4.1.0: 21 | version "4.1.0" 22 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" 23 | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== 24 | 25 | ansi-styles@^3.2.0: 26 | version "3.2.1" 27 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 28 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 29 | dependencies: 30 | color-convert "^1.9.0" 31 | 32 | ansi-styles@^4.1.0: 33 | version "4.3.0" 34 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 35 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 36 | dependencies: 37 | color-convert "^2.0.1" 38 | 39 | anymatch@~3.1.1: 40 | version "3.1.1" 41 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" 42 | integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== 43 | dependencies: 44 | normalize-path "^3.0.0" 45 | picomatch "^2.0.4" 46 | 47 | argparse@^1.0.7: 48 | version "1.0.10" 49 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 50 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 51 | dependencies: 52 | sprintf-js "~1.0.2" 53 | 54 | asynckit@^0.4.0: 55 | version "0.4.0" 56 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 57 | integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= 58 | 59 | balanced-match@^1.0.0: 60 | version "1.0.0" 61 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 62 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 63 | 64 | binary-extensions@^2.0.0: 65 | version "2.0.0" 66 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" 67 | integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== 68 | 69 | brace-expansion@^1.1.7: 70 | version "1.1.11" 71 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 72 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 73 | dependencies: 74 | balanced-match "^1.0.0" 75 | concat-map "0.0.1" 76 | 77 | braces@~3.0.2: 78 | version "3.0.2" 79 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 80 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 81 | dependencies: 82 | fill-range "^7.0.1" 83 | 84 | browser-stdout@1.3.1: 85 | version "1.3.1" 86 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 87 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 88 | 89 | camelcase@^5.0.0: 90 | version "5.3.1" 91 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 92 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 93 | 94 | camelcase@^6.0.0: 95 | version "6.2.0" 96 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" 97 | integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== 98 | 99 | chalk@^4.0.0: 100 | version "4.1.0" 101 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" 102 | integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== 103 | dependencies: 104 | ansi-styles "^4.1.0" 105 | supports-color "^7.1.0" 106 | 107 | chokidar@3.4.3: 108 | version "3.4.3" 109 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" 110 | integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== 111 | dependencies: 112 | anymatch "~3.1.1" 113 | braces "~3.0.2" 114 | glob-parent "~5.1.0" 115 | is-binary-path "~2.1.0" 116 | is-glob "~4.0.1" 117 | normalize-path "~3.0.0" 118 | readdirp "~3.5.0" 119 | optionalDependencies: 120 | fsevents "~2.1.2" 121 | 122 | cliui@^5.0.0: 123 | version "5.0.0" 124 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" 125 | integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== 126 | dependencies: 127 | string-width "^3.1.0" 128 | strip-ansi "^5.2.0" 129 | wrap-ansi "^5.1.0" 130 | 131 | color-convert@^1.9.0: 132 | version "1.9.3" 133 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 134 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 135 | dependencies: 136 | color-name "1.1.3" 137 | 138 | color-convert@^2.0.1: 139 | version "2.0.1" 140 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 141 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 142 | dependencies: 143 | color-name "~1.1.4" 144 | 145 | color-name@1.1.3: 146 | version "1.1.3" 147 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 148 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 149 | 150 | color-name@~1.1.4: 151 | version "1.1.4" 152 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 153 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 154 | 155 | combined-stream@^1.0.6: 156 | version "1.0.8" 157 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 158 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 159 | dependencies: 160 | delayed-stream "~1.0.0" 161 | 162 | concat-map@0.0.1: 163 | version "0.0.1" 164 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 165 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 166 | 167 | debug@4.2.0: 168 | version "4.2.0" 169 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" 170 | integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== 171 | dependencies: 172 | ms "2.1.2" 173 | 174 | decamelize@^1.2.0: 175 | version "1.2.0" 176 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 177 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 178 | 179 | decamelize@^4.0.0: 180 | version "4.0.0" 181 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" 182 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 183 | 184 | delayed-stream@~1.0.0: 185 | version "1.0.0" 186 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 187 | integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= 188 | 189 | diff@4.0.2: 190 | version "4.0.2" 191 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 192 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 193 | 194 | emoji-regex@^7.0.1: 195 | version "7.0.3" 196 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" 197 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== 198 | 199 | escape-string-regexp@4.0.0: 200 | version "4.0.0" 201 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 202 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 203 | 204 | esprima@^4.0.0: 205 | version "4.0.1" 206 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 207 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 208 | 209 | fill-range@^7.0.1: 210 | version "7.0.1" 211 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 212 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 213 | dependencies: 214 | to-regex-range "^5.0.1" 215 | 216 | find-up@5.0.0: 217 | version "5.0.0" 218 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 219 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 220 | dependencies: 221 | locate-path "^6.0.0" 222 | path-exists "^4.0.0" 223 | 224 | find-up@^3.0.0: 225 | version "3.0.0" 226 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" 227 | integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== 228 | dependencies: 229 | locate-path "^3.0.0" 230 | 231 | flat@^5.0.2: 232 | version "5.0.2" 233 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 234 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 235 | 236 | form-data@^2.5.0: 237 | version "2.5.1" 238 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" 239 | integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== 240 | dependencies: 241 | asynckit "^0.4.0" 242 | combined-stream "^1.0.6" 243 | mime-types "^2.1.12" 244 | 245 | formidable@^1.2.1: 246 | version "1.2.2" 247 | resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" 248 | integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q== 249 | 250 | fs.realpath@^1.0.0: 251 | version "1.0.0" 252 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 253 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 254 | 255 | fsevents@~2.1.2: 256 | version "2.1.3" 257 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" 258 | integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== 259 | 260 | get-caller-file@^2.0.1: 261 | version "2.0.5" 262 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 263 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 264 | 265 | glob-parent@~5.1.0: 266 | version "5.1.1" 267 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" 268 | integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== 269 | dependencies: 270 | is-glob "^4.0.1" 271 | 272 | glob@7.1.6: 273 | version "7.1.6" 274 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 275 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 276 | dependencies: 277 | fs.realpath "^1.0.0" 278 | inflight "^1.0.4" 279 | inherits "2" 280 | minimatch "^3.0.4" 281 | once "^1.3.0" 282 | path-is-absolute "^1.0.0" 283 | 284 | growl@1.10.5: 285 | version "1.10.5" 286 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 287 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 288 | 289 | has-flag@^4.0.0: 290 | version "4.0.0" 291 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 292 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 293 | 294 | he@1.2.0: 295 | version "1.2.0" 296 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 297 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 298 | 299 | inflight@^1.0.4: 300 | version "1.0.6" 301 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 302 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 303 | dependencies: 304 | once "^1.3.0" 305 | wrappy "1" 306 | 307 | inherits@2: 308 | version "2.0.4" 309 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 310 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 311 | 312 | is-binary-path@~2.1.0: 313 | version "2.1.0" 314 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 315 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 316 | dependencies: 317 | binary-extensions "^2.0.0" 318 | 319 | is-extglob@^2.1.1: 320 | version "2.1.1" 321 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 322 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 323 | 324 | is-file-stream@^1.0.0: 325 | version "1.0.0" 326 | resolved "https://registry.yarnpkg.com/is-file-stream/-/is-file-stream-1.0.0.tgz#09a4fbab5dfede3bc5f694210d2dbfb8af46db28" 327 | integrity sha1-CaT7q13+3jvF9pQhDS2/uK9G2yg= 328 | dependencies: 329 | is-stream "^1.1.0" 330 | 331 | is-fullwidth-code-point@^2.0.0: 332 | version "2.0.0" 333 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 334 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 335 | 336 | is-glob@^4.0.1, is-glob@~4.0.1: 337 | version "4.0.1" 338 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" 339 | integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== 340 | dependencies: 341 | is-extglob "^2.1.1" 342 | 343 | is-number@^7.0.0: 344 | version "7.0.0" 345 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 346 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 347 | 348 | is-plain-obj@^2.1.0: 349 | version "2.1.0" 350 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" 351 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 352 | 353 | is-stream@^1.1.0: 354 | version "1.1.0" 355 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 356 | integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= 357 | 358 | isexe@^2.0.0: 359 | version "2.0.0" 360 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 361 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 362 | 363 | js-yaml@3.14.0: 364 | version "3.14.0" 365 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" 366 | integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== 367 | dependencies: 368 | argparse "^1.0.7" 369 | esprima "^4.0.0" 370 | 371 | locate-path@^3.0.0: 372 | version "3.0.0" 373 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" 374 | integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== 375 | dependencies: 376 | p-locate "^3.0.0" 377 | path-exists "^3.0.0" 378 | 379 | locate-path@^6.0.0: 380 | version "6.0.0" 381 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 382 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 383 | dependencies: 384 | p-locate "^5.0.0" 385 | 386 | log-symbols@4.0.0: 387 | version "4.0.0" 388 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" 389 | integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== 390 | dependencies: 391 | chalk "^4.0.0" 392 | 393 | mime-db@1.44.0: 394 | version "1.44.0" 395 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" 396 | integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== 397 | 398 | mime-types@^2.1.12: 399 | version "2.1.27" 400 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" 401 | integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== 402 | dependencies: 403 | mime-db "1.44.0" 404 | 405 | minimatch@3.0.4, minimatch@^3.0.4: 406 | version "3.0.4" 407 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 408 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 409 | dependencies: 410 | brace-expansion "^1.1.7" 411 | 412 | mocha@^8.2.1: 413 | version "8.2.1" 414 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.2.1.tgz#f2fa68817ed0e53343d989df65ccd358bc3a4b39" 415 | integrity sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w== 416 | dependencies: 417 | "@ungap/promise-all-settled" "1.1.2" 418 | ansi-colors "4.1.1" 419 | browser-stdout "1.3.1" 420 | chokidar "3.4.3" 421 | debug "4.2.0" 422 | diff "4.0.2" 423 | escape-string-regexp "4.0.0" 424 | find-up "5.0.0" 425 | glob "7.1.6" 426 | growl "1.10.5" 427 | he "1.2.0" 428 | js-yaml "3.14.0" 429 | log-symbols "4.0.0" 430 | minimatch "3.0.4" 431 | ms "2.1.2" 432 | nanoid "3.1.12" 433 | serialize-javascript "5.0.1" 434 | strip-json-comments "3.1.1" 435 | supports-color "7.2.0" 436 | which "2.0.2" 437 | wide-align "1.1.3" 438 | workerpool "6.0.2" 439 | yargs "13.3.2" 440 | yargs-parser "13.1.2" 441 | yargs-unparser "2.0.0" 442 | 443 | ms@2.1.2: 444 | version "2.1.2" 445 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 446 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 447 | 448 | nanoid@3.1.12: 449 | version "3.1.12" 450 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.12.tgz#6f7736c62e8d39421601e4a0c77623a97ea69654" 451 | integrity sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A== 452 | 453 | normalize-path@^3.0.0, normalize-path@~3.0.0: 454 | version "3.0.0" 455 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 456 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 457 | 458 | once@^1.3.0: 459 | version "1.4.0" 460 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 461 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 462 | dependencies: 463 | wrappy "1" 464 | 465 | p-limit@^2.0.0: 466 | version "2.3.0" 467 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" 468 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== 469 | dependencies: 470 | p-try "^2.0.0" 471 | 472 | p-limit@^3.0.2: 473 | version "3.1.0" 474 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 475 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 476 | dependencies: 477 | yocto-queue "^0.1.0" 478 | 479 | p-locate@^3.0.0: 480 | version "3.0.0" 481 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" 482 | integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== 483 | dependencies: 484 | p-limit "^2.0.0" 485 | 486 | p-locate@^5.0.0: 487 | version "5.0.0" 488 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 489 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 490 | dependencies: 491 | p-limit "^3.0.2" 492 | 493 | p-try@^2.0.0: 494 | version "2.2.0" 495 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" 496 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== 497 | 498 | path-exists@^3.0.0: 499 | version "3.0.0" 500 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" 501 | integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= 502 | 503 | path-exists@^4.0.0: 504 | version "4.0.0" 505 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 506 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 507 | 508 | path-is-absolute@^1.0.0: 509 | version "1.0.1" 510 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 511 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 512 | 513 | picomatch@^2.0.4, picomatch@^2.2.1: 514 | version "2.2.2" 515 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" 516 | integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== 517 | 518 | randombytes@^2.1.0: 519 | version "2.1.0" 520 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 521 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 522 | dependencies: 523 | safe-buffer "^5.1.0" 524 | 525 | readdirp@~3.5.0: 526 | version "3.5.0" 527 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" 528 | integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== 529 | dependencies: 530 | picomatch "^2.2.1" 531 | 532 | require-directory@^2.1.1: 533 | version "2.1.1" 534 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 535 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 536 | 537 | require-main-filename@^2.0.0: 538 | version "2.0.0" 539 | resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" 540 | integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== 541 | 542 | safe-buffer@^5.1.0: 543 | version "5.2.1" 544 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 545 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 546 | 547 | serialize-javascript@5.0.1: 548 | version "5.0.1" 549 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" 550 | integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== 551 | dependencies: 552 | randombytes "^2.1.0" 553 | 554 | set-blocking@^2.0.0: 555 | version "2.0.0" 556 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 557 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 558 | 559 | sprintf-js@~1.0.2: 560 | version "1.0.3" 561 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 562 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 563 | 564 | "string-width@^1.0.2 || 2": 565 | version "2.1.1" 566 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 567 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== 568 | dependencies: 569 | is-fullwidth-code-point "^2.0.0" 570 | strip-ansi "^4.0.0" 571 | 572 | string-width@^3.0.0, string-width@^3.1.0: 573 | version "3.1.0" 574 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" 575 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== 576 | dependencies: 577 | emoji-regex "^7.0.1" 578 | is-fullwidth-code-point "^2.0.0" 579 | strip-ansi "^5.1.0" 580 | 581 | strip-ansi@^4.0.0: 582 | version "4.0.0" 583 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 584 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= 585 | dependencies: 586 | ansi-regex "^3.0.0" 587 | 588 | strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: 589 | version "5.2.0" 590 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" 591 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== 592 | dependencies: 593 | ansi-regex "^4.1.0" 594 | 595 | strip-json-comments@3.1.1: 596 | version "3.1.1" 597 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 598 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 599 | 600 | supports-color@7.2.0, supports-color@^7.1.0: 601 | version "7.2.0" 602 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 603 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 604 | dependencies: 605 | has-flag "^4.0.0" 606 | 607 | to-regex-range@^5.0.1: 608 | version "5.0.1" 609 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 610 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 611 | dependencies: 612 | is-number "^7.0.0" 613 | 614 | which-module@^2.0.0: 615 | version "2.0.0" 616 | resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" 617 | integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= 618 | 619 | which@2.0.2: 620 | version "2.0.2" 621 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 622 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 623 | dependencies: 624 | isexe "^2.0.0" 625 | 626 | wide-align@1.1.3: 627 | version "1.1.3" 628 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" 629 | integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== 630 | dependencies: 631 | string-width "^1.0.2 || 2" 632 | 633 | workerpool@6.0.2: 634 | version "6.0.2" 635 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.0.2.tgz#e241b43d8d033f1beb52c7851069456039d1d438" 636 | integrity sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q== 637 | 638 | wrap-ansi@^5.1.0: 639 | version "5.1.0" 640 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" 641 | integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== 642 | dependencies: 643 | ansi-styles "^3.2.0" 644 | string-width "^3.0.0" 645 | strip-ansi "^5.0.0" 646 | 647 | wrappy@1: 648 | version "1.0.2" 649 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 650 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 651 | 652 | y18n@^4.0.0: 653 | version "4.0.0" 654 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" 655 | integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== 656 | 657 | yargs-parser@13.1.2, yargs-parser@^13.1.2: 658 | version "13.1.2" 659 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" 660 | integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== 661 | dependencies: 662 | camelcase "^5.0.0" 663 | decamelize "^1.2.0" 664 | 665 | yargs-unparser@2.0.0: 666 | version "2.0.0" 667 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" 668 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 669 | dependencies: 670 | camelcase "^6.0.0" 671 | decamelize "^4.0.0" 672 | flat "^5.0.2" 673 | is-plain-obj "^2.1.0" 674 | 675 | yargs@13.3.2: 676 | version "13.3.2" 677 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" 678 | integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== 679 | dependencies: 680 | cliui "^5.0.0" 681 | find-up "^3.0.0" 682 | get-caller-file "^2.0.1" 683 | require-directory "^2.1.1" 684 | require-main-filename "^2.0.0" 685 | set-blocking "^2.0.0" 686 | string-width "^3.0.0" 687 | which-module "^2.0.0" 688 | y18n "^4.0.0" 689 | yargs-parser "^13.1.2" 690 | 691 | yocto-queue@^0.1.0: 692 | version "0.1.0" 693 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 694 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 695 | --------------------------------------------------------------------------------