├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ └── push.yml ├── .gitignore ├── LICENSE ├── README.md ├── lib └── balancer.js ├── package-lock.json ├── package.json ├── stress_test.js └── test ├── balancer.test.js └── test-utils.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: sinon 11 | versions: 12 | - 10.0.0 13 | - 9.2.4 14 | - dependency-name: mocha 15 | versions: 16 | - 8.3.0 17 | - 8.3.1 18 | - dependency-name: chai 19 | versions: 20 | - 4.3.0 21 | - 4.3.1 22 | - 4.3.3 23 | -------------------------------------------------------------------------------- /.github/workflows/push.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | on: [push, pull_request] 3 | jobs: 4 | test: 5 | runs-on: ubuntu-latest 6 | strategy: 7 | matrix: 8 | node-version: [11.x, 12.x] 9 | steps: 10 | - uses: actions/checkout@master 11 | - name: Use Node.js ${{ matrix.node-version }} 12 | uses: actions/setup-node@v1 13 | with: 14 | node-version: ${{ matrix.node-version }} 15 | - name: npm install, build, and test 16 | run: | 17 | npm install 18 | npm run build --if-present 19 | npm test 20 | env: 21 | CI: true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # next.js build output 79 | .next 80 | 81 | # nuxt.js build output 82 | .nuxt 83 | 84 | # gatsby files 85 | .cache/ 86 | public 87 | 88 | # vuepress build output 89 | .vuepress/dist 90 | 91 | # Serverless directories 92 | .serverless/ 93 | 94 | # FuseBox cache 95 | .fusebox/ 96 | 97 | # DynamoDB Local files 98 | .dynamodb/ 99 | 100 | # TernJS port file 101 | .tern-port -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Jakob S 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # proxy-balancer 2 | 3 | [![Build status](https://github.com/zjael/proxy-balancer/workflows/Node%20CI/badge.svg)](https://github.com/zjael/proxy-balancer/actions) 4 | [![Package version](https://img.shields.io/npm/v/proxy-balancer.svg)](https://npmjs.org/package/proxy-balancer) 5 | [![NPM downloads](https://img.shields.io/npm/dm/proxy-balancer)](https://npmjs.org/package/proxy-balancer) 6 | [![Make a pull request](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) 7 | [![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT) 8 | 9 | > Proxy Load Balancer 10 | 11 | ## Table of Contents 12 | 13 | - [Install](#install) 14 | - [Usage](#usage) 15 | - [License](#license) 16 | 17 | ## Install 18 | 19 | ```shell script 20 | npm install proxy-balancer 21 | ``` 22 | 23 | ## Usage 24 | 25 | ```js 26 | const Balancer = require('proxy-balancer'); 27 | const fetch = require('node-fetch'); 28 | 29 | const balancer = new Balancer({ 30 | // Required function to populate proxy list, in this case we use a simple web request using node-fetch. 31 | // Proxies should be in this format: 32 | // [ http://0.0.0.0:8080, https://0.0.0.0:8081, socks4://0.0.0.0:8000 ] 33 | fetchProxies: () => { 34 | return fetch('https://www.cool-proxy.net/proxies.json') 35 | .then(res => res.json()) 36 | .then(proxies => { 37 | return proxies 38 | .filter(proxy => proxy.working_average > 70) 39 | .map(proxy => `http://${proxy.ip}:${proxy.port}`) 40 | }) 41 | }, 42 | 43 | /* 44 | * * * Optional Configs * * * 45 | * all times in milli-seconds 46 | */ 47 | 48 | // Time in milli-seconds, until the proxy list will be updated. 49 | poolExpired: 1 * 60 * 1000, 50 | 51 | // Max concurrent requests at once. Set to null for infinite 52 | maxConcurrent: 15, 53 | 54 | // Minimum time between each request in milli-seconds. 55 | minTime: 100, 56 | 57 | // Time in milli-seconds, to wait for request response. 58 | timeout: 3 * 1000, 59 | 60 | // Time in milli-seconds, to wait for proxy connection to establish. 61 | proxyTimeout: 2 * 1000, 62 | 63 | // optionally specify a request agent of your choosing, default is node-fetch 64 | requestor: axios, 65 | 66 | // Shuffle fetched proxies, based on Fisher-Yates algorithm. 67 | shuffle: false, 68 | 69 | // optional agent function to use other proxy agents (i.e. tunnel) 70 | // or you can add proxy agent auth settings or 71 | // return a unique agent object (supports async/await) 72 | agentFn: ({ url, timeout }) => new ProxyAgent(url, { 73 | timeout 74 | }), 75 | 76 | // optional configs for bottleneck package 77 | bottleneck: {}, 78 | 79 | // optional retry function logic (supports async/await) 80 | // es6: import Balancer, { retryOptions } from 'proxy-balancer' 81 | // es5: const retryOptions = Balancer.retryOptions 82 | retryFn: ({ error, retryCount, timesThisIpRetried, ipsTried }, { retrySameIp, retryNextIp, abort }) => { 83 | if (retryCount >= 3) { 84 | return abort(); 85 | } 86 | 87 | if (error.name && (error.name === "FetchError" || error.name === "AbortError")) { 88 | return retryNextIp(); 89 | } 90 | 91 | return abort(); 92 | }, 93 | 94 | // optional limiter to fine tune timeouts 95 | limiter: { 96 | callsPerDuration: 5, // required 97 | duration: 60 * 1000, // required 98 | postDurationWait: 5 * 60 * 1000, // required 99 | }, 100 | 101 | // optionally handle no available proxies, i.e. request more proxies 102 | handleNoAvailableProxies: () => { 103 | }, 104 | 105 | // optional proxy formatting function if you're using unique proxy objects 106 | formatProxy: (proxy) => { 107 | if (proxy.url) { 108 | // default will return proxy.url 109 | return proxy.url 110 | } else { 111 | // if you use unique objects, it expects it to resemble a URL object 112 | // Url is the node-url package https://www.npmjs.com/package/url 113 | return Url.format(proxy) 114 | } 115 | } 116 | }); 117 | 118 | // Each request will use a fresh proxy, using round robin. 119 | // If a proxy fails or times out, next available proxy in list will be used. 120 | balancer.request('https://www.cool-proxy.net') 121 | .then(res => res.text()) 122 | .then(body => console.log(body)) 123 | .catch(err => console.error(err)) 124 | 125 | balancer.request('https://www.cool-proxy.net/proxies.json') 126 | .then(res => res.json()) 127 | .then(json => console.log(json)) 128 | .catch(err => console.error(err)) 129 | ``` 130 | 131 | ## License 132 | 133 | MIT 134 | -------------------------------------------------------------------------------- /lib/balancer.js: -------------------------------------------------------------------------------- 1 | const Bottleneck = require('bottleneck'); 2 | const ProxyAgent = require('simple-proxy-agent'); 3 | const fetch = require('node-fetch'); 4 | const shuffle = require('shuffle-array'); 5 | const Url = require('url') 6 | const { RateLimiterMemory } = require('rate-limiter-flexible') 7 | 8 | class ResponseError extends Error { 9 | constructor(message = "", response) { 10 | super(message, response); 11 | this.name = "ResponseError"; 12 | this.message = message; 13 | this.response = response; 14 | } 15 | } 16 | 17 | function delay(ms) { 18 | return new Promise(resolve => setTimeout(resolve, ms)); 19 | } 20 | 21 | function formatProxy(proxy) { 22 | if (typeof proxy === 'string') { 23 | return { url: proxy } 24 | } else if (typeof proxy === 'object') { 25 | // should have url or hostname 26 | return proxy 27 | } else { 28 | return {} 29 | } 30 | } 31 | 32 | const defaultConfig = { 33 | poolExpired: 1 * 60 * 1000, 34 | fetchProxies: () => [], 35 | maxConcurrent: 15, 36 | minTime: 100, 37 | timeout: 3 * 1000, 38 | proxyTimeout: 2 * 1000, 39 | requestor: fetch, 40 | bottleneck: {}, 41 | shuffle: false, 42 | validateFn(res) { 43 | if (res.status && !(res.status >= 200 && res.status < 300)) { 44 | throw new ResponseError('Server responded with a status code that falls out of the range of 2xx', res); 45 | } 46 | }, 47 | agentFn({ proxy, timeout }) { 48 | return new ProxyAgent(this.formatProxy(proxy), { 49 | timeout 50 | }) 51 | }, 52 | retryFn({ error, retryCount, timesThisIpRetried, ipsTried }, { retrySameIp, retryNextIp, abort }) { 53 | if (retryCount >= 3) { 54 | return abort(); 55 | } 56 | 57 | // if fetch error and not a bad response code retry 58 | if (error.name && (error.name === "FetchError" || error.name === "AbortError")) { 59 | return retryNextIp(); 60 | } 61 | 62 | return abort(); 63 | }, 64 | formatProxy(proxy) { 65 | if (proxy.url) { 66 | // default will return proxy.url 67 | return proxy.url 68 | } else { 69 | // if you use unique objects, it expects it to resemble a URL object 70 | return Url.format(proxy) 71 | } 72 | } 73 | } 74 | 75 | class Balancer { 76 | constructor(config) { 77 | this.lastUpdate; 78 | this.proxies = []; 79 | this.currentProxy = 0; 80 | this.config = Object.assign({}, defaultConfig, config); 81 | this.callstackLimiter = new Bottleneck(Object.assign({ 82 | // if null will default to infinity in bottleneck 83 | maxConcurrent: this.config.maxConcurrent, 84 | minTime: this.config.minTime 85 | }, this.config.bottleneck)); 86 | // sets ipLimiter if callsPerDuration, duration, and postDurationWait (then converted to seconds) 87 | this.ipLimiter = (config.limiter && config.limiter.callsPerDuration && config.limiter.duration && config.limiter.postDurationWait) 88 | && new RateLimiterMemory({ points: config.limiter.callsPerDuration, duration: config.limiter.duration / 1000 }); 89 | this.fetchingProxies = false; 90 | this.requestor = this.config.requestor 91 | this.formatProxy = this.config.formatProxy 92 | } 93 | 94 | // gets and refreshes when applicable 95 | async getProxies(forceRefresh = false) { 96 | if (this.fetchingProxies) { 97 | if (this.proxies.length > 0) { 98 | // return potentially stale proxies 99 | return this.proxies; 100 | } 101 | // delay next check to see if proxies have arrived in 200ms intervals 102 | await delay(200); 103 | return this.getProxies(); 104 | } 105 | 106 | if (forceRefresh || !this.lastUpdate || this.proxies.length === 0 || Date.now() > this.lastUpdate + this.config.poolExpired) { 107 | this.fetchingProxies = true; 108 | try { 109 | const proxies = await this.config.fetchProxies(); 110 | if (!Array.isArray(proxies)) { 111 | throw new Error('Proxies must be an array') 112 | } 113 | if (this.config.shuffle) { 114 | shuffle(proxies); 115 | } 116 | const formattedProxies = proxies.map(formatProxy) 117 | this.proxies = formattedProxies || []; 118 | } catch (err) { 119 | this.proxies = []; 120 | throw err; 121 | } finally { 122 | this.lastUpdate = Date.now(); 123 | this.fetchingProxies = false; 124 | } 125 | } 126 | 127 | return this.proxies; 128 | } 129 | 130 | async request(url, options, timeout = this.config.timeout / 1000, { retryCount = 0, timesThisIpRetried = 0, ipsTried = 1 } = {}) { 131 | try { 132 | const next = await this.getAndSetNext(); 133 | if (typeof this.config.agentFn !== 'function') throw new Error('agentFn must be a function') 134 | const agent = await this.config.agentFn({ 135 | proxy: next, 136 | timeout: this.config.proxyTimeout 137 | }); 138 | if (this.ipLimiter) { 139 | const proxies = await this.getProxies() 140 | const usedProxy = this.formatProxy(proxies[this.currentProxy]) 141 | try { 142 | await this.ipLimiter.consume(usedProxy) 143 | 144 | // if no points remaining, delay the proxy 145 | const limit = await this.ipLimiter.get(usedProxy) 146 | if (limit && limit.remainingPoints === 0) { 147 | // block calls for duration 148 | const waitInSeconds = this.config.limiter.postDurationWait / 1000 149 | await this.ipLimiter.block(usedProxy, waitInSeconds) 150 | } 151 | } catch { 152 | throw new Error('Failed to consume, this may mean no remaining proxies are available.') 153 | } 154 | } 155 | const res = await this.callstackLimiter.schedule(() => { 156 | return this.fetch(url, { 157 | agent: agent, 158 | ...options 159 | }, timeout) 160 | }) 161 | 162 | if (typeof this.config.validateFn !== 'function') throw new Error('validateFn must be a function') 163 | const valid = await this.config.validateFn(res); 164 | if (valid !== undefined && !valid) { 165 | throw new Error("Response was not valid"); 166 | } 167 | 168 | return res; 169 | } catch (err) { 170 | if (typeof this.config.retryFn !== 'function') throw new Error('retryFn must be a function') 171 | const retryChoice = await this.config.retryFn({ error: err, retryCount, timesThisIpRetried, ipsTried }, { 172 | retryNextIp: () => { return this.request(url, options, timeout, { retryCount: retryCount + 1, timesThisIpRetried: 0, ipsTried: ipsTried + 1 }) }, 173 | retrySameIp: () => { return this.request(url, options, timeout, { retryCount: retryCount + 1, timesThisIpRetried: timesThisIpRetried + 1, ipsTried }) }, 174 | abort: () => { return Promise.reject(err) } 175 | }) 176 | if (retryChoice === undefined) throw err; 177 | return retryChoice; 178 | } 179 | } 180 | 181 | async nextProxyIndex(proxies) { 182 | if (this.ipLimiter) { 183 | const hasCallsRemaining = (limit) => !limit || (limit && limit.remainingPoints > 0) 184 | // find next available in line 185 | const offset = this.currentProxy + 1 186 | const nextProxyAvailable = proxies.slice(offset, proxies.length).findIndex(async ip => { 187 | const url = this.formatProxy(ip) 188 | const limit = await this.ipLimiter.get(url) 189 | return hasCallsRemaining(limit) 190 | }) 191 | if (nextProxyAvailable > -1) { 192 | return nextProxyAvailable + offset 193 | } else { 194 | // find next available starting from begining 195 | const previousProxyAvailable = proxies.slice(0, this.currentProxy).findIndex(async ip => { 196 | const url = this.formatProxy(ip) 197 | const limit = await this.ipLimiter.get(url) 198 | return hasCallsRemaining(limit) 199 | }) 200 | if (previousProxyAvailable > -1) { 201 | return previousProxyAvailable 202 | } else { 203 | // check if we can reuse the same proxy since none left 204 | const url = this.formatProxy(proxies[this.currentProxy]) 205 | const thisProxyLimit = await this.ipLimiter.get(url) 206 | if (hasCallsRemaining(thisProxyLimit)) { 207 | return this.currentProxy 208 | } 209 | 210 | if (typeof this.config.handleNoAvailableProxies === 'function') { 211 | // optional handler to request more proxies 212 | this.config.handleNoAvailableProxies() 213 | } 214 | // no proxies available! 215 | return null 216 | } 217 | } 218 | } else { 219 | const nextIndex = this.currentProxy + 1 220 | const nextProxyInArr = proxies[nextIndex] 221 | const initialProxy = 0 222 | return nextProxyInArr ? nextIndex : initialProxy 223 | } 224 | } 225 | 226 | async getAndSetNext() { 227 | const proxies = await this.getProxies(); 228 | if (proxies.length === 0) { 229 | throw new Error("Empty proxy list"); 230 | } 231 | 232 | const nextProxyIndex = await this.nextProxyIndex(proxies) 233 | const nextProxy = proxies[nextProxyIndex]; 234 | if (!nextProxy) { 235 | throw new Error('No more proxies available.') 236 | } 237 | 238 | // set current proxy for usage 239 | this.currentProxy = nextProxyIndex 240 | 241 | return nextProxy; 242 | } 243 | 244 | async fetch(url, options, timeout = 5) { 245 | try { 246 | const res = await this.requestor(url, { 247 | ...options, 248 | timeout: timeout * 1000 249 | }) 250 | 251 | return res; 252 | } catch (err) { 253 | throw err; 254 | } 255 | } 256 | } 257 | 258 | module.exports = Balancer -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "proxy-balancer", 3 | "version": "2.0.1", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "proxy-balancer", 9 | "version": "2.0.1", 10 | "license": "MIT", 11 | "dependencies": { 12 | "bottleneck": "^2.19.5", 13 | "node-fetch": "^2.6.7", 14 | "rate-limiter-flexible": "^2.1.15", 15 | "shuffle-array": "^1.0.1", 16 | "simple-proxy-agent": "^1.1.0", 17 | "url": "^0.11.0" 18 | }, 19 | "devDependencies": { 20 | "axios": "^1.1.3", 21 | "chai": "^4.2.0", 22 | "chai-as-promised": "^7.1.1", 23 | "got": "^11.8.5", 24 | "mocha": "^10.1.0", 25 | "sinon": "^14.0.1", 26 | "tunnel": "0.0.6" 27 | }, 28 | "engines": { 29 | "node": ">=10.0" 30 | } 31 | }, 32 | "node_modules/@sindresorhus/is": { 33 | "version": "4.6.0", 34 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", 35 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", 36 | "dev": true, 37 | "engines": { 38 | "node": ">=10" 39 | }, 40 | "funding": { 41 | "url": "https://github.com/sindresorhus/is?sponsor=1" 42 | } 43 | }, 44 | "node_modules/@sinonjs/commons": { 45 | "version": "1.8.3", 46 | "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", 47 | "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", 48 | "dev": true, 49 | "dependencies": { 50 | "type-detect": "4.0.8" 51 | } 52 | }, 53 | "node_modules/@sinonjs/fake-timers": { 54 | "version": "9.1.2", 55 | "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", 56 | "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", 57 | "dev": true, 58 | "dependencies": { 59 | "@sinonjs/commons": "^1.7.0" 60 | } 61 | }, 62 | "node_modules/@sinonjs/samsam": { 63 | "version": "6.1.1", 64 | "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", 65 | "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", 66 | "dev": true, 67 | "dependencies": { 68 | "@sinonjs/commons": "^1.6.0", 69 | "lodash.get": "^4.4.2", 70 | "type-detect": "^4.0.8" 71 | } 72 | }, 73 | "node_modules/@sinonjs/text-encoding": { 74 | "version": "0.7.2", 75 | "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", 76 | "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", 77 | "dev": true 78 | }, 79 | "node_modules/@szmarczak/http-timer": { 80 | "version": "4.0.6", 81 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", 82 | "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", 83 | "dev": true, 84 | "dependencies": { 85 | "defer-to-connect": "^2.0.0" 86 | }, 87 | "engines": { 88 | "node": ">=10" 89 | } 90 | }, 91 | "node_modules/@types/cacheable-request": { 92 | "version": "6.0.2", 93 | "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", 94 | "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", 95 | "dev": true, 96 | "dependencies": { 97 | "@types/http-cache-semantics": "*", 98 | "@types/keyv": "*", 99 | "@types/node": "*", 100 | "@types/responselike": "*" 101 | } 102 | }, 103 | "node_modules/@types/http-cache-semantics": { 104 | "version": "4.0.1", 105 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", 106 | "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", 107 | "dev": true 108 | }, 109 | "node_modules/@types/keyv": { 110 | "version": "4.2.0", 111 | "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-4.2.0.tgz", 112 | "integrity": "sha512-xoBtGl5R9jeKUhc8ZqeYaRDx04qqJ10yhhXYGmJ4Jr8qKpvMsDQQrNUvF/wUJ4klOtmJeJM+p2Xo3zp9uaC3tw==", 113 | "deprecated": "This is a stub types definition. keyv provides its own type definitions, so you do not need this installed.", 114 | "dev": true, 115 | "dependencies": { 116 | "keyv": "*" 117 | } 118 | }, 119 | "node_modules/@types/node": { 120 | "version": "18.11.3", 121 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.3.tgz", 122 | "integrity": "sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A==", 123 | "dev": true 124 | }, 125 | "node_modules/@types/responselike": { 126 | "version": "1.0.0", 127 | "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", 128 | "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", 129 | "dev": true, 130 | "dependencies": { 131 | "@types/node": "*" 132 | } 133 | }, 134 | "node_modules/ansi-colors": { 135 | "version": "4.1.1", 136 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 137 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 138 | "dev": true, 139 | "engines": { 140 | "node": ">=6" 141 | } 142 | }, 143 | "node_modules/ansi-regex": { 144 | "version": "5.0.1", 145 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 146 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 147 | "dev": true, 148 | "engines": { 149 | "node": ">=8" 150 | } 151 | }, 152 | "node_modules/ansi-styles": { 153 | "version": "4.3.0", 154 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 155 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 156 | "dev": true, 157 | "dependencies": { 158 | "color-convert": "^2.0.1" 159 | }, 160 | "engines": { 161 | "node": ">=8" 162 | }, 163 | "funding": { 164 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 165 | } 166 | }, 167 | "node_modules/anymatch": { 168 | "version": "3.1.2", 169 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", 170 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", 171 | "dev": true, 172 | "dependencies": { 173 | "normalize-path": "^3.0.0", 174 | "picomatch": "^2.0.4" 175 | }, 176 | "engines": { 177 | "node": ">= 8" 178 | } 179 | }, 180 | "node_modules/argparse": { 181 | "version": "2.0.1", 182 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 183 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 184 | "dev": true 185 | }, 186 | "node_modules/assertion-error": { 187 | "version": "1.1.0", 188 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 189 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 190 | "dev": true, 191 | "engines": { 192 | "node": "*" 193 | } 194 | }, 195 | "node_modules/asynckit": { 196 | "version": "0.4.0", 197 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 198 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", 199 | "dev": true 200 | }, 201 | "node_modules/axios": { 202 | "version": "1.1.3", 203 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", 204 | "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", 205 | "dev": true, 206 | "dependencies": { 207 | "follow-redirects": "^1.15.0", 208 | "form-data": "^4.0.0", 209 | "proxy-from-env": "^1.1.0" 210 | } 211 | }, 212 | "node_modules/balanced-match": { 213 | "version": "1.0.2", 214 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 215 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 216 | "dev": true 217 | }, 218 | "node_modules/binary-extensions": { 219 | "version": "2.2.0", 220 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 221 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 222 | "dev": true, 223 | "engines": { 224 | "node": ">=8" 225 | } 226 | }, 227 | "node_modules/bottleneck": { 228 | "version": "2.19.5", 229 | "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", 230 | "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" 231 | }, 232 | "node_modules/brace-expansion": { 233 | "version": "1.1.11", 234 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 235 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 236 | "dev": true, 237 | "dependencies": { 238 | "balanced-match": "^1.0.0", 239 | "concat-map": "0.0.1" 240 | } 241 | }, 242 | "node_modules/braces": { 243 | "version": "3.0.2", 244 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 245 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 246 | "dev": true, 247 | "dependencies": { 248 | "fill-range": "^7.0.1" 249 | }, 250 | "engines": { 251 | "node": ">=8" 252 | } 253 | }, 254 | "node_modules/browser-stdout": { 255 | "version": "1.3.1", 256 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 257 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 258 | "dev": true 259 | }, 260 | "node_modules/cacheable-lookup": { 261 | "version": "5.0.4", 262 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", 263 | "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", 264 | "dev": true, 265 | "engines": { 266 | "node": ">=10.6.0" 267 | } 268 | }, 269 | "node_modules/cacheable-request": { 270 | "version": "7.0.2", 271 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", 272 | "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", 273 | "dev": true, 274 | "dependencies": { 275 | "clone-response": "^1.0.2", 276 | "get-stream": "^5.1.0", 277 | "http-cache-semantics": "^4.0.0", 278 | "keyv": "^4.0.0", 279 | "lowercase-keys": "^2.0.0", 280 | "normalize-url": "^6.0.1", 281 | "responselike": "^2.0.0" 282 | }, 283 | "engines": { 284 | "node": ">=8" 285 | } 286 | }, 287 | "node_modules/camelcase": { 288 | "version": "6.3.0", 289 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", 290 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", 291 | "dev": true, 292 | "engines": { 293 | "node": ">=10" 294 | }, 295 | "funding": { 296 | "url": "https://github.com/sponsors/sindresorhus" 297 | } 298 | }, 299 | "node_modules/chai": { 300 | "version": "4.3.6", 301 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", 302 | "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", 303 | "dev": true, 304 | "dependencies": { 305 | "assertion-error": "^1.1.0", 306 | "check-error": "^1.0.2", 307 | "deep-eql": "^3.0.1", 308 | "get-func-name": "^2.0.0", 309 | "loupe": "^2.3.1", 310 | "pathval": "^1.1.1", 311 | "type-detect": "^4.0.5" 312 | }, 313 | "engines": { 314 | "node": ">=4" 315 | } 316 | }, 317 | "node_modules/chai-as-promised": { 318 | "version": "7.1.1", 319 | "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", 320 | "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", 321 | "dev": true, 322 | "dependencies": { 323 | "check-error": "^1.0.2" 324 | }, 325 | "peerDependencies": { 326 | "chai": ">= 2.1.2 < 5" 327 | } 328 | }, 329 | "node_modules/chalk": { 330 | "version": "4.1.2", 331 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 332 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 333 | "dev": true, 334 | "dependencies": { 335 | "ansi-styles": "^4.1.0", 336 | "supports-color": "^7.1.0" 337 | }, 338 | "engines": { 339 | "node": ">=10" 340 | }, 341 | "funding": { 342 | "url": "https://github.com/chalk/chalk?sponsor=1" 343 | } 344 | }, 345 | "node_modules/chalk/node_modules/supports-color": { 346 | "version": "7.2.0", 347 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 348 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 349 | "dev": true, 350 | "dependencies": { 351 | "has-flag": "^4.0.0" 352 | }, 353 | "engines": { 354 | "node": ">=8" 355 | } 356 | }, 357 | "node_modules/check-error": { 358 | "version": "1.0.2", 359 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 360 | "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", 361 | "dev": true, 362 | "engines": { 363 | "node": "*" 364 | } 365 | }, 366 | "node_modules/chokidar": { 367 | "version": "3.5.3", 368 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 369 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 370 | "dev": true, 371 | "funding": [ 372 | { 373 | "type": "individual", 374 | "url": "https://paulmillr.com/funding/" 375 | } 376 | ], 377 | "dependencies": { 378 | "anymatch": "~3.1.2", 379 | "braces": "~3.0.2", 380 | "glob-parent": "~5.1.2", 381 | "is-binary-path": "~2.1.0", 382 | "is-glob": "~4.0.1", 383 | "normalize-path": "~3.0.0", 384 | "readdirp": "~3.6.0" 385 | }, 386 | "engines": { 387 | "node": ">= 8.10.0" 388 | }, 389 | "optionalDependencies": { 390 | "fsevents": "~2.3.2" 391 | } 392 | }, 393 | "node_modules/cliui": { 394 | "version": "7.0.4", 395 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 396 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 397 | "dev": true, 398 | "dependencies": { 399 | "string-width": "^4.2.0", 400 | "strip-ansi": "^6.0.0", 401 | "wrap-ansi": "^7.0.0" 402 | } 403 | }, 404 | "node_modules/clone-response": { 405 | "version": "1.0.3", 406 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", 407 | "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", 408 | "dev": true, 409 | "dependencies": { 410 | "mimic-response": "^1.0.0" 411 | }, 412 | "funding": { 413 | "url": "https://github.com/sponsors/sindresorhus" 414 | } 415 | }, 416 | "node_modules/color-convert": { 417 | "version": "2.0.1", 418 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 419 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 420 | "dev": true, 421 | "dependencies": { 422 | "color-name": "~1.1.4" 423 | }, 424 | "engines": { 425 | "node": ">=7.0.0" 426 | } 427 | }, 428 | "node_modules/color-name": { 429 | "version": "1.1.4", 430 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 431 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 432 | "dev": true 433 | }, 434 | "node_modules/combined-stream": { 435 | "version": "1.0.8", 436 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 437 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 438 | "dev": true, 439 | "dependencies": { 440 | "delayed-stream": "~1.0.0" 441 | }, 442 | "engines": { 443 | "node": ">= 0.8" 444 | } 445 | }, 446 | "node_modules/concat-map": { 447 | "version": "0.0.1", 448 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 449 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 450 | "dev": true 451 | }, 452 | "node_modules/debug": { 453 | "version": "4.3.4", 454 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 455 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 456 | "dev": true, 457 | "dependencies": { 458 | "ms": "2.1.2" 459 | }, 460 | "engines": { 461 | "node": ">=6.0" 462 | }, 463 | "peerDependenciesMeta": { 464 | "supports-color": { 465 | "optional": true 466 | } 467 | } 468 | }, 469 | "node_modules/debug/node_modules/ms": { 470 | "version": "2.1.2", 471 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 472 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 473 | "dev": true 474 | }, 475 | "node_modules/decamelize": { 476 | "version": "4.0.0", 477 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 478 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 479 | "dev": true, 480 | "engines": { 481 | "node": ">=10" 482 | }, 483 | "funding": { 484 | "url": "https://github.com/sponsors/sindresorhus" 485 | } 486 | }, 487 | "node_modules/decompress-response": { 488 | "version": "6.0.0", 489 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 490 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 491 | "dev": true, 492 | "dependencies": { 493 | "mimic-response": "^3.1.0" 494 | }, 495 | "engines": { 496 | "node": ">=10" 497 | }, 498 | "funding": { 499 | "url": "https://github.com/sponsors/sindresorhus" 500 | } 501 | }, 502 | "node_modules/decompress-response/node_modules/mimic-response": { 503 | "version": "3.1.0", 504 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 505 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", 506 | "dev": true, 507 | "engines": { 508 | "node": ">=10" 509 | }, 510 | "funding": { 511 | "url": "https://github.com/sponsors/sindresorhus" 512 | } 513 | }, 514 | "node_modules/deep-eql": { 515 | "version": "3.0.1", 516 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 517 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 518 | "dev": true, 519 | "dependencies": { 520 | "type-detect": "^4.0.0" 521 | }, 522 | "engines": { 523 | "node": ">=0.12" 524 | } 525 | }, 526 | "node_modules/defer-to-connect": { 527 | "version": "2.0.1", 528 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", 529 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", 530 | "dev": true, 531 | "engines": { 532 | "node": ">=10" 533 | } 534 | }, 535 | "node_modules/delayed-stream": { 536 | "version": "1.0.0", 537 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 538 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 539 | "dev": true, 540 | "engines": { 541 | "node": ">=0.4.0" 542 | } 543 | }, 544 | "node_modules/diff": { 545 | "version": "5.0.0", 546 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", 547 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", 548 | "dev": true, 549 | "engines": { 550 | "node": ">=0.3.1" 551 | } 552 | }, 553 | "node_modules/emoji-regex": { 554 | "version": "8.0.0", 555 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 556 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 557 | "dev": true 558 | }, 559 | "node_modules/end-of-stream": { 560 | "version": "1.4.4", 561 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 562 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 563 | "dev": true, 564 | "dependencies": { 565 | "once": "^1.4.0" 566 | } 567 | }, 568 | "node_modules/escalade": { 569 | "version": "3.1.1", 570 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 571 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 572 | "dev": true, 573 | "engines": { 574 | "node": ">=6" 575 | } 576 | }, 577 | "node_modules/escape-string-regexp": { 578 | "version": "4.0.0", 579 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 580 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 581 | "dev": true, 582 | "engines": { 583 | "node": ">=10" 584 | }, 585 | "funding": { 586 | "url": "https://github.com/sponsors/sindresorhus" 587 | } 588 | }, 589 | "node_modules/fill-range": { 590 | "version": "7.0.1", 591 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 592 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 593 | "dev": true, 594 | "dependencies": { 595 | "to-regex-range": "^5.0.1" 596 | }, 597 | "engines": { 598 | "node": ">=8" 599 | } 600 | }, 601 | "node_modules/find-up": { 602 | "version": "5.0.0", 603 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 604 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 605 | "dev": true, 606 | "dependencies": { 607 | "locate-path": "^6.0.0", 608 | "path-exists": "^4.0.0" 609 | }, 610 | "engines": { 611 | "node": ">=10" 612 | }, 613 | "funding": { 614 | "url": "https://github.com/sponsors/sindresorhus" 615 | } 616 | }, 617 | "node_modules/flat": { 618 | "version": "5.0.2", 619 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 620 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 621 | "dev": true, 622 | "bin": { 623 | "flat": "cli.js" 624 | } 625 | }, 626 | "node_modules/follow-redirects": { 627 | "version": "1.15.2", 628 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", 629 | "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", 630 | "dev": true, 631 | "funding": [ 632 | { 633 | "type": "individual", 634 | "url": "https://github.com/sponsors/RubenVerborgh" 635 | } 636 | ], 637 | "engines": { 638 | "node": ">=4.0" 639 | }, 640 | "peerDependenciesMeta": { 641 | "debug": { 642 | "optional": true 643 | } 644 | } 645 | }, 646 | "node_modules/form-data": { 647 | "version": "4.0.0", 648 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 649 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 650 | "dev": true, 651 | "dependencies": { 652 | "asynckit": "^0.4.0", 653 | "combined-stream": "^1.0.8", 654 | "mime-types": "^2.1.12" 655 | }, 656 | "engines": { 657 | "node": ">= 6" 658 | } 659 | }, 660 | "node_modules/fs.realpath": { 661 | "version": "1.0.0", 662 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 663 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 664 | "dev": true 665 | }, 666 | "node_modules/fsevents": { 667 | "version": "2.3.2", 668 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 669 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 670 | "dev": true, 671 | "hasInstallScript": true, 672 | "optional": true, 673 | "os": [ 674 | "darwin" 675 | ], 676 | "engines": { 677 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 678 | } 679 | }, 680 | "node_modules/get-caller-file": { 681 | "version": "2.0.5", 682 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 683 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 684 | "dev": true, 685 | "engines": { 686 | "node": "6.* || 8.* || >= 10.*" 687 | } 688 | }, 689 | "node_modules/get-func-name": { 690 | "version": "2.0.0", 691 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 692 | "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", 693 | "dev": true, 694 | "engines": { 695 | "node": "*" 696 | } 697 | }, 698 | "node_modules/get-stream": { 699 | "version": "5.2.0", 700 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 701 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 702 | "dev": true, 703 | "dependencies": { 704 | "pump": "^3.0.0" 705 | }, 706 | "engines": { 707 | "node": ">=8" 708 | }, 709 | "funding": { 710 | "url": "https://github.com/sponsors/sindresorhus" 711 | } 712 | }, 713 | "node_modules/glob": { 714 | "version": "7.2.0", 715 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 716 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 717 | "dev": true, 718 | "dependencies": { 719 | "fs.realpath": "^1.0.0", 720 | "inflight": "^1.0.4", 721 | "inherits": "2", 722 | "minimatch": "^3.0.4", 723 | "once": "^1.3.0", 724 | "path-is-absolute": "^1.0.0" 725 | }, 726 | "engines": { 727 | "node": "*" 728 | }, 729 | "funding": { 730 | "url": "https://github.com/sponsors/isaacs" 731 | } 732 | }, 733 | "node_modules/glob-parent": { 734 | "version": "5.1.2", 735 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 736 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 737 | "dev": true, 738 | "dependencies": { 739 | "is-glob": "^4.0.1" 740 | }, 741 | "engines": { 742 | "node": ">= 6" 743 | } 744 | }, 745 | "node_modules/glob/node_modules/minimatch": { 746 | "version": "3.1.2", 747 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 748 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 749 | "dev": true, 750 | "dependencies": { 751 | "brace-expansion": "^1.1.7" 752 | }, 753 | "engines": { 754 | "node": "*" 755 | } 756 | }, 757 | "node_modules/got": { 758 | "version": "11.8.5", 759 | "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", 760 | "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", 761 | "dev": true, 762 | "dependencies": { 763 | "@sindresorhus/is": "^4.0.0", 764 | "@szmarczak/http-timer": "^4.0.5", 765 | "@types/cacheable-request": "^6.0.1", 766 | "@types/responselike": "^1.0.0", 767 | "cacheable-lookup": "^5.0.3", 768 | "cacheable-request": "^7.0.2", 769 | "decompress-response": "^6.0.0", 770 | "http2-wrapper": "^1.0.0-beta.5.2", 771 | "lowercase-keys": "^2.0.0", 772 | "p-cancelable": "^2.0.0", 773 | "responselike": "^2.0.0" 774 | }, 775 | "engines": { 776 | "node": ">=10.19.0" 777 | }, 778 | "funding": { 779 | "url": "https://github.com/sindresorhus/got?sponsor=1" 780 | } 781 | }, 782 | "node_modules/has-flag": { 783 | "version": "4.0.0", 784 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 785 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 786 | "dev": true, 787 | "engines": { 788 | "node": ">=8" 789 | } 790 | }, 791 | "node_modules/he": { 792 | "version": "1.2.0", 793 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 794 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 795 | "dev": true, 796 | "bin": { 797 | "he": "bin/he" 798 | } 799 | }, 800 | "node_modules/http-cache-semantics": { 801 | "version": "4.1.0", 802 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", 803 | "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", 804 | "dev": true 805 | }, 806 | "node_modules/http2-wrapper": { 807 | "version": "1.0.3", 808 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", 809 | "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", 810 | "dev": true, 811 | "dependencies": { 812 | "quick-lru": "^5.1.1", 813 | "resolve-alpn": "^1.0.0" 814 | }, 815 | "engines": { 816 | "node": ">=10.19.0" 817 | } 818 | }, 819 | "node_modules/inflight": { 820 | "version": "1.0.6", 821 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 822 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 823 | "dev": true, 824 | "dependencies": { 825 | "once": "^1.3.0", 826 | "wrappy": "1" 827 | } 828 | }, 829 | "node_modules/inherits": { 830 | "version": "2.0.4", 831 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 832 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 833 | "dev": true 834 | }, 835 | "node_modules/ip": { 836 | "version": "2.0.0", 837 | "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", 838 | "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" 839 | }, 840 | "node_modules/is-binary-path": { 841 | "version": "2.1.0", 842 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 843 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 844 | "dev": true, 845 | "dependencies": { 846 | "binary-extensions": "^2.0.0" 847 | }, 848 | "engines": { 849 | "node": ">=8" 850 | } 851 | }, 852 | "node_modules/is-extglob": { 853 | "version": "2.1.1", 854 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 855 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 856 | "dev": true, 857 | "engines": { 858 | "node": ">=0.10.0" 859 | } 860 | }, 861 | "node_modules/is-fullwidth-code-point": { 862 | "version": "3.0.0", 863 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 864 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 865 | "dev": true, 866 | "engines": { 867 | "node": ">=8" 868 | } 869 | }, 870 | "node_modules/is-glob": { 871 | "version": "4.0.3", 872 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 873 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 874 | "dev": true, 875 | "dependencies": { 876 | "is-extglob": "^2.1.1" 877 | }, 878 | "engines": { 879 | "node": ">=0.10.0" 880 | } 881 | }, 882 | "node_modules/is-number": { 883 | "version": "7.0.0", 884 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 885 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 886 | "dev": true, 887 | "engines": { 888 | "node": ">=0.12.0" 889 | } 890 | }, 891 | "node_modules/is-plain-obj": { 892 | "version": "2.1.0", 893 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 894 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 895 | "dev": true, 896 | "engines": { 897 | "node": ">=8" 898 | } 899 | }, 900 | "node_modules/is-unicode-supported": { 901 | "version": "0.1.0", 902 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", 903 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", 904 | "dev": true, 905 | "engines": { 906 | "node": ">=10" 907 | }, 908 | "funding": { 909 | "url": "https://github.com/sponsors/sindresorhus" 910 | } 911 | }, 912 | "node_modules/isarray": { 913 | "version": "0.0.1", 914 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 915 | "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", 916 | "dev": true 917 | }, 918 | "node_modules/js-yaml": { 919 | "version": "4.1.0", 920 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 921 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 922 | "dev": true, 923 | "dependencies": { 924 | "argparse": "^2.0.1" 925 | }, 926 | "bin": { 927 | "js-yaml": "bin/js-yaml.js" 928 | } 929 | }, 930 | "node_modules/json-buffer": { 931 | "version": "3.0.1", 932 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 933 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 934 | "dev": true 935 | }, 936 | "node_modules/just-extend": { 937 | "version": "4.2.1", 938 | "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", 939 | "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", 940 | "dev": true 941 | }, 942 | "node_modules/keyv": { 943 | "version": "4.5.0", 944 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.0.tgz", 945 | "integrity": "sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==", 946 | "dev": true, 947 | "dependencies": { 948 | "json-buffer": "3.0.1" 949 | } 950 | }, 951 | "node_modules/locate-path": { 952 | "version": "6.0.0", 953 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 954 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 955 | "dev": true, 956 | "dependencies": { 957 | "p-locate": "^5.0.0" 958 | }, 959 | "engines": { 960 | "node": ">=10" 961 | }, 962 | "funding": { 963 | "url": "https://github.com/sponsors/sindresorhus" 964 | } 965 | }, 966 | "node_modules/lodash.get": { 967 | "version": "4.4.2", 968 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 969 | "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", 970 | "dev": true 971 | }, 972 | "node_modules/log-symbols": { 973 | "version": "4.1.0", 974 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", 975 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", 976 | "dev": true, 977 | "dependencies": { 978 | "chalk": "^4.1.0", 979 | "is-unicode-supported": "^0.1.0" 980 | }, 981 | "engines": { 982 | "node": ">=10" 983 | }, 984 | "funding": { 985 | "url": "https://github.com/sponsors/sindresorhus" 986 | } 987 | }, 988 | "node_modules/loupe": { 989 | "version": "2.3.4", 990 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", 991 | "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", 992 | "dev": true, 993 | "dependencies": { 994 | "get-func-name": "^2.0.0" 995 | } 996 | }, 997 | "node_modules/lowercase-keys": { 998 | "version": "2.0.0", 999 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 1000 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", 1001 | "dev": true, 1002 | "engines": { 1003 | "node": ">=8" 1004 | } 1005 | }, 1006 | "node_modules/mime-db": { 1007 | "version": "1.52.0", 1008 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1009 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1010 | "dev": true, 1011 | "engines": { 1012 | "node": ">= 0.6" 1013 | } 1014 | }, 1015 | "node_modules/mime-types": { 1016 | "version": "2.1.35", 1017 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1018 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1019 | "dev": true, 1020 | "dependencies": { 1021 | "mime-db": "1.52.0" 1022 | }, 1023 | "engines": { 1024 | "node": ">= 0.6" 1025 | } 1026 | }, 1027 | "node_modules/mimic-response": { 1028 | "version": "1.0.1", 1029 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 1030 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", 1031 | "dev": true, 1032 | "engines": { 1033 | "node": ">=4" 1034 | } 1035 | }, 1036 | "node_modules/minimatch": { 1037 | "version": "5.0.1", 1038 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", 1039 | "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", 1040 | "dev": true, 1041 | "dependencies": { 1042 | "brace-expansion": "^2.0.1" 1043 | }, 1044 | "engines": { 1045 | "node": ">=10" 1046 | } 1047 | }, 1048 | "node_modules/minimatch/node_modules/brace-expansion": { 1049 | "version": "2.0.1", 1050 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1051 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1052 | "dev": true, 1053 | "dependencies": { 1054 | "balanced-match": "^1.0.0" 1055 | } 1056 | }, 1057 | "node_modules/mocha": { 1058 | "version": "10.1.0", 1059 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", 1060 | "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", 1061 | "dev": true, 1062 | "dependencies": { 1063 | "ansi-colors": "4.1.1", 1064 | "browser-stdout": "1.3.1", 1065 | "chokidar": "3.5.3", 1066 | "debug": "4.3.4", 1067 | "diff": "5.0.0", 1068 | "escape-string-regexp": "4.0.0", 1069 | "find-up": "5.0.0", 1070 | "glob": "7.2.0", 1071 | "he": "1.2.0", 1072 | "js-yaml": "4.1.0", 1073 | "log-symbols": "4.1.0", 1074 | "minimatch": "5.0.1", 1075 | "ms": "2.1.3", 1076 | "nanoid": "3.3.3", 1077 | "serialize-javascript": "6.0.0", 1078 | "strip-json-comments": "3.1.1", 1079 | "supports-color": "8.1.1", 1080 | "workerpool": "6.2.1", 1081 | "yargs": "16.2.0", 1082 | "yargs-parser": "20.2.4", 1083 | "yargs-unparser": "2.0.0" 1084 | }, 1085 | "bin": { 1086 | "_mocha": "bin/_mocha", 1087 | "mocha": "bin/mocha.js" 1088 | }, 1089 | "engines": { 1090 | "node": ">= 14.0.0" 1091 | }, 1092 | "funding": { 1093 | "type": "opencollective", 1094 | "url": "https://opencollective.com/mochajs" 1095 | } 1096 | }, 1097 | "node_modules/ms": { 1098 | "version": "2.1.3", 1099 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1100 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1101 | "dev": true 1102 | }, 1103 | "node_modules/nanoid": { 1104 | "version": "3.3.3", 1105 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", 1106 | "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", 1107 | "dev": true, 1108 | "bin": { 1109 | "nanoid": "bin/nanoid.cjs" 1110 | }, 1111 | "engines": { 1112 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1113 | } 1114 | }, 1115 | "node_modules/nise": { 1116 | "version": "5.1.1", 1117 | "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", 1118 | "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", 1119 | "dev": true, 1120 | "dependencies": { 1121 | "@sinonjs/commons": "^1.8.3", 1122 | "@sinonjs/fake-timers": ">=5", 1123 | "@sinonjs/text-encoding": "^0.7.1", 1124 | "just-extend": "^4.0.2", 1125 | "path-to-regexp": "^1.7.0" 1126 | } 1127 | }, 1128 | "node_modules/node-fetch": { 1129 | "version": "2.6.7", 1130 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", 1131 | "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", 1132 | "dependencies": { 1133 | "whatwg-url": "^5.0.0" 1134 | }, 1135 | "engines": { 1136 | "node": "4.x || >=6.0.0" 1137 | }, 1138 | "peerDependencies": { 1139 | "encoding": "^0.1.0" 1140 | }, 1141 | "peerDependenciesMeta": { 1142 | "encoding": { 1143 | "optional": true 1144 | } 1145 | } 1146 | }, 1147 | "node_modules/normalize-path": { 1148 | "version": "3.0.0", 1149 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1150 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1151 | "dev": true, 1152 | "engines": { 1153 | "node": ">=0.10.0" 1154 | } 1155 | }, 1156 | "node_modules/normalize-url": { 1157 | "version": "6.1.0", 1158 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", 1159 | "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", 1160 | "dev": true, 1161 | "engines": { 1162 | "node": ">=10" 1163 | }, 1164 | "funding": { 1165 | "url": "https://github.com/sponsors/sindresorhus" 1166 | } 1167 | }, 1168 | "node_modules/once": { 1169 | "version": "1.4.0", 1170 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1171 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1172 | "dev": true, 1173 | "dependencies": { 1174 | "wrappy": "1" 1175 | } 1176 | }, 1177 | "node_modules/p-cancelable": { 1178 | "version": "2.1.1", 1179 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", 1180 | "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", 1181 | "dev": true, 1182 | "engines": { 1183 | "node": ">=8" 1184 | } 1185 | }, 1186 | "node_modules/p-limit": { 1187 | "version": "3.1.0", 1188 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1189 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1190 | "dev": true, 1191 | "dependencies": { 1192 | "yocto-queue": "^0.1.0" 1193 | }, 1194 | "engines": { 1195 | "node": ">=10" 1196 | }, 1197 | "funding": { 1198 | "url": "https://github.com/sponsors/sindresorhus" 1199 | } 1200 | }, 1201 | "node_modules/p-locate": { 1202 | "version": "5.0.0", 1203 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1204 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1205 | "dev": true, 1206 | "dependencies": { 1207 | "p-limit": "^3.0.2" 1208 | }, 1209 | "engines": { 1210 | "node": ">=10" 1211 | }, 1212 | "funding": { 1213 | "url": "https://github.com/sponsors/sindresorhus" 1214 | } 1215 | }, 1216 | "node_modules/path-exists": { 1217 | "version": "4.0.0", 1218 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1219 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1220 | "dev": true, 1221 | "engines": { 1222 | "node": ">=8" 1223 | } 1224 | }, 1225 | "node_modules/path-is-absolute": { 1226 | "version": "1.0.1", 1227 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1228 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1229 | "dev": true, 1230 | "engines": { 1231 | "node": ">=0.10.0" 1232 | } 1233 | }, 1234 | "node_modules/path-to-regexp": { 1235 | "version": "1.8.0", 1236 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", 1237 | "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", 1238 | "dev": true, 1239 | "dependencies": { 1240 | "isarray": "0.0.1" 1241 | } 1242 | }, 1243 | "node_modules/pathval": { 1244 | "version": "1.1.1", 1245 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", 1246 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", 1247 | "dev": true, 1248 | "engines": { 1249 | "node": "*" 1250 | } 1251 | }, 1252 | "node_modules/picomatch": { 1253 | "version": "2.3.1", 1254 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1255 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1256 | "dev": true, 1257 | "engines": { 1258 | "node": ">=8.6" 1259 | }, 1260 | "funding": { 1261 | "url": "https://github.com/sponsors/jonschlinkert" 1262 | } 1263 | }, 1264 | "node_modules/proxy-from-env": { 1265 | "version": "1.1.0", 1266 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 1267 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", 1268 | "dev": true 1269 | }, 1270 | "node_modules/pump": { 1271 | "version": "3.0.0", 1272 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 1273 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 1274 | "dev": true, 1275 | "dependencies": { 1276 | "end-of-stream": "^1.1.0", 1277 | "once": "^1.3.1" 1278 | } 1279 | }, 1280 | "node_modules/punycode": { 1281 | "version": "1.3.2", 1282 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 1283 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" 1284 | }, 1285 | "node_modules/querystring": { 1286 | "version": "0.2.0", 1287 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 1288 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", 1289 | "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", 1290 | "engines": { 1291 | "node": ">=0.4.x" 1292 | } 1293 | }, 1294 | "node_modules/quick-lru": { 1295 | "version": "5.1.1", 1296 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 1297 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", 1298 | "dev": true, 1299 | "engines": { 1300 | "node": ">=10" 1301 | }, 1302 | "funding": { 1303 | "url": "https://github.com/sponsors/sindresorhus" 1304 | } 1305 | }, 1306 | "node_modules/randombytes": { 1307 | "version": "2.1.0", 1308 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1309 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1310 | "dev": true, 1311 | "dependencies": { 1312 | "safe-buffer": "^5.1.0" 1313 | } 1314 | }, 1315 | "node_modules/rate-limiter-flexible": { 1316 | "version": "2.3.12", 1317 | "resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-2.3.12.tgz", 1318 | "integrity": "sha512-L8gGX+R7mUmyP7Cu0DjcRabGwkOwvS7IHdVptOPyOV5TAdUsvRgdDhzlk9eVt+S/B16m6DUWWMDwcAuFKElCfg==" 1319 | }, 1320 | "node_modules/readdirp": { 1321 | "version": "3.6.0", 1322 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1323 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1324 | "dev": true, 1325 | "dependencies": { 1326 | "picomatch": "^2.2.1" 1327 | }, 1328 | "engines": { 1329 | "node": ">=8.10.0" 1330 | } 1331 | }, 1332 | "node_modules/require-directory": { 1333 | "version": "2.1.1", 1334 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1335 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 1336 | "dev": true, 1337 | "engines": { 1338 | "node": ">=0.10.0" 1339 | } 1340 | }, 1341 | "node_modules/resolve-alpn": { 1342 | "version": "1.2.1", 1343 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", 1344 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", 1345 | "dev": true 1346 | }, 1347 | "node_modules/responselike": { 1348 | "version": "2.0.1", 1349 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", 1350 | "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", 1351 | "dev": true, 1352 | "dependencies": { 1353 | "lowercase-keys": "^2.0.0" 1354 | }, 1355 | "funding": { 1356 | "url": "https://github.com/sponsors/sindresorhus" 1357 | } 1358 | }, 1359 | "node_modules/safe-buffer": { 1360 | "version": "5.2.1", 1361 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1362 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1363 | "dev": true, 1364 | "funding": [ 1365 | { 1366 | "type": "github", 1367 | "url": "https://github.com/sponsors/feross" 1368 | }, 1369 | { 1370 | "type": "patreon", 1371 | "url": "https://www.patreon.com/feross" 1372 | }, 1373 | { 1374 | "type": "consulting", 1375 | "url": "https://feross.org/support" 1376 | } 1377 | ] 1378 | }, 1379 | "node_modules/serialize-javascript": { 1380 | "version": "6.0.0", 1381 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", 1382 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", 1383 | "dev": true, 1384 | "dependencies": { 1385 | "randombytes": "^2.1.0" 1386 | } 1387 | }, 1388 | "node_modules/shuffle-array": { 1389 | "version": "1.0.1", 1390 | "resolved": "https://registry.npmjs.org/shuffle-array/-/shuffle-array-1.0.1.tgz", 1391 | "integrity": "sha512-0TFRU8zVQaLatWKr0/czo19VyPNgb/a3sBc1GAjVfivfzEGaS54vueNgtAu/8/pW7EM/VF5fwq9zgpLdGyRmVw==" 1392 | }, 1393 | "node_modules/simple-proxy-agent": { 1394 | "version": "1.1.0", 1395 | "resolved": "https://registry.npmjs.org/simple-proxy-agent/-/simple-proxy-agent-1.1.0.tgz", 1396 | "integrity": "sha512-amJaLagzNELaNNB2UXdXiORVbbU/RC4yRwtGvF4cttJheTm4JvL2fZ1SfuLU952XC7TLamYdgzzJtWUbGM6Jcw==", 1397 | "dependencies": { 1398 | "socks": "^2.3.2" 1399 | }, 1400 | "engines": { 1401 | "node": ">=10.0" 1402 | } 1403 | }, 1404 | "node_modules/sinon": { 1405 | "version": "14.0.1", 1406 | "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.1.tgz", 1407 | "integrity": "sha512-JhJ0jCiyBWVAHDS+YSjgEbDn7Wgz9iIjA1/RK+eseJN0vAAWIWiXBdrnb92ELPyjsfreCYntD1ORtLSfIrlvSQ==", 1408 | "dev": true, 1409 | "dependencies": { 1410 | "@sinonjs/commons": "^1.8.3", 1411 | "@sinonjs/fake-timers": "^9.1.2", 1412 | "@sinonjs/samsam": "^6.1.1", 1413 | "diff": "^5.0.0", 1414 | "nise": "^5.1.1", 1415 | "supports-color": "^7.2.0" 1416 | }, 1417 | "funding": { 1418 | "type": "opencollective", 1419 | "url": "https://opencollective.com/sinon" 1420 | } 1421 | }, 1422 | "node_modules/sinon/node_modules/supports-color": { 1423 | "version": "7.2.0", 1424 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1425 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1426 | "dev": true, 1427 | "dependencies": { 1428 | "has-flag": "^4.0.0" 1429 | }, 1430 | "engines": { 1431 | "node": ">=8" 1432 | } 1433 | }, 1434 | "node_modules/smart-buffer": { 1435 | "version": "4.2.0", 1436 | "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", 1437 | "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", 1438 | "engines": { 1439 | "node": ">= 6.0.0", 1440 | "npm": ">= 3.0.0" 1441 | } 1442 | }, 1443 | "node_modules/socks": { 1444 | "version": "2.7.1", 1445 | "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", 1446 | "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", 1447 | "dependencies": { 1448 | "ip": "^2.0.0", 1449 | "smart-buffer": "^4.2.0" 1450 | }, 1451 | "engines": { 1452 | "node": ">= 10.13.0", 1453 | "npm": ">= 3.0.0" 1454 | } 1455 | }, 1456 | "node_modules/string-width": { 1457 | "version": "4.2.3", 1458 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1459 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1460 | "dev": true, 1461 | "dependencies": { 1462 | "emoji-regex": "^8.0.0", 1463 | "is-fullwidth-code-point": "^3.0.0", 1464 | "strip-ansi": "^6.0.1" 1465 | }, 1466 | "engines": { 1467 | "node": ">=8" 1468 | } 1469 | }, 1470 | "node_modules/strip-ansi": { 1471 | "version": "6.0.1", 1472 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1473 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1474 | "dev": true, 1475 | "dependencies": { 1476 | "ansi-regex": "^5.0.1" 1477 | }, 1478 | "engines": { 1479 | "node": ">=8" 1480 | } 1481 | }, 1482 | "node_modules/strip-json-comments": { 1483 | "version": "3.1.1", 1484 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1485 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1486 | "dev": true, 1487 | "engines": { 1488 | "node": ">=8" 1489 | }, 1490 | "funding": { 1491 | "url": "https://github.com/sponsors/sindresorhus" 1492 | } 1493 | }, 1494 | "node_modules/supports-color": { 1495 | "version": "8.1.1", 1496 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 1497 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 1498 | "dev": true, 1499 | "dependencies": { 1500 | "has-flag": "^4.0.0" 1501 | }, 1502 | "engines": { 1503 | "node": ">=10" 1504 | }, 1505 | "funding": { 1506 | "url": "https://github.com/chalk/supports-color?sponsor=1" 1507 | } 1508 | }, 1509 | "node_modules/to-regex-range": { 1510 | "version": "5.0.1", 1511 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1512 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1513 | "dev": true, 1514 | "dependencies": { 1515 | "is-number": "^7.0.0" 1516 | }, 1517 | "engines": { 1518 | "node": ">=8.0" 1519 | } 1520 | }, 1521 | "node_modules/tr46": { 1522 | "version": "0.0.3", 1523 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 1524 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 1525 | }, 1526 | "node_modules/tunnel": { 1527 | "version": "0.0.6", 1528 | "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", 1529 | "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", 1530 | "dev": true, 1531 | "engines": { 1532 | "node": ">=0.6.11 <=0.7.0 || >=0.7.3" 1533 | } 1534 | }, 1535 | "node_modules/type-detect": { 1536 | "version": "4.0.8", 1537 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 1538 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 1539 | "dev": true, 1540 | "engines": { 1541 | "node": ">=4" 1542 | } 1543 | }, 1544 | "node_modules/url": { 1545 | "version": "0.11.0", 1546 | "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", 1547 | "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", 1548 | "dependencies": { 1549 | "punycode": "1.3.2", 1550 | "querystring": "0.2.0" 1551 | } 1552 | }, 1553 | "node_modules/webidl-conversions": { 1554 | "version": "3.0.1", 1555 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 1556 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 1557 | }, 1558 | "node_modules/whatwg-url": { 1559 | "version": "5.0.0", 1560 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 1561 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 1562 | "dependencies": { 1563 | "tr46": "~0.0.3", 1564 | "webidl-conversions": "^3.0.0" 1565 | } 1566 | }, 1567 | "node_modules/workerpool": { 1568 | "version": "6.2.1", 1569 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", 1570 | "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", 1571 | "dev": true 1572 | }, 1573 | "node_modules/wrap-ansi": { 1574 | "version": "7.0.0", 1575 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 1576 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 1577 | "dev": true, 1578 | "dependencies": { 1579 | "ansi-styles": "^4.0.0", 1580 | "string-width": "^4.1.0", 1581 | "strip-ansi": "^6.0.0" 1582 | }, 1583 | "engines": { 1584 | "node": ">=10" 1585 | }, 1586 | "funding": { 1587 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 1588 | } 1589 | }, 1590 | "node_modules/wrappy": { 1591 | "version": "1.0.2", 1592 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1593 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1594 | "dev": true 1595 | }, 1596 | "node_modules/y18n": { 1597 | "version": "5.0.8", 1598 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 1599 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 1600 | "dev": true, 1601 | "engines": { 1602 | "node": ">=10" 1603 | } 1604 | }, 1605 | "node_modules/yargs": { 1606 | "version": "16.2.0", 1607 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 1608 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 1609 | "dev": true, 1610 | "dependencies": { 1611 | "cliui": "^7.0.2", 1612 | "escalade": "^3.1.1", 1613 | "get-caller-file": "^2.0.5", 1614 | "require-directory": "^2.1.1", 1615 | "string-width": "^4.2.0", 1616 | "y18n": "^5.0.5", 1617 | "yargs-parser": "^20.2.2" 1618 | }, 1619 | "engines": { 1620 | "node": ">=10" 1621 | } 1622 | }, 1623 | "node_modules/yargs-parser": { 1624 | "version": "20.2.4", 1625 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 1626 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", 1627 | "dev": true, 1628 | "engines": { 1629 | "node": ">=10" 1630 | } 1631 | }, 1632 | "node_modules/yargs-unparser": { 1633 | "version": "2.0.0", 1634 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 1635 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 1636 | "dev": true, 1637 | "dependencies": { 1638 | "camelcase": "^6.0.0", 1639 | "decamelize": "^4.0.0", 1640 | "flat": "^5.0.2", 1641 | "is-plain-obj": "^2.1.0" 1642 | }, 1643 | "engines": { 1644 | "node": ">=10" 1645 | } 1646 | }, 1647 | "node_modules/yocto-queue": { 1648 | "version": "0.1.0", 1649 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1650 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1651 | "dev": true, 1652 | "engines": { 1653 | "node": ">=10" 1654 | }, 1655 | "funding": { 1656 | "url": "https://github.com/sponsors/sindresorhus" 1657 | } 1658 | } 1659 | }, 1660 | "dependencies": { 1661 | "@sindresorhus/is": { 1662 | "version": "4.6.0", 1663 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", 1664 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", 1665 | "dev": true 1666 | }, 1667 | "@sinonjs/commons": { 1668 | "version": "1.8.3", 1669 | "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", 1670 | "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", 1671 | "dev": true, 1672 | "requires": { 1673 | "type-detect": "4.0.8" 1674 | } 1675 | }, 1676 | "@sinonjs/fake-timers": { 1677 | "version": "9.1.2", 1678 | "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", 1679 | "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", 1680 | "dev": true, 1681 | "requires": { 1682 | "@sinonjs/commons": "^1.7.0" 1683 | } 1684 | }, 1685 | "@sinonjs/samsam": { 1686 | "version": "6.1.1", 1687 | "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", 1688 | "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", 1689 | "dev": true, 1690 | "requires": { 1691 | "@sinonjs/commons": "^1.6.0", 1692 | "lodash.get": "^4.4.2", 1693 | "type-detect": "^4.0.8" 1694 | } 1695 | }, 1696 | "@sinonjs/text-encoding": { 1697 | "version": "0.7.2", 1698 | "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", 1699 | "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", 1700 | "dev": true 1701 | }, 1702 | "@szmarczak/http-timer": { 1703 | "version": "4.0.6", 1704 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", 1705 | "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", 1706 | "dev": true, 1707 | "requires": { 1708 | "defer-to-connect": "^2.0.0" 1709 | } 1710 | }, 1711 | "@types/cacheable-request": { 1712 | "version": "6.0.2", 1713 | "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", 1714 | "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", 1715 | "dev": true, 1716 | "requires": { 1717 | "@types/http-cache-semantics": "*", 1718 | "@types/keyv": "*", 1719 | "@types/node": "*", 1720 | "@types/responselike": "*" 1721 | } 1722 | }, 1723 | "@types/http-cache-semantics": { 1724 | "version": "4.0.1", 1725 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", 1726 | "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", 1727 | "dev": true 1728 | }, 1729 | "@types/keyv": { 1730 | "version": "4.2.0", 1731 | "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-4.2.0.tgz", 1732 | "integrity": "sha512-xoBtGl5R9jeKUhc8ZqeYaRDx04qqJ10yhhXYGmJ4Jr8qKpvMsDQQrNUvF/wUJ4klOtmJeJM+p2Xo3zp9uaC3tw==", 1733 | "dev": true, 1734 | "requires": { 1735 | "keyv": "*" 1736 | } 1737 | }, 1738 | "@types/node": { 1739 | "version": "18.11.3", 1740 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.3.tgz", 1741 | "integrity": "sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A==", 1742 | "dev": true 1743 | }, 1744 | "@types/responselike": { 1745 | "version": "1.0.0", 1746 | "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", 1747 | "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", 1748 | "dev": true, 1749 | "requires": { 1750 | "@types/node": "*" 1751 | } 1752 | }, 1753 | "ansi-colors": { 1754 | "version": "4.1.1", 1755 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 1756 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 1757 | "dev": true 1758 | }, 1759 | "ansi-regex": { 1760 | "version": "5.0.1", 1761 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1762 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1763 | "dev": true 1764 | }, 1765 | "ansi-styles": { 1766 | "version": "4.3.0", 1767 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1768 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1769 | "dev": true, 1770 | "requires": { 1771 | "color-convert": "^2.0.1" 1772 | } 1773 | }, 1774 | "anymatch": { 1775 | "version": "3.1.2", 1776 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", 1777 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", 1778 | "dev": true, 1779 | "requires": { 1780 | "normalize-path": "^3.0.0", 1781 | "picomatch": "^2.0.4" 1782 | } 1783 | }, 1784 | "argparse": { 1785 | "version": "2.0.1", 1786 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 1787 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1788 | "dev": true 1789 | }, 1790 | "assertion-error": { 1791 | "version": "1.1.0", 1792 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 1793 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 1794 | "dev": true 1795 | }, 1796 | "asynckit": { 1797 | "version": "0.4.0", 1798 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 1799 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", 1800 | "dev": true 1801 | }, 1802 | "axios": { 1803 | "version": "1.1.3", 1804 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", 1805 | "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", 1806 | "dev": true, 1807 | "requires": { 1808 | "follow-redirects": "^1.15.0", 1809 | "form-data": "^4.0.0", 1810 | "proxy-from-env": "^1.1.0" 1811 | } 1812 | }, 1813 | "balanced-match": { 1814 | "version": "1.0.2", 1815 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1816 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1817 | "dev": true 1818 | }, 1819 | "binary-extensions": { 1820 | "version": "2.2.0", 1821 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 1822 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 1823 | "dev": true 1824 | }, 1825 | "bottleneck": { 1826 | "version": "2.19.5", 1827 | "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", 1828 | "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" 1829 | }, 1830 | "brace-expansion": { 1831 | "version": "1.1.11", 1832 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1833 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1834 | "dev": true, 1835 | "requires": { 1836 | "balanced-match": "^1.0.0", 1837 | "concat-map": "0.0.1" 1838 | } 1839 | }, 1840 | "braces": { 1841 | "version": "3.0.2", 1842 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 1843 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 1844 | "dev": true, 1845 | "requires": { 1846 | "fill-range": "^7.0.1" 1847 | } 1848 | }, 1849 | "browser-stdout": { 1850 | "version": "1.3.1", 1851 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 1852 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 1853 | "dev": true 1854 | }, 1855 | "cacheable-lookup": { 1856 | "version": "5.0.4", 1857 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", 1858 | "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", 1859 | "dev": true 1860 | }, 1861 | "cacheable-request": { 1862 | "version": "7.0.2", 1863 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", 1864 | "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", 1865 | "dev": true, 1866 | "requires": { 1867 | "clone-response": "^1.0.2", 1868 | "get-stream": "^5.1.0", 1869 | "http-cache-semantics": "^4.0.0", 1870 | "keyv": "^4.0.0", 1871 | "lowercase-keys": "^2.0.0", 1872 | "normalize-url": "^6.0.1", 1873 | "responselike": "^2.0.0" 1874 | } 1875 | }, 1876 | "camelcase": { 1877 | "version": "6.3.0", 1878 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", 1879 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", 1880 | "dev": true 1881 | }, 1882 | "chai": { 1883 | "version": "4.3.6", 1884 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", 1885 | "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", 1886 | "dev": true, 1887 | "requires": { 1888 | "assertion-error": "^1.1.0", 1889 | "check-error": "^1.0.2", 1890 | "deep-eql": "^3.0.1", 1891 | "get-func-name": "^2.0.0", 1892 | "loupe": "^2.3.1", 1893 | "pathval": "^1.1.1", 1894 | "type-detect": "^4.0.5" 1895 | } 1896 | }, 1897 | "chai-as-promised": { 1898 | "version": "7.1.1", 1899 | "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", 1900 | "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", 1901 | "dev": true, 1902 | "requires": { 1903 | "check-error": "^1.0.2" 1904 | } 1905 | }, 1906 | "chalk": { 1907 | "version": "4.1.2", 1908 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1909 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1910 | "dev": true, 1911 | "requires": { 1912 | "ansi-styles": "^4.1.0", 1913 | "supports-color": "^7.1.0" 1914 | }, 1915 | "dependencies": { 1916 | "supports-color": { 1917 | "version": "7.2.0", 1918 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1919 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1920 | "dev": true, 1921 | "requires": { 1922 | "has-flag": "^4.0.0" 1923 | } 1924 | } 1925 | } 1926 | }, 1927 | "check-error": { 1928 | "version": "1.0.2", 1929 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 1930 | "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", 1931 | "dev": true 1932 | }, 1933 | "chokidar": { 1934 | "version": "3.5.3", 1935 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 1936 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 1937 | "dev": true, 1938 | "requires": { 1939 | "anymatch": "~3.1.2", 1940 | "braces": "~3.0.2", 1941 | "fsevents": "~2.3.2", 1942 | "glob-parent": "~5.1.2", 1943 | "is-binary-path": "~2.1.0", 1944 | "is-glob": "~4.0.1", 1945 | "normalize-path": "~3.0.0", 1946 | "readdirp": "~3.6.0" 1947 | } 1948 | }, 1949 | "cliui": { 1950 | "version": "7.0.4", 1951 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 1952 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 1953 | "dev": true, 1954 | "requires": { 1955 | "string-width": "^4.2.0", 1956 | "strip-ansi": "^6.0.0", 1957 | "wrap-ansi": "^7.0.0" 1958 | } 1959 | }, 1960 | "clone-response": { 1961 | "version": "1.0.3", 1962 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", 1963 | "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", 1964 | "dev": true, 1965 | "requires": { 1966 | "mimic-response": "^1.0.0" 1967 | } 1968 | }, 1969 | "color-convert": { 1970 | "version": "2.0.1", 1971 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1972 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1973 | "dev": true, 1974 | "requires": { 1975 | "color-name": "~1.1.4" 1976 | } 1977 | }, 1978 | "color-name": { 1979 | "version": "1.1.4", 1980 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1981 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1982 | "dev": true 1983 | }, 1984 | "combined-stream": { 1985 | "version": "1.0.8", 1986 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 1987 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 1988 | "dev": true, 1989 | "requires": { 1990 | "delayed-stream": "~1.0.0" 1991 | } 1992 | }, 1993 | "concat-map": { 1994 | "version": "0.0.1", 1995 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1996 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1997 | "dev": true 1998 | }, 1999 | "debug": { 2000 | "version": "4.3.4", 2001 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 2002 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 2003 | "dev": true, 2004 | "requires": { 2005 | "ms": "2.1.2" 2006 | }, 2007 | "dependencies": { 2008 | "ms": { 2009 | "version": "2.1.2", 2010 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2011 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 2012 | "dev": true 2013 | } 2014 | } 2015 | }, 2016 | "decamelize": { 2017 | "version": "4.0.0", 2018 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 2019 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 2020 | "dev": true 2021 | }, 2022 | "decompress-response": { 2023 | "version": "6.0.0", 2024 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 2025 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 2026 | "dev": true, 2027 | "requires": { 2028 | "mimic-response": "^3.1.0" 2029 | }, 2030 | "dependencies": { 2031 | "mimic-response": { 2032 | "version": "3.1.0", 2033 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 2034 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", 2035 | "dev": true 2036 | } 2037 | } 2038 | }, 2039 | "deep-eql": { 2040 | "version": "3.0.1", 2041 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 2042 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 2043 | "dev": true, 2044 | "requires": { 2045 | "type-detect": "^4.0.0" 2046 | } 2047 | }, 2048 | "defer-to-connect": { 2049 | "version": "2.0.1", 2050 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", 2051 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", 2052 | "dev": true 2053 | }, 2054 | "delayed-stream": { 2055 | "version": "1.0.0", 2056 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 2057 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 2058 | "dev": true 2059 | }, 2060 | "diff": { 2061 | "version": "5.0.0", 2062 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", 2063 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", 2064 | "dev": true 2065 | }, 2066 | "emoji-regex": { 2067 | "version": "8.0.0", 2068 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2069 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2070 | "dev": true 2071 | }, 2072 | "end-of-stream": { 2073 | "version": "1.4.4", 2074 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 2075 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 2076 | "dev": true, 2077 | "requires": { 2078 | "once": "^1.4.0" 2079 | } 2080 | }, 2081 | "escalade": { 2082 | "version": "3.1.1", 2083 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 2084 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 2085 | "dev": true 2086 | }, 2087 | "escape-string-regexp": { 2088 | "version": "4.0.0", 2089 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 2090 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 2091 | "dev": true 2092 | }, 2093 | "fill-range": { 2094 | "version": "7.0.1", 2095 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 2096 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 2097 | "dev": true, 2098 | "requires": { 2099 | "to-regex-range": "^5.0.1" 2100 | } 2101 | }, 2102 | "find-up": { 2103 | "version": "5.0.0", 2104 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 2105 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 2106 | "dev": true, 2107 | "requires": { 2108 | "locate-path": "^6.0.0", 2109 | "path-exists": "^4.0.0" 2110 | } 2111 | }, 2112 | "flat": { 2113 | "version": "5.0.2", 2114 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 2115 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 2116 | "dev": true 2117 | }, 2118 | "follow-redirects": { 2119 | "version": "1.15.2", 2120 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", 2121 | "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", 2122 | "dev": true 2123 | }, 2124 | "form-data": { 2125 | "version": "4.0.0", 2126 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 2127 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 2128 | "dev": true, 2129 | "requires": { 2130 | "asynckit": "^0.4.0", 2131 | "combined-stream": "^1.0.8", 2132 | "mime-types": "^2.1.12" 2133 | } 2134 | }, 2135 | "fs.realpath": { 2136 | "version": "1.0.0", 2137 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 2138 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 2139 | "dev": true 2140 | }, 2141 | "fsevents": { 2142 | "version": "2.3.2", 2143 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 2144 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 2145 | "dev": true, 2146 | "optional": true 2147 | }, 2148 | "get-caller-file": { 2149 | "version": "2.0.5", 2150 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 2151 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 2152 | "dev": true 2153 | }, 2154 | "get-func-name": { 2155 | "version": "2.0.0", 2156 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 2157 | "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", 2158 | "dev": true 2159 | }, 2160 | "get-stream": { 2161 | "version": "5.2.0", 2162 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 2163 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 2164 | "dev": true, 2165 | "requires": { 2166 | "pump": "^3.0.0" 2167 | } 2168 | }, 2169 | "glob": { 2170 | "version": "7.2.0", 2171 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 2172 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 2173 | "dev": true, 2174 | "requires": { 2175 | "fs.realpath": "^1.0.0", 2176 | "inflight": "^1.0.4", 2177 | "inherits": "2", 2178 | "minimatch": "^3.0.4", 2179 | "once": "^1.3.0", 2180 | "path-is-absolute": "^1.0.0" 2181 | }, 2182 | "dependencies": { 2183 | "minimatch": { 2184 | "version": "3.1.2", 2185 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 2186 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 2187 | "dev": true, 2188 | "requires": { 2189 | "brace-expansion": "^1.1.7" 2190 | } 2191 | } 2192 | } 2193 | }, 2194 | "glob-parent": { 2195 | "version": "5.1.2", 2196 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 2197 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 2198 | "dev": true, 2199 | "requires": { 2200 | "is-glob": "^4.0.1" 2201 | } 2202 | }, 2203 | "got": { 2204 | "version": "11.8.5", 2205 | "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", 2206 | "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", 2207 | "dev": true, 2208 | "requires": { 2209 | "@sindresorhus/is": "^4.0.0", 2210 | "@szmarczak/http-timer": "^4.0.5", 2211 | "@types/cacheable-request": "^6.0.1", 2212 | "@types/responselike": "^1.0.0", 2213 | "cacheable-lookup": "^5.0.3", 2214 | "cacheable-request": "^7.0.2", 2215 | "decompress-response": "^6.0.0", 2216 | "http2-wrapper": "^1.0.0-beta.5.2", 2217 | "lowercase-keys": "^2.0.0", 2218 | "p-cancelable": "^2.0.0", 2219 | "responselike": "^2.0.0" 2220 | } 2221 | }, 2222 | "has-flag": { 2223 | "version": "4.0.0", 2224 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 2225 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 2226 | "dev": true 2227 | }, 2228 | "he": { 2229 | "version": "1.2.0", 2230 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 2231 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 2232 | "dev": true 2233 | }, 2234 | "http-cache-semantics": { 2235 | "version": "4.1.0", 2236 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", 2237 | "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", 2238 | "dev": true 2239 | }, 2240 | "http2-wrapper": { 2241 | "version": "1.0.3", 2242 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", 2243 | "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", 2244 | "dev": true, 2245 | "requires": { 2246 | "quick-lru": "^5.1.1", 2247 | "resolve-alpn": "^1.0.0" 2248 | } 2249 | }, 2250 | "inflight": { 2251 | "version": "1.0.6", 2252 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 2253 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 2254 | "dev": true, 2255 | "requires": { 2256 | "once": "^1.3.0", 2257 | "wrappy": "1" 2258 | } 2259 | }, 2260 | "inherits": { 2261 | "version": "2.0.4", 2262 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 2263 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 2264 | "dev": true 2265 | }, 2266 | "ip": { 2267 | "version": "2.0.0", 2268 | "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", 2269 | "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" 2270 | }, 2271 | "is-binary-path": { 2272 | "version": "2.1.0", 2273 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 2274 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 2275 | "dev": true, 2276 | "requires": { 2277 | "binary-extensions": "^2.0.0" 2278 | } 2279 | }, 2280 | "is-extglob": { 2281 | "version": "2.1.1", 2282 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 2283 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 2284 | "dev": true 2285 | }, 2286 | "is-fullwidth-code-point": { 2287 | "version": "3.0.0", 2288 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 2289 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 2290 | "dev": true 2291 | }, 2292 | "is-glob": { 2293 | "version": "4.0.3", 2294 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 2295 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 2296 | "dev": true, 2297 | "requires": { 2298 | "is-extglob": "^2.1.1" 2299 | } 2300 | }, 2301 | "is-number": { 2302 | "version": "7.0.0", 2303 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 2304 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 2305 | "dev": true 2306 | }, 2307 | "is-plain-obj": { 2308 | "version": "2.1.0", 2309 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 2310 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 2311 | "dev": true 2312 | }, 2313 | "is-unicode-supported": { 2314 | "version": "0.1.0", 2315 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", 2316 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", 2317 | "dev": true 2318 | }, 2319 | "isarray": { 2320 | "version": "0.0.1", 2321 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 2322 | "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", 2323 | "dev": true 2324 | }, 2325 | "js-yaml": { 2326 | "version": "4.1.0", 2327 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 2328 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 2329 | "dev": true, 2330 | "requires": { 2331 | "argparse": "^2.0.1" 2332 | } 2333 | }, 2334 | "json-buffer": { 2335 | "version": "3.0.1", 2336 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 2337 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 2338 | "dev": true 2339 | }, 2340 | "just-extend": { 2341 | "version": "4.2.1", 2342 | "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", 2343 | "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", 2344 | "dev": true 2345 | }, 2346 | "keyv": { 2347 | "version": "4.5.0", 2348 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.0.tgz", 2349 | "integrity": "sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==", 2350 | "dev": true, 2351 | "requires": { 2352 | "json-buffer": "3.0.1" 2353 | } 2354 | }, 2355 | "locate-path": { 2356 | "version": "6.0.0", 2357 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 2358 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 2359 | "dev": true, 2360 | "requires": { 2361 | "p-locate": "^5.0.0" 2362 | } 2363 | }, 2364 | "lodash.get": { 2365 | "version": "4.4.2", 2366 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 2367 | "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", 2368 | "dev": true 2369 | }, 2370 | "log-symbols": { 2371 | "version": "4.1.0", 2372 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", 2373 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", 2374 | "dev": true, 2375 | "requires": { 2376 | "chalk": "^4.1.0", 2377 | "is-unicode-supported": "^0.1.0" 2378 | } 2379 | }, 2380 | "loupe": { 2381 | "version": "2.3.4", 2382 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", 2383 | "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", 2384 | "dev": true, 2385 | "requires": { 2386 | "get-func-name": "^2.0.0" 2387 | } 2388 | }, 2389 | "lowercase-keys": { 2390 | "version": "2.0.0", 2391 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 2392 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", 2393 | "dev": true 2394 | }, 2395 | "mime-db": { 2396 | "version": "1.52.0", 2397 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 2398 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 2399 | "dev": true 2400 | }, 2401 | "mime-types": { 2402 | "version": "2.1.35", 2403 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 2404 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 2405 | "dev": true, 2406 | "requires": { 2407 | "mime-db": "1.52.0" 2408 | } 2409 | }, 2410 | "mimic-response": { 2411 | "version": "1.0.1", 2412 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 2413 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", 2414 | "dev": true 2415 | }, 2416 | "minimatch": { 2417 | "version": "5.0.1", 2418 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", 2419 | "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", 2420 | "dev": true, 2421 | "requires": { 2422 | "brace-expansion": "^2.0.1" 2423 | }, 2424 | "dependencies": { 2425 | "brace-expansion": { 2426 | "version": "2.0.1", 2427 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 2428 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 2429 | "dev": true, 2430 | "requires": { 2431 | "balanced-match": "^1.0.0" 2432 | } 2433 | } 2434 | } 2435 | }, 2436 | "mocha": { 2437 | "version": "10.1.0", 2438 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", 2439 | "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", 2440 | "dev": true, 2441 | "requires": { 2442 | "ansi-colors": "4.1.1", 2443 | "browser-stdout": "1.3.1", 2444 | "chokidar": "3.5.3", 2445 | "debug": "4.3.4", 2446 | "diff": "5.0.0", 2447 | "escape-string-regexp": "4.0.0", 2448 | "find-up": "5.0.0", 2449 | "glob": "7.2.0", 2450 | "he": "1.2.0", 2451 | "js-yaml": "4.1.0", 2452 | "log-symbols": "4.1.0", 2453 | "minimatch": "5.0.1", 2454 | "ms": "2.1.3", 2455 | "nanoid": "3.3.3", 2456 | "serialize-javascript": "6.0.0", 2457 | "strip-json-comments": "3.1.1", 2458 | "supports-color": "8.1.1", 2459 | "workerpool": "6.2.1", 2460 | "yargs": "16.2.0", 2461 | "yargs-parser": "20.2.4", 2462 | "yargs-unparser": "2.0.0" 2463 | } 2464 | }, 2465 | "ms": { 2466 | "version": "2.1.3", 2467 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 2468 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 2469 | "dev": true 2470 | }, 2471 | "nanoid": { 2472 | "version": "3.3.3", 2473 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", 2474 | "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", 2475 | "dev": true 2476 | }, 2477 | "nise": { 2478 | "version": "5.1.1", 2479 | "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", 2480 | "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", 2481 | "dev": true, 2482 | "requires": { 2483 | "@sinonjs/commons": "^1.8.3", 2484 | "@sinonjs/fake-timers": ">=5", 2485 | "@sinonjs/text-encoding": "^0.7.1", 2486 | "just-extend": "^4.0.2", 2487 | "path-to-regexp": "^1.7.0" 2488 | } 2489 | }, 2490 | "node-fetch": { 2491 | "version": "2.6.7", 2492 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", 2493 | "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", 2494 | "requires": { 2495 | "whatwg-url": "^5.0.0" 2496 | } 2497 | }, 2498 | "normalize-path": { 2499 | "version": "3.0.0", 2500 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 2501 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 2502 | "dev": true 2503 | }, 2504 | "normalize-url": { 2505 | "version": "6.1.0", 2506 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", 2507 | "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", 2508 | "dev": true 2509 | }, 2510 | "once": { 2511 | "version": "1.4.0", 2512 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2513 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 2514 | "dev": true, 2515 | "requires": { 2516 | "wrappy": "1" 2517 | } 2518 | }, 2519 | "p-cancelable": { 2520 | "version": "2.1.1", 2521 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", 2522 | "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", 2523 | "dev": true 2524 | }, 2525 | "p-limit": { 2526 | "version": "3.1.0", 2527 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 2528 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 2529 | "dev": true, 2530 | "requires": { 2531 | "yocto-queue": "^0.1.0" 2532 | } 2533 | }, 2534 | "p-locate": { 2535 | "version": "5.0.0", 2536 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 2537 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 2538 | "dev": true, 2539 | "requires": { 2540 | "p-limit": "^3.0.2" 2541 | } 2542 | }, 2543 | "path-exists": { 2544 | "version": "4.0.0", 2545 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 2546 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 2547 | "dev": true 2548 | }, 2549 | "path-is-absolute": { 2550 | "version": "1.0.1", 2551 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2552 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 2553 | "dev": true 2554 | }, 2555 | "path-to-regexp": { 2556 | "version": "1.8.0", 2557 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", 2558 | "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", 2559 | "dev": true, 2560 | "requires": { 2561 | "isarray": "0.0.1" 2562 | } 2563 | }, 2564 | "pathval": { 2565 | "version": "1.1.1", 2566 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", 2567 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", 2568 | "dev": true 2569 | }, 2570 | "picomatch": { 2571 | "version": "2.3.1", 2572 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 2573 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 2574 | "dev": true 2575 | }, 2576 | "proxy-from-env": { 2577 | "version": "1.1.0", 2578 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 2579 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", 2580 | "dev": true 2581 | }, 2582 | "pump": { 2583 | "version": "3.0.0", 2584 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 2585 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 2586 | "dev": true, 2587 | "requires": { 2588 | "end-of-stream": "^1.1.0", 2589 | "once": "^1.3.1" 2590 | } 2591 | }, 2592 | "punycode": { 2593 | "version": "1.3.2", 2594 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 2595 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" 2596 | }, 2597 | "querystring": { 2598 | "version": "0.2.0", 2599 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 2600 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" 2601 | }, 2602 | "quick-lru": { 2603 | "version": "5.1.1", 2604 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 2605 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", 2606 | "dev": true 2607 | }, 2608 | "randombytes": { 2609 | "version": "2.1.0", 2610 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 2611 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 2612 | "dev": true, 2613 | "requires": { 2614 | "safe-buffer": "^5.1.0" 2615 | } 2616 | }, 2617 | "rate-limiter-flexible": { 2618 | "version": "2.3.12", 2619 | "resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-2.3.12.tgz", 2620 | "integrity": "sha512-L8gGX+R7mUmyP7Cu0DjcRabGwkOwvS7IHdVptOPyOV5TAdUsvRgdDhzlk9eVt+S/B16m6DUWWMDwcAuFKElCfg==" 2621 | }, 2622 | "readdirp": { 2623 | "version": "3.6.0", 2624 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 2625 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 2626 | "dev": true, 2627 | "requires": { 2628 | "picomatch": "^2.2.1" 2629 | } 2630 | }, 2631 | "require-directory": { 2632 | "version": "2.1.1", 2633 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 2634 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 2635 | "dev": true 2636 | }, 2637 | "resolve-alpn": { 2638 | "version": "1.2.1", 2639 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", 2640 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", 2641 | "dev": true 2642 | }, 2643 | "responselike": { 2644 | "version": "2.0.1", 2645 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", 2646 | "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", 2647 | "dev": true, 2648 | "requires": { 2649 | "lowercase-keys": "^2.0.0" 2650 | } 2651 | }, 2652 | "safe-buffer": { 2653 | "version": "5.2.1", 2654 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 2655 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 2656 | "dev": true 2657 | }, 2658 | "serialize-javascript": { 2659 | "version": "6.0.0", 2660 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", 2661 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", 2662 | "dev": true, 2663 | "requires": { 2664 | "randombytes": "^2.1.0" 2665 | } 2666 | }, 2667 | "shuffle-array": { 2668 | "version": "1.0.1", 2669 | "resolved": "https://registry.npmjs.org/shuffle-array/-/shuffle-array-1.0.1.tgz", 2670 | "integrity": "sha512-0TFRU8zVQaLatWKr0/czo19VyPNgb/a3sBc1GAjVfivfzEGaS54vueNgtAu/8/pW7EM/VF5fwq9zgpLdGyRmVw==" 2671 | }, 2672 | "simple-proxy-agent": { 2673 | "version": "1.1.0", 2674 | "resolved": "https://registry.npmjs.org/simple-proxy-agent/-/simple-proxy-agent-1.1.0.tgz", 2675 | "integrity": "sha512-amJaLagzNELaNNB2UXdXiORVbbU/RC4yRwtGvF4cttJheTm4JvL2fZ1SfuLU952XC7TLamYdgzzJtWUbGM6Jcw==", 2676 | "requires": { 2677 | "socks": "^2.3.2" 2678 | } 2679 | }, 2680 | "sinon": { 2681 | "version": "14.0.1", 2682 | "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.1.tgz", 2683 | "integrity": "sha512-JhJ0jCiyBWVAHDS+YSjgEbDn7Wgz9iIjA1/RK+eseJN0vAAWIWiXBdrnb92ELPyjsfreCYntD1ORtLSfIrlvSQ==", 2684 | "dev": true, 2685 | "requires": { 2686 | "@sinonjs/commons": "^1.8.3", 2687 | "@sinonjs/fake-timers": "^9.1.2", 2688 | "@sinonjs/samsam": "^6.1.1", 2689 | "diff": "^5.0.0", 2690 | "nise": "^5.1.1", 2691 | "supports-color": "^7.2.0" 2692 | }, 2693 | "dependencies": { 2694 | "supports-color": { 2695 | "version": "7.2.0", 2696 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2697 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2698 | "dev": true, 2699 | "requires": { 2700 | "has-flag": "^4.0.0" 2701 | } 2702 | } 2703 | } 2704 | }, 2705 | "smart-buffer": { 2706 | "version": "4.2.0", 2707 | "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", 2708 | "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" 2709 | }, 2710 | "socks": { 2711 | "version": "2.7.1", 2712 | "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", 2713 | "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", 2714 | "requires": { 2715 | "ip": "^2.0.0", 2716 | "smart-buffer": "^4.2.0" 2717 | } 2718 | }, 2719 | "string-width": { 2720 | "version": "4.2.3", 2721 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2722 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2723 | "dev": true, 2724 | "requires": { 2725 | "emoji-regex": "^8.0.0", 2726 | "is-fullwidth-code-point": "^3.0.0", 2727 | "strip-ansi": "^6.0.1" 2728 | } 2729 | }, 2730 | "strip-ansi": { 2731 | "version": "6.0.1", 2732 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2733 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2734 | "dev": true, 2735 | "requires": { 2736 | "ansi-regex": "^5.0.1" 2737 | } 2738 | }, 2739 | "strip-json-comments": { 2740 | "version": "3.1.1", 2741 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2742 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2743 | "dev": true 2744 | }, 2745 | "supports-color": { 2746 | "version": "8.1.1", 2747 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 2748 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 2749 | "dev": true, 2750 | "requires": { 2751 | "has-flag": "^4.0.0" 2752 | } 2753 | }, 2754 | "to-regex-range": { 2755 | "version": "5.0.1", 2756 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2757 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2758 | "dev": true, 2759 | "requires": { 2760 | "is-number": "^7.0.0" 2761 | } 2762 | }, 2763 | "tr46": { 2764 | "version": "0.0.3", 2765 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 2766 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 2767 | }, 2768 | "tunnel": { 2769 | "version": "0.0.6", 2770 | "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", 2771 | "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", 2772 | "dev": true 2773 | }, 2774 | "type-detect": { 2775 | "version": "4.0.8", 2776 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 2777 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 2778 | "dev": true 2779 | }, 2780 | "url": { 2781 | "version": "0.11.0", 2782 | "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", 2783 | "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", 2784 | "requires": { 2785 | "punycode": "1.3.2", 2786 | "querystring": "0.2.0" 2787 | } 2788 | }, 2789 | "webidl-conversions": { 2790 | "version": "3.0.1", 2791 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 2792 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 2793 | }, 2794 | "whatwg-url": { 2795 | "version": "5.0.0", 2796 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 2797 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 2798 | "requires": { 2799 | "tr46": "~0.0.3", 2800 | "webidl-conversions": "^3.0.0" 2801 | } 2802 | }, 2803 | "workerpool": { 2804 | "version": "6.2.1", 2805 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", 2806 | "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", 2807 | "dev": true 2808 | }, 2809 | "wrap-ansi": { 2810 | "version": "7.0.0", 2811 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2812 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2813 | "dev": true, 2814 | "requires": { 2815 | "ansi-styles": "^4.0.0", 2816 | "string-width": "^4.1.0", 2817 | "strip-ansi": "^6.0.0" 2818 | } 2819 | }, 2820 | "wrappy": { 2821 | "version": "1.0.2", 2822 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2823 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 2824 | "dev": true 2825 | }, 2826 | "y18n": { 2827 | "version": "5.0.8", 2828 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 2829 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 2830 | "dev": true 2831 | }, 2832 | "yargs": { 2833 | "version": "16.2.0", 2834 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 2835 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 2836 | "dev": true, 2837 | "requires": { 2838 | "cliui": "^7.0.2", 2839 | "escalade": "^3.1.1", 2840 | "get-caller-file": "^2.0.5", 2841 | "require-directory": "^2.1.1", 2842 | "string-width": "^4.2.0", 2843 | "y18n": "^5.0.5", 2844 | "yargs-parser": "^20.2.2" 2845 | } 2846 | }, 2847 | "yargs-parser": { 2848 | "version": "20.2.4", 2849 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 2850 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", 2851 | "dev": true 2852 | }, 2853 | "yargs-unparser": { 2854 | "version": "2.0.0", 2855 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 2856 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 2857 | "dev": true, 2858 | "requires": { 2859 | "camelcase": "^6.0.0", 2860 | "decamelize": "^4.0.0", 2861 | "flat": "^5.0.2", 2862 | "is-plain-obj": "^2.1.0" 2863 | } 2864 | }, 2865 | "yocto-queue": { 2866 | "version": "0.1.0", 2867 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 2868 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 2869 | "dev": true 2870 | } 2871 | } 2872 | } 2873 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "proxy-balancer", 3 | "version": "2.0.1", 4 | "description": "Proxy load balancer", 5 | "main": "./lib/balancer.js", 6 | "engines": { 7 | "node": ">=10.0" 8 | }, 9 | "scripts": { 10 | "test": "mocha --timeout 10000 --exit", 11 | "stress": "node stress_test.js" 12 | }, 13 | "keywords": [ 14 | "proxy", 15 | "proxies", 16 | "balancer", 17 | "rotater", 18 | "rotating" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/zjael/proxy-balancer.git" 23 | }, 24 | "author": "Jakob Sjælland", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/zjael/proxy-balancer/issues" 28 | }, 29 | "homepage": "https://github.com/zjael/proxy-balancer#readme", 30 | "dependencies": { 31 | "bottleneck": "^2.19.5", 32 | "node-fetch": "^2.6.7", 33 | "rate-limiter-flexible": "^2.1.15", 34 | "shuffle-array": "^1.0.1", 35 | "simple-proxy-agent": "^1.1.0", 36 | "url": "^0.11.0" 37 | }, 38 | "devDependencies": { 39 | "axios": "^1.1.3", 40 | "chai": "^4.2.0", 41 | "chai-as-promised": "^7.1.1", 42 | "got": "^11.8.5", 43 | "mocha": "^10.1.0", 44 | "sinon": "^14.0.1", 45 | "tunnel": "0.0.6" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /stress_test.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | const Balancer = require('./lib/balancer'); 3 | 4 | const balancer = new Balancer({ 5 | poolExpired: 1 * 60 * 1000, 6 | maxConcurrent: 15, 7 | minTime: 100, 8 | timeout: 3 * 1000, 9 | proxyTimeout: 2 * 1000, 10 | fetchProxies() { 11 | return fetch('https://www.cool-proxy.net/proxies.json') 12 | .then(res => res.json()) 13 | .then(proxies => { 14 | return proxies 15 | .filter(proxy => proxy.working_average > 70) 16 | .map(proxy => `http://${proxy.ip}:${proxy.port}`) 17 | }) 18 | } 19 | }); 20 | 21 | let promises = []; 22 | for (let i = 0; i < 100; i++) { 23 | promises.push(balancer.request('https://ipv4.icanhazip.com') 24 | .then(res => res.text()) 25 | .then(body => { 26 | body = body.trim(); 27 | console.log(`completed: ${i}, ip: ${body}`); 28 | return body; 29 | }) 30 | .catch(err => { 31 | console.error(err) 32 | }) 33 | ); 34 | } 35 | 36 | Promise.all(promises).then(result => { 37 | console.log(result); 38 | }) -------------------------------------------------------------------------------- /test/balancer.test.js: -------------------------------------------------------------------------------- 1 | const Balancer = require('../lib/balancer'); 2 | const chai = require('chai'); 3 | const ProxyAgent = require('simple-proxy-agent'); 4 | const chaiAsPromised = require('chai-as-promised'); 5 | const http = require('http'); 6 | const { createProxyServer, delay } = require('./test-utils'); 7 | const axios = require('axios') 8 | const got = require('got') 9 | const tunnel = require('tunnel') 10 | const sinon = require('sinon') 11 | 12 | const expect = chai.expect; 13 | chai.use(chaiAsPromised); 14 | 15 | const ports = [ 16 | 4001, 17 | 4002, 18 | 4003, 19 | 4004 20 | ] 21 | const fetchProxies = (i) => (i ? ['http://127.0.0.1:' + ports[i]] : ports.map(port => 'http://127.0.0.1:' + port)) 22 | const createTestServer = () => http.createServer((req, res) => { 23 | res.writeHead(200, { 'Content-type': 'text/plan' }); 24 | res.write('test'); 25 | res.end(); 26 | }).listen(8080); 27 | const createFailureServer = () => http.createServer((req, res) => { 28 | res.statusCode = 500 29 | res.write('fail'); 30 | res.end(); 31 | }).listen(8080); 32 | 33 | describe('Proxy Balancer', () => { 34 | let servers; 35 | let singleServer; 36 | 37 | before(done => { 38 | servers = ports.map(port => createProxyServer().listen(port)); 39 | done(); 40 | }); 41 | 42 | after(done => { 43 | for (const server of servers) { 44 | server.close(); 45 | } 46 | sinon.restore(); 47 | done(); 48 | }) 49 | 50 | afterEach(done => { 51 | if (singleServer) singleServer.close() 52 | done(); 53 | }) 54 | 55 | context('fetchProxies(..)', () => { 56 | it('should populate proxies using fetchProxies', (done) => { 57 | const balancer = new Balancer({ 58 | fetchProxies 59 | }); 60 | 61 | balancer.getProxies().then(proxies => { 62 | for (const port of ports) { 63 | expect(proxies).to.deep.include({ url: 'http://127.0.0.1:' + port }); 64 | } 65 | done(); 66 | }); 67 | }); 68 | 69 | it('should catch fetchProxies error', async () => { 70 | const errorMsg = "Intended error"; 71 | const balancer = new Balancer({ 72 | fetchProxies() { 73 | throw new Error(errorMsg); 74 | } 75 | }); 76 | 77 | await expect(balancer.request()).to.be.rejectedWith(errorMsg); 78 | }); 79 | 80 | it('should catch empty proxy list error', async () => { 81 | const balancer = new Balancer({ 82 | fetchProxies() { 83 | return []; 84 | } 85 | }); 86 | 87 | await expect(balancer.request()).to.be.rejectedWith("Empty proxy list"); 88 | }); 89 | 90 | it('it should force refresh when passed true', async () => { 91 | let fProxies = fetchProxies() 92 | const balancer = new Balancer({ 93 | fetchProxies: () => fProxies 94 | }); 95 | 96 | let proxies = await balancer.getProxies() 97 | for (const port of ports) { 98 | expect(proxies).to.deep.include({ url: 'http://127.0.0.1:' + port }); 99 | } 100 | 101 | // set proxies to just 1 102 | fProxies = fetchProxies().slice(0, 1) 103 | 104 | // should return same proxies 105 | proxies = await balancer.getProxies() 106 | for (const port of ports) { 107 | expect(proxies).to.deep.include({ url: 'http://127.0.0.1:' + port }); 108 | } 109 | expect(proxies.length).to.equal(4) 110 | 111 | proxies = await balancer.getProxies(true) 112 | expect(proxies.length).to.equal(1) 113 | expect(proxies).to.deep.include({ url: 'http://127.0.0.1:' + ports[0] }); 114 | expect(proxies).to.not.deep.include({ url: 'http://127.0.0.1:' + ports[4] }); 115 | }); 116 | 117 | it('should shuffle proxies', async () => { 118 | const fProxies = fetchProxies() 119 | const balancer = new Balancer({ 120 | fetchProxies: () => fProxies, 121 | shuffle: true 122 | }); 123 | 124 | const proxies = await balancer.getProxies(); 125 | expect(proxies.map(proxy => proxy.url)).to.not.have.deep.ordered.members(fetchProxies()); 126 | }); 127 | }) 128 | 129 | context('ip limiter', () => { 130 | it('should limit requests based on callsPerDuration', async () => { 131 | let next, proxies 132 | const duration = 100 133 | const postDurationWait = 200 134 | const balancer = new Balancer({ 135 | limiter: { 136 | callsPerDuration: 2, 137 | duration, 138 | postDurationWait 139 | }, 140 | timeout: 0, 141 | fetchProxies: () => fetchProxies(1) 142 | }); 143 | 144 | singleServer = createTestServer() 145 | 146 | const call = () => balancer.request('http://127.0.0.1:8080') 147 | 148 | await call() 149 | 150 | proxies = await balancer.getProxies() 151 | next = await balancer.nextProxyIndex(proxies) 152 | expect(next).to.equal(0) 153 | 154 | await call() 155 | 156 | proxies = await balancer.getProxies() 157 | next = await balancer.nextProxyIndex(proxies) 158 | expect(next).to.equal(null) 159 | 160 | const success = true 161 | expect(success).to.be.true 162 | 163 | failure = false 164 | try { 165 | await call() 166 | } catch (err) { 167 | failure = true 168 | } 169 | expect(failure).to.be.true 170 | 171 | // wait partial duration and expect failure 172 | await delay(postDurationWait / 2) 173 | 174 | failure = false 175 | try { 176 | await call() 177 | } catch { 178 | failure = true 179 | } 180 | expect(failure).to.be.true 181 | 182 | // wait full duration and expect success 183 | await delay(postDurationWait / 2) 184 | 185 | await call() 186 | expect(success).to.be.true 187 | }) 188 | 189 | it('goes to next proxy after limit reached', async () => { 190 | let next, proxies 191 | const duration = 100 192 | const balancer = new Balancer({ 193 | callsPerDuration: 2, 194 | duration, 195 | timeout: 0, 196 | postDurationWait: 1000, 197 | fetchProxies: () => fetchProxies() 198 | }); 199 | 200 | singleServer = createTestServer() 201 | 202 | const call = () => balancer.request('http://127.0.0.1:8080') 203 | 204 | proxies = await balancer.getProxies() 205 | next = await balancer.nextProxyIndex(proxies) 206 | expect(next).to.equal(1) 207 | 208 | await call() 209 | 210 | proxies = await balancer.getProxies() 211 | next = await balancer.nextProxyIndex(proxies) 212 | expect(next).to.equal(2) 213 | 214 | 215 | await call() 216 | 217 | proxies = await balancer.getProxies() 218 | next = await balancer.nextProxyIndex(proxies) 219 | expect(next).to.equal(3) 220 | 221 | await call() 222 | 223 | proxies = await balancer.getProxies() 224 | next = await balancer.nextProxyIndex(proxies) 225 | // expect to reset to 0 226 | expect(next).to.equal(0) 227 | }) 228 | 229 | it('calls handleNoAvailableProxies when no available proxies', async () => { 230 | let noProxies 231 | const duration = 100 232 | const balancer = new Balancer({ 233 | limiter: { 234 | callsPerDuration: 1, 235 | duration, 236 | postDurationWait: 1000, 237 | }, 238 | timeout: 0, 239 | fetchProxies: () => fetchProxies(1), 240 | handleNoAvailableProxies: () => { 241 | noProxies = true 242 | } 243 | }); 244 | 245 | singleServer = createTestServer() 246 | 247 | const call = () => balancer.request('http://127.0.0.1:8080') 248 | 249 | await call() 250 | 251 | expect(!noProxies).to.be.true 252 | 253 | let fail = false 254 | try { 255 | await call() 256 | } catch { 257 | fail = true 258 | } 259 | expect(fail).to.be.true 260 | 261 | expect(noProxies).to.be.true 262 | }) 263 | }) 264 | 265 | context('base functionalities', () => { 266 | it('should use new proxy on each request - round robin', async () => { 267 | const balancer = new Balancer({ 268 | fetchProxies 269 | }); 270 | 271 | // first starts at index 0, getAndSetNext will increment 272 | const second = await balancer.getAndSetNext(); 273 | const third = await balancer.getAndSetNext(); 274 | 275 | expect(second).to.deep.equal({ url: 'http://127.0.0.1:' + ports[1] }); 276 | expect(third).to.deep.equal({ url: 'http://127.0.0.1:' + ports[2] }); 277 | }); 278 | 279 | it('should send request using proxy', (done) => { 280 | const balancer = new Balancer({ 281 | fetchProxies 282 | }); 283 | 284 | singleServer = createTestServer() 285 | 286 | balancer.request('http://127.0.0.1:8080') 287 | .then(res => res.text()) 288 | .then(body => { 289 | expect(body).to.equal('test') 290 | done(); 291 | }) 292 | }); 293 | }) 294 | 295 | context('different requestors', () => { 296 | it('should make requests successfully with axios', (done) => { 297 | const balancer = new Balancer({ 298 | requestor: axios, 299 | fetchProxies 300 | }); 301 | 302 | singleServer = createTestServer() 303 | 304 | balancer.request('http://127.0.0.1:8080') 305 | .then(res => res.data) 306 | .then(body => { 307 | expect(body).to.equal('test') 308 | done(); 309 | }) 310 | }); 311 | 312 | it('should make requests successfully with got', (done) => { 313 | const balancer = new Balancer({ 314 | requestor: got, 315 | agentFn: ({ proxy, timeout }) => ({ 316 | https: new ProxyAgent(proxy.url, { 317 | timeout 318 | }) 319 | }), 320 | fetchProxies 321 | }); 322 | 323 | singleServer = createTestServer() 324 | 325 | balancer.request('http://127.0.0.1:8080') 326 | .then(res => res.body) 327 | .then(body => { 328 | expect(body).to.equal('test') 329 | done(); 330 | }) 331 | }); 332 | }) 333 | 334 | context('different proxy agents', () => { 335 | it('should make requests successfully with tunnel', (done) => { 336 | const balancer = new Balancer({ 337 | requestor: axios, 338 | agentFn() { 339 | const agent = tunnel.httpsOverHttp({ 340 | proxy: { 341 | host: '127.0.0.1', 342 | port: ports[0], 343 | headers: { 344 | 'User-Agent': 'Node' 345 | } 346 | } 347 | }) 348 | return agent 349 | }, 350 | fetchProxies 351 | }); 352 | 353 | singleServer = createTestServer() 354 | 355 | balancer.request('http://127.0.0.1:8080') 356 | .then(res => res.data) 357 | .then(body => { 358 | expect(body).to.equal('test') 359 | done(); 360 | }) 361 | }); 362 | }) 363 | 364 | context('validateFn(..)', () => { 365 | it('should pass if true', (done) => { 366 | const balancer = new Balancer({ 367 | validateFn: (res) => { 368 | return true; 369 | }, 370 | retryFn: ({ }, { abort }) => { 371 | return abort(); 372 | }, 373 | fetchProxies 374 | }); 375 | 376 | singleServer = createTestServer() 377 | 378 | balancer.request('http://127.0.0.1:8080') 379 | .then(res => res.text()) 380 | .then(body => { 381 | expect(body).to.equal('test') 382 | done(); 383 | }) 384 | }); 385 | 386 | it('should fail if false', async () => { 387 | let err 388 | const balancer = new Balancer({ 389 | validateFn: (res) => { 390 | return false; 391 | }, 392 | retryFn: ({ error }, { abort }) => { 393 | err = error; 394 | return abort(); 395 | }, 396 | fetchProxies 397 | }); 398 | 399 | singleServer = createTestServer() 400 | 401 | // creates function wrapper 402 | sinon.spy(balancer, 'request') 403 | 404 | try { 405 | await balancer.request('http://127.0.0.1:8080') 406 | } catch { 407 | expect(balancer.request.calledOnce).to.be.true 408 | expect(err.message).to.equal('Response was not valid') 409 | } 410 | }) 411 | 412 | it('should fail on error', async () => { 413 | let err 414 | 415 | const message = "test"; 416 | const balancer = new Balancer({ 417 | validateFn: (res) => { 418 | throw new Error(message); 419 | }, 420 | retryFn: ({ error }, { abort }) => { 421 | err = error; 422 | return abort(); 423 | }, 424 | fetchProxies 425 | }); 426 | 427 | singleServer = createTestServer() 428 | 429 | // creates function wrapper 430 | sinon.spy(balancer, 'request') 431 | 432 | try { 433 | await balancer.request('http://127.0.0.1:8080') 434 | } catch { 435 | expect(balancer.request.calledOnce).to.be.true 436 | expect(err.message).to.equal(message) 437 | } 438 | }) 439 | }) 440 | 441 | context('retryFn(..)', () => { 442 | it('aborts and returns error', async () => { 443 | let err 444 | const balancer = new Balancer({ 445 | retryFn: async ({ error, retryCount, timesThisIpRetried, ipsTried }, { abort }) => { 446 | err = error 447 | return abort(); 448 | }, 449 | fetchProxies 450 | }); 451 | 452 | singleServer = createFailureServer() 453 | 454 | // creates function wrapper 455 | sinon.spy(balancer, 'request') 456 | 457 | try { 458 | await balancer.request('http://127.0.0.1:8080') 459 | } catch { 460 | const message = await err.response.text(); 461 | expect(balancer.request.calledOnce).to.be.true 462 | expect(message).to.equal('fail') 463 | } 464 | }); 465 | 466 | it('retryNextIp should include retryCount, timesThisIpRetried, and ipsTried correctly', async () => { 467 | let ipsTriedVal 468 | let retryCountVal 469 | let timesThisIpRetriedVal 470 | const balancer = new Balancer({ 471 | retryFn: ({ error, retryCount, timesThisIpRetried, ipsTried }, { retryNextIp, abort }) => { 472 | retryCountVal = retryCount 473 | ipsTriedVal = ipsTried 474 | timesThisIpRetriedVal = timesThisIpRetried 475 | return retryCount >= 2 ? abort() : retryNextIp() 476 | }, 477 | fetchProxies 478 | }); 479 | 480 | singleServer = createFailureServer() 481 | 482 | // creates function wrapper 483 | sinon.spy(balancer, 'request') 484 | 485 | try { 486 | await balancer.request('http://127.0.0.1:8080') 487 | } catch { 488 | expect(balancer.request.calledThrice).to.be.true 489 | expect(ipsTriedVal).to.equal(3) 490 | expect(retryCountVal).to.equal(2) 491 | expect(timesThisIpRetriedVal).to.equal(0) 492 | } 493 | }); 494 | 495 | it('retrySameIp should include retryCount, timesThisIpRetried, and ipsTried correctly', async () => { 496 | let ipsTriedVal 497 | let retryCountVal 498 | let timesThisIpRetriedVal 499 | const balancer = new Balancer({ 500 | retryFn: ({ error, retryCount, timesThisIpRetried, ipsTried }, { retrySameIp, abort }) => { 501 | retryCountVal = retryCount 502 | ipsTriedVal = ipsTried 503 | timesThisIpRetriedVal = timesThisIpRetried 504 | return retryCount >= 2 ? abort() : retrySameIp() 505 | }, 506 | fetchProxies 507 | }); 508 | 509 | singleServer = createFailureServer() 510 | 511 | // creates function wrapper 512 | sinon.spy(balancer, 'request') 513 | 514 | try { 515 | await balancer.request('http://127.0.0.1:8080') 516 | } catch { 517 | expect(balancer.request.calledThrice).to.be.true 518 | expect(ipsTriedVal).to.equal(1) 519 | expect(retryCountVal).to.equal(2) 520 | expect(timesThisIpRetriedVal).to.equal(2) 521 | } 522 | }); 523 | }) 524 | }); -------------------------------------------------------------------------------- /test/test-utils.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | 3 | function onRequest(req, res) { 4 | const options = { 5 | method: req.method, 6 | headers: req.headers 7 | }; 8 | 9 | let body = ''; 10 | req.on('data', (chunk) => { 11 | body += chunk.toString(); 12 | }); 13 | 14 | const data = http.request(req.url, options, (response) => { 15 | response.setEncoding('utf8'); 16 | res.writeHead(response.statusCode, response.headers); 17 | 18 | response.on('data', (chunk) => { 19 | res.write(chunk); 20 | }); 21 | response.on('close', () => { 22 | res.end(); 23 | }); 24 | response.on('end', () => { 25 | res.end(); 26 | }); 27 | }).on('error', (err) => { 28 | res.writeHead(500); 29 | res.end(); 30 | }); 31 | 32 | req.on('end', () => { 33 | data.write(body); 34 | data.end(); 35 | }) 36 | } 37 | 38 | function createProxyServer() { 39 | return http.createServer(onRequest); 40 | } 41 | 42 | function delay(ms) { 43 | return new Promise(resolve => setTimeout(resolve, ms)); 44 | } 45 | 46 | module.exports = { 47 | createProxyServer, 48 | delay 49 | } --------------------------------------------------------------------------------