├── .gitignore ├── server ├── package.json ├── index.js └── package-lock.json ├── client ├── css │ └── style.css └── index.html └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "amqplib": "^0.10.3", 14 | "cors": "^2.8.5", 15 | "dockerode": "^3.3.5", 16 | "express": "^4.18.2", 17 | "uuid": "^9.0.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /client/css/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&display=swap'); 2 | 3 | *{ 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | text-decoration: none; 8 | font-family: 'DM Sans', sans-serif; 9 | } 10 | 11 | body{ 12 | width: 100%; 13 | max-width: 1444px; 14 | margin: auto; 15 | height: 100vh; 16 | display: grid; 17 | grid-template-rows: 3fr 1fr; 18 | padding: 30px; 19 | gap: 30px; 20 | background-color: rgb(32, 34, 44); 21 | } 22 | 23 | button{ 24 | padding: 8px 10px; 25 | border: 2px solid rgb(0, 0, 0); 26 | border-radius: 10px; 27 | text-transform: uppercase; 28 | font-weight: bold; 29 | color: white; 30 | background-color: rgb(0, 0, 0); 31 | cursor: pointer; 32 | } 33 | button:hover{ 34 | scale: 1.05; 35 | } 36 | select{ 37 | padding: 5px 10px; 38 | margin-right: 15px; 39 | } 40 | 41 | section{ 42 | position: relative; 43 | } 44 | 45 | #code{ 46 | width: 100%; 47 | height: 100%; 48 | border-radius: 15px; 49 | padding: 30px; 50 | border: 2px solid rgb(46, 46, 46); 51 | resize: none; 52 | font-weight: 500; 53 | font-family: 'Courier New', Courier, monospace; 54 | background-color: rgb(41, 43, 56); 55 | outline: none; 56 | color: white; 57 | } 58 | #code:focus{ 59 | filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.3)); 60 | } 61 | 62 | .optionBtn{ 63 | position: absolute; 64 | top: 15px; 65 | right: 15px; 66 | } 67 | 68 | .output{ 69 | position: relative; 70 | } 71 | 72 | .output h4{ 73 | position: absolute; 74 | color: rgba(255, 255, 255, 0.582); 75 | top: 15px; 76 | right: 15px; 77 | } 78 | 79 | #output{ 80 | width: 100%; 81 | height: 300px; 82 | background-color: rgb(27, 27, 36); 83 | border-radius: 15px; 84 | padding: 30px; 85 | font-family: 'Courier New', Courier, monospace; 86 | color: white; 87 | overflow-y: scroll; 88 | scroll-behavior: smooth; 89 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | https://github.com/amitanshusahu/node-containerized-execution-env/assets/83657737/df6c601a-6ec1-4a5c-a8ee-7c4b29a293c9 4 | 5 |
6 | 7 | ## Set Up the Project 8 | - clone the repo 9 | ```bash 10 | git clone https://github.com/amitanshusahu/node-containerized-execution-env.git 11 | ``` 12 | - open the server folder inside the repo folder 13 | ```bash 14 | cd node-containerized-execution-env/server 15 | ``` 16 | 17 | - install all dependencies 18 | ```bash 19 | npm i 20 | ``` 21 | - pull node and gcc docker image 22 | ```bash 23 | # pull latest node image 24 | docker pull node 25 | # pull latest gcc image 26 | docker pull gcc 27 | ``` 28 | - run RabbitMq and bind it to port 5672 in a terminal instance 29 | ```bash 30 | docker run \ 31 | -p 5672:5672 \ 32 | rabbitmq 33 | ``` 34 | - open another terminal instance and run the node server, from server folder 35 | ```bash 36 | # go to server folder 37 | cd server 38 | # start the server 39 | npm start 40 | ``` 41 | - open another terminal instance and serve the index.html, from client folder 42 | ```bash 43 | # go from server folder to client folder 44 | cd ../client 45 | # create a static server 46 | npx serve 47 | ``` 48 | 49 | > make sure `3000`, `3010`, `5672` are not bussyyyy!! 50 | 51 | ## load test 52 | - install loadtest 53 | ```bash 54 | npm i -g loadtest 55 | ``` 56 | 57 | - test the server 58 | ```bash 59 | # send 1000 reqs with an concorency level 100 60 | loadtest -n 1000 -c 100 http://localhost:3010 61 | ``` 62 | 63 | ## References 64 | - [Remote Code Execution System just like kirat said](https://blog.devgenius.io/case-study-remote-code-execution-engine-system-63aa43344f24) 65 | - [Using RabbitMQ in node js app](https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html) 66 | - [Docker Engine API to create and work with containers](https://docs.docker.com/engine/api/v1.42/#tag/Container/operation/ContainerCreate) 67 | - [An Implementation of the Docker API as node package - Dockerode](https://github.com/apocas/dockerode) 68 | - [Running Docker/Commnds using "child-process" module in node js (exec, spwan)](https://stackoverflow.com/questions/35644155/how-can-i-dynamically-create-a-docker-container-from-a-node-application) 69 | - [Parallel Processing/Multithreading in node js](https://deepsource.com/blog/nodejs-worker-threads/) 70 | - __Video Tutorials__ 71 | - [What are Messagin queue, RabbitMQ pub/sub with nodjs](https://youtu.be/e03c3CIGtYU) 72 | - [Docker Tutorial, all about docker](https://youtu.be/3c-iBn73dDE) 73 | - [Scale node js app using cluster module and test it with loadTest](https://youtu.be/9RLeLngtQ3A) 74 | 75 | 76 |

Star the Repo ⭐

77 | -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 |
18 | 23 | 24 |
25 | 26 |
27 | 28 |
29 |

Terminal (read only)

30 |
31 |
32 | 33 | 34 | 35 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const app = express() 3 | const port = 3010 4 | const cors = require("cors"); 5 | const docker = new require("dockerode")(); 6 | const amqp = require("amqplib"); 7 | const { v4: uuidv4 } = require('uuid'); 8 | const cluster = require("cluster"); 9 | const os = require("os"); 10 | 11 | 12 | 13 | 14 | /// ------------- MIDDLEWARES ------------------ 15 | 16 | app.use(express.json()); 17 | app.use(cors()); 18 | 19 | 20 | 21 | 22 | /// ------------------ RCP SERVER(WORKER) ------------------- 23 | 24 | async function startRcpServerAsWorker() { 25 | 26 | //connect to rabbitmq 27 | const { connection, channel } = await connectRabbitMQ(); 28 | 29 | // declare rcpcodeexecutionqueue 30 | channel.prefetch(1); // limit the no. of unack msg, fetch only one msg 31 | channel.assertQueue(codeExecutionQueue); 32 | 33 | // consumer for rcpCodeExecutionQueue 34 | channel.consume(codeExecutionQueue, async msg => { 35 | 36 | const { code, language } = JSON.parse(msg.content.toString()); 37 | 38 | try { 39 | // process the rcp request / execute code inside container 40 | const executionResult = await executeUserCodeInContainer(code, language); 41 | 42 | // publish the result to the response queue 43 | channel.sendToQueue(msg.properties.replyTo, Buffer.from(JSON.stringify(executionResult)), { 44 | correlationId: msg.properties.correlationId 45 | }); 46 | 47 | // acknowledge the message (dqueue) 48 | channel.ack(msg); 49 | } 50 | catch (err) { 51 | console.log("Error processing RCP request for execution: ", err); 52 | process.exit(1); // terminate 53 | } 54 | 55 | }); 56 | 57 | } 58 | 59 | 60 | 61 | 62 | /// --------------- RPC CLIENT ---------------- 63 | 64 | const codeExecutionQueue = "rpcCodeExecutionQueue"; 65 | 66 | // Connect to rabbit mq 67 | async function connectRabbitMQ() { 68 | 69 | const connection = await amqp.connect("amqp://localhost:5672"); 70 | const channel = await connection.createChannel(); 71 | return{ connection, channel}; 72 | 73 | } 74 | 75 | // Publish message to queue 76 | async function publishMessageToCodeExecutionQueue(connection, channel, code, language, res) { 77 | 78 | // set up responsequeue (temp) 79 | const responseQueue = await channel.assertQueue("", { exclusive: true }); 80 | const responseQueueName = responseQueue.queue; 81 | 82 | const correlationId = uuidv4(); 83 | 84 | // consumer for the response queue 85 | channel.consume(responseQueueName, msg => { 86 | if (msg.properties.correlationId == correlationId) { 87 | const result = JSON.parse(msg.content.toString()); 88 | res.status(200).json(result); 89 | console.log(result.result); 90 | channel.close(); 91 | connection.close(); 92 | } 93 | }, { noAck: true }); 94 | 95 | // publish msg(code) to rcpcodeExecutionQueue / send rcp request 96 | channel.sendToQueue(codeExecutionQueue, Buffer.from(JSON.stringify({ code, language })), { 97 | correlationId, 98 | replyTo: responseQueueName 99 | }); 100 | 101 | } 102 | 103 | 104 | 105 | 106 | /// ----------------- DOCKER LOGIC ---------------------- 107 | 108 | // Create container according to user selected language 109 | async function createDockerContainer(language, code) { 110 | 111 | const containerConfig = { 112 | Image: getDockerImage(language), //node 113 | Cmd: getExecutionCommand(language, code), // ["node", "-e", code] 114 | Tty: true, 115 | // HostConfig: { 116 | // StopTimeout: 2, // Stop the container after 2 seconds 117 | // }, 118 | } 119 | // same as docker create --image imageName --tty --command cmdToRun 120 | const container = await docker.createContainer(containerConfig) 121 | 122 | return container; 123 | 124 | } 125 | 126 | // helper fun to get image according to user Selected language 127 | function getDockerImage(language) { 128 | 129 | let image; 130 | 131 | switch (language) { 132 | case 'cpp': 133 | image = "gcc" 134 | break; 135 | case "js": 136 | image = "node"; 137 | break; 138 | case "c": 139 | image = "gcc"; 140 | break; 141 | default: 142 | throw new Error(`unsupprted language: ${language}`); 143 | } 144 | 145 | return image; 146 | 147 | } 148 | 149 | // helper fun to get Execution command acc... to user selected language 150 | function getExecutionCommand(language, code){ 151 | 152 | let cmd; 153 | 154 | switch (language) { 155 | case 'cpp': 156 | cmd = ['bash', '-c', `echo "${code}" > myapp.cpp && g++ -o myapp myapp.cpp && ./myapp`]; 157 | break; 158 | case "js": 159 | cmd = ["node", "-e", code]; 160 | break; 161 | case "c": 162 | console.log(code); 163 | cmd = ['bash', '-c', `echo "${code}" > myapp.c && gcc -o myapp myapp.c && ./myapp`]; 164 | break; 165 | default: 166 | throw new Error(`unsupprted language: ${language}`); 167 | } 168 | 169 | return cmd; 170 | 171 | } 172 | 173 | 174 | 175 | 176 | /// ------------------- CODE EXECUTION LOGIC ----------------- 177 | 178 | async function executeUserCodeInContainer(code, language) { 179 | return new Promise(async (resolve, reject) => { 180 | console.log("executing code"); 181 | const container = await createDockerContainer(language, code); 182 | await container.start(); 183 | 184 | // send a TLE after 2sec 185 | const tle = setTimeout(async () => { 186 | console.log("sending a tle") 187 | resolve({result: "Time Limit Exceed!! 😔 \n \n - Optimize your code \n - Avoid infinite loops", sucess: false}); 188 | await container.stop(); 189 | }, 2000); 190 | 191 | const containerExitStatus = await container.wait(); // wait for container to exit 192 | 193 | // get logs 194 | const logs = await container.logs({ stdout: true, stderr: true }); 195 | 196 | // return output/error 197 | if (containerExitStatus.StatusCode === 0) { 198 | resolve({ result: logs.toString(), sucess: true }); 199 | clearTimeout(tle); 200 | await container.remove(); 201 | } else { 202 | resolve({ result: logs.toString(), sucess: false }); 203 | clearTimeout(tle); 204 | await container.remove(); 205 | } 206 | }); 207 | } 208 | 209 | 210 | 211 | 212 | ///----------------- ROUTES ----------------------- 213 | 214 | app.post("/submissions", async (req, res) => { 215 | let body = req.body; 216 | let userSubmittedCode = body.submission.code; 217 | let codeLanguage = body.submission.language; 218 | 219 | try { 220 | 221 | const { connection, channel } = await connectRabbitMQ(); 222 | await publishMessageToCodeExecutionQueue(connection, channel, userSubmittedCode, codeLanguage, res); 223 | 224 | } 225 | catch (er) { 226 | console.log("Error Publishing message to RcpCodeExecution queue", er); 227 | res.status(500).json({ err: "Somethig Went Wrong" }); 228 | } 229 | 230 | }); 231 | 232 | 233 | 234 | 235 | /// ------------- SCALE USING CLUSTER ---------------- 236 | 237 | // get cpu threads 238 | let cpuThreads = os.cpus().length; // 12 (my i5 12400) 239 | if ( cpuThreads >= 4 ) cpuNum = 4; // limit worker to 4 240 | 241 | if (cluster.isMaster) { 242 | for (let i = 0; i < cpuNum; i++) { 243 | cluster.fork(); 244 | } 245 | 246 | cluster.on("exit", (worker, code, signal) => { 247 | console.log(`worker ${worker.process.pid} exited`); 248 | cluster.fork(); 249 | }); 250 | } 251 | else { 252 | startRcpServerAsWorker(); 253 | 254 | const server = app.listen(port, () => { 255 | console.log(`server ${process.pid} is listening on port ${port}`) 256 | }) 257 | 258 | server.on('error', (error) => { 259 | if (error.code === 'EADDRINUSE') { 260 | console.log(`Port ${port} is already in use`); 261 | } else { 262 | console.error('An error occurred:', error); 263 | } 264 | }); 265 | } -------------------------------------------------------------------------------- /server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "server", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "amqplib": "^0.10.3", 13 | "cors": "^2.8.5", 14 | "dockerode": "^3.3.5", 15 | "express": "^4.18.2", 16 | "uuid": "^9.0.0" 17 | } 18 | }, 19 | "node_modules/@acuminous/bitsyntax": { 20 | "version": "0.1.2", 21 | "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", 22 | "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", 23 | "dependencies": { 24 | "buffer-more-ints": "~1.0.0", 25 | "debug": "^4.3.4", 26 | "safe-buffer": "~5.1.2" 27 | }, 28 | "engines": { 29 | "node": ">=0.8" 30 | } 31 | }, 32 | "node_modules/@balena/dockerignore": { 33 | "version": "1.0.2", 34 | "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", 35 | "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==" 36 | }, 37 | "node_modules/accepts": { 38 | "version": "1.3.8", 39 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 40 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 41 | "dependencies": { 42 | "mime-types": "~2.1.34", 43 | "negotiator": "0.6.3" 44 | }, 45 | "engines": { 46 | "node": ">= 0.6" 47 | } 48 | }, 49 | "node_modules/amqplib": { 50 | "version": "0.10.3", 51 | "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", 52 | "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", 53 | "dependencies": { 54 | "@acuminous/bitsyntax": "^0.1.2", 55 | "buffer-more-ints": "~1.0.0", 56 | "readable-stream": "1.x >=1.1.9", 57 | "url-parse": "~1.5.10" 58 | }, 59 | "engines": { 60 | "node": ">=10" 61 | } 62 | }, 63 | "node_modules/array-flatten": { 64 | "version": "1.1.1", 65 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 66 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 67 | }, 68 | "node_modules/asn1": { 69 | "version": "0.2.6", 70 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", 71 | "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", 72 | "dependencies": { 73 | "safer-buffer": "~2.1.0" 74 | } 75 | }, 76 | "node_modules/base64-js": { 77 | "version": "1.5.1", 78 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 79 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 80 | "funding": [ 81 | { 82 | "type": "github", 83 | "url": "https://github.com/sponsors/feross" 84 | }, 85 | { 86 | "type": "patreon", 87 | "url": "https://www.patreon.com/feross" 88 | }, 89 | { 90 | "type": "consulting", 91 | "url": "https://feross.org/support" 92 | } 93 | ] 94 | }, 95 | "node_modules/bcrypt-pbkdf": { 96 | "version": "1.0.2", 97 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 98 | "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", 99 | "dependencies": { 100 | "tweetnacl": "^0.14.3" 101 | } 102 | }, 103 | "node_modules/bl": { 104 | "version": "4.1.0", 105 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", 106 | "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", 107 | "dependencies": { 108 | "buffer": "^5.5.0", 109 | "inherits": "^2.0.4", 110 | "readable-stream": "^3.4.0" 111 | } 112 | }, 113 | "node_modules/bl/node_modules/readable-stream": { 114 | "version": "3.6.2", 115 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 116 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 117 | "dependencies": { 118 | "inherits": "^2.0.3", 119 | "string_decoder": "^1.1.1", 120 | "util-deprecate": "^1.0.1" 121 | }, 122 | "engines": { 123 | "node": ">= 6" 124 | } 125 | }, 126 | "node_modules/bl/node_modules/safe-buffer": { 127 | "version": "5.2.1", 128 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 129 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 130 | "funding": [ 131 | { 132 | "type": "github", 133 | "url": "https://github.com/sponsors/feross" 134 | }, 135 | { 136 | "type": "patreon", 137 | "url": "https://www.patreon.com/feross" 138 | }, 139 | { 140 | "type": "consulting", 141 | "url": "https://feross.org/support" 142 | } 143 | ] 144 | }, 145 | "node_modules/bl/node_modules/string_decoder": { 146 | "version": "1.3.0", 147 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 148 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 149 | "dependencies": { 150 | "safe-buffer": "~5.2.0" 151 | } 152 | }, 153 | "node_modules/body-parser": { 154 | "version": "1.20.1", 155 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 156 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 157 | "dependencies": { 158 | "bytes": "3.1.2", 159 | "content-type": "~1.0.4", 160 | "debug": "2.6.9", 161 | "depd": "2.0.0", 162 | "destroy": "1.2.0", 163 | "http-errors": "2.0.0", 164 | "iconv-lite": "0.4.24", 165 | "on-finished": "2.4.1", 166 | "qs": "6.11.0", 167 | "raw-body": "2.5.1", 168 | "type-is": "~1.6.18", 169 | "unpipe": "1.0.0" 170 | }, 171 | "engines": { 172 | "node": ">= 0.8", 173 | "npm": "1.2.8000 || >= 1.4.16" 174 | } 175 | }, 176 | "node_modules/body-parser/node_modules/debug": { 177 | "version": "2.6.9", 178 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 179 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 180 | "dependencies": { 181 | "ms": "2.0.0" 182 | } 183 | }, 184 | "node_modules/body-parser/node_modules/ms": { 185 | "version": "2.0.0", 186 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 187 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 188 | }, 189 | "node_modules/buffer": { 190 | "version": "5.7.1", 191 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 192 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 193 | "funding": [ 194 | { 195 | "type": "github", 196 | "url": "https://github.com/sponsors/feross" 197 | }, 198 | { 199 | "type": "patreon", 200 | "url": "https://www.patreon.com/feross" 201 | }, 202 | { 203 | "type": "consulting", 204 | "url": "https://feross.org/support" 205 | } 206 | ], 207 | "dependencies": { 208 | "base64-js": "^1.3.1", 209 | "ieee754": "^1.1.13" 210 | } 211 | }, 212 | "node_modules/buffer-more-ints": { 213 | "version": "1.0.0", 214 | "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", 215 | "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" 216 | }, 217 | "node_modules/buildcheck": { 218 | "version": "0.0.6", 219 | "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz", 220 | "integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==", 221 | "optional": true, 222 | "engines": { 223 | "node": ">=10.0.0" 224 | } 225 | }, 226 | "node_modules/bytes": { 227 | "version": "3.1.2", 228 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 229 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 230 | "engines": { 231 | "node": ">= 0.8" 232 | } 233 | }, 234 | "node_modules/call-bind": { 235 | "version": "1.0.2", 236 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 237 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 238 | "dependencies": { 239 | "function-bind": "^1.1.1", 240 | "get-intrinsic": "^1.0.2" 241 | }, 242 | "funding": { 243 | "url": "https://github.com/sponsors/ljharb" 244 | } 245 | }, 246 | "node_modules/chownr": { 247 | "version": "1.1.4", 248 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 249 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" 250 | }, 251 | "node_modules/content-disposition": { 252 | "version": "0.5.4", 253 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 254 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 255 | "dependencies": { 256 | "safe-buffer": "5.2.1" 257 | }, 258 | "engines": { 259 | "node": ">= 0.6" 260 | } 261 | }, 262 | "node_modules/content-disposition/node_modules/safe-buffer": { 263 | "version": "5.2.1", 264 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 265 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 266 | "funding": [ 267 | { 268 | "type": "github", 269 | "url": "https://github.com/sponsors/feross" 270 | }, 271 | { 272 | "type": "patreon", 273 | "url": "https://www.patreon.com/feross" 274 | }, 275 | { 276 | "type": "consulting", 277 | "url": "https://feross.org/support" 278 | } 279 | ] 280 | }, 281 | "node_modules/content-type": { 282 | "version": "1.0.5", 283 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 284 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 285 | "engines": { 286 | "node": ">= 0.6" 287 | } 288 | }, 289 | "node_modules/cookie": { 290 | "version": "0.5.0", 291 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 292 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 293 | "engines": { 294 | "node": ">= 0.6" 295 | } 296 | }, 297 | "node_modules/cookie-signature": { 298 | "version": "1.0.6", 299 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 300 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 301 | }, 302 | "node_modules/core-util-is": { 303 | "version": "1.0.3", 304 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", 305 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" 306 | }, 307 | "node_modules/cors": { 308 | "version": "2.8.5", 309 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 310 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 311 | "dependencies": { 312 | "object-assign": "^4", 313 | "vary": "^1" 314 | }, 315 | "engines": { 316 | "node": ">= 0.10" 317 | } 318 | }, 319 | "node_modules/cpu-features": { 320 | "version": "0.0.7", 321 | "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.7.tgz", 322 | "integrity": "sha512-fjzFmsUKKCrC9GrM1eQTvQx18e+kjXFzjRLvJPNEDjk31+bJ6ZiV6uchv/hzbzXVIgbWdrEyyX1IFKwse65+8w==", 323 | "hasInstallScript": true, 324 | "optional": true, 325 | "dependencies": { 326 | "buildcheck": "~0.0.6", 327 | "nan": "^2.17.0" 328 | }, 329 | "engines": { 330 | "node": ">=10.0.0" 331 | } 332 | }, 333 | "node_modules/debug": { 334 | "version": "4.3.4", 335 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 336 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 337 | "dependencies": { 338 | "ms": "2.1.2" 339 | }, 340 | "engines": { 341 | "node": ">=6.0" 342 | }, 343 | "peerDependenciesMeta": { 344 | "supports-color": { 345 | "optional": true 346 | } 347 | } 348 | }, 349 | "node_modules/depd": { 350 | "version": "2.0.0", 351 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 352 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 353 | "engines": { 354 | "node": ">= 0.8" 355 | } 356 | }, 357 | "node_modules/destroy": { 358 | "version": "1.2.0", 359 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 360 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 361 | "engines": { 362 | "node": ">= 0.8", 363 | "npm": "1.2.8000 || >= 1.4.16" 364 | } 365 | }, 366 | "node_modules/docker-modem": { 367 | "version": "3.0.8", 368 | "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.8.tgz", 369 | "integrity": "sha512-f0ReSURdM3pcKPNS30mxOHSbaFLcknGmQjwSfmbcdOw1XWKXVhukM3NJHhr7NpY9BIyyWQb0EBo3KQvvuU5egQ==", 370 | "dependencies": { 371 | "debug": "^4.1.1", 372 | "readable-stream": "^3.5.0", 373 | "split-ca": "^1.0.1", 374 | "ssh2": "^1.11.0" 375 | }, 376 | "engines": { 377 | "node": ">= 8.0" 378 | } 379 | }, 380 | "node_modules/docker-modem/node_modules/readable-stream": { 381 | "version": "3.6.2", 382 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 383 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 384 | "dependencies": { 385 | "inherits": "^2.0.3", 386 | "string_decoder": "^1.1.1", 387 | "util-deprecate": "^1.0.1" 388 | }, 389 | "engines": { 390 | "node": ">= 6" 391 | } 392 | }, 393 | "node_modules/docker-modem/node_modules/safe-buffer": { 394 | "version": "5.2.1", 395 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 396 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 397 | "funding": [ 398 | { 399 | "type": "github", 400 | "url": "https://github.com/sponsors/feross" 401 | }, 402 | { 403 | "type": "patreon", 404 | "url": "https://www.patreon.com/feross" 405 | }, 406 | { 407 | "type": "consulting", 408 | "url": "https://feross.org/support" 409 | } 410 | ] 411 | }, 412 | "node_modules/docker-modem/node_modules/string_decoder": { 413 | "version": "1.3.0", 414 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 415 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 416 | "dependencies": { 417 | "safe-buffer": "~5.2.0" 418 | } 419 | }, 420 | "node_modules/dockerode": { 421 | "version": "3.3.5", 422 | "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.3.5.tgz", 423 | "integrity": "sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA==", 424 | "dependencies": { 425 | "@balena/dockerignore": "^1.0.2", 426 | "docker-modem": "^3.0.0", 427 | "tar-fs": "~2.0.1" 428 | }, 429 | "engines": { 430 | "node": ">= 8.0" 431 | } 432 | }, 433 | "node_modules/ee-first": { 434 | "version": "1.1.1", 435 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 436 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 437 | }, 438 | "node_modules/encodeurl": { 439 | "version": "1.0.2", 440 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 441 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 442 | "engines": { 443 | "node": ">= 0.8" 444 | } 445 | }, 446 | "node_modules/end-of-stream": { 447 | "version": "1.4.4", 448 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 449 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 450 | "dependencies": { 451 | "once": "^1.4.0" 452 | } 453 | }, 454 | "node_modules/escape-html": { 455 | "version": "1.0.3", 456 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 457 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 458 | }, 459 | "node_modules/etag": { 460 | "version": "1.8.1", 461 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 462 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 463 | "engines": { 464 | "node": ">= 0.6" 465 | } 466 | }, 467 | "node_modules/express": { 468 | "version": "4.18.2", 469 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 470 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 471 | "dependencies": { 472 | "accepts": "~1.3.8", 473 | "array-flatten": "1.1.1", 474 | "body-parser": "1.20.1", 475 | "content-disposition": "0.5.4", 476 | "content-type": "~1.0.4", 477 | "cookie": "0.5.0", 478 | "cookie-signature": "1.0.6", 479 | "debug": "2.6.9", 480 | "depd": "2.0.0", 481 | "encodeurl": "~1.0.2", 482 | "escape-html": "~1.0.3", 483 | "etag": "~1.8.1", 484 | "finalhandler": "1.2.0", 485 | "fresh": "0.5.2", 486 | "http-errors": "2.0.0", 487 | "merge-descriptors": "1.0.1", 488 | "methods": "~1.1.2", 489 | "on-finished": "2.4.1", 490 | "parseurl": "~1.3.3", 491 | "path-to-regexp": "0.1.7", 492 | "proxy-addr": "~2.0.7", 493 | "qs": "6.11.0", 494 | "range-parser": "~1.2.1", 495 | "safe-buffer": "5.2.1", 496 | "send": "0.18.0", 497 | "serve-static": "1.15.0", 498 | "setprototypeof": "1.2.0", 499 | "statuses": "2.0.1", 500 | "type-is": "~1.6.18", 501 | "utils-merge": "1.0.1", 502 | "vary": "~1.1.2" 503 | }, 504 | "engines": { 505 | "node": ">= 0.10.0" 506 | } 507 | }, 508 | "node_modules/express/node_modules/debug": { 509 | "version": "2.6.9", 510 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 511 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 512 | "dependencies": { 513 | "ms": "2.0.0" 514 | } 515 | }, 516 | "node_modules/express/node_modules/ms": { 517 | "version": "2.0.0", 518 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 519 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 520 | }, 521 | "node_modules/express/node_modules/safe-buffer": { 522 | "version": "5.2.1", 523 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 524 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 525 | "funding": [ 526 | { 527 | "type": "github", 528 | "url": "https://github.com/sponsors/feross" 529 | }, 530 | { 531 | "type": "patreon", 532 | "url": "https://www.patreon.com/feross" 533 | }, 534 | { 535 | "type": "consulting", 536 | "url": "https://feross.org/support" 537 | } 538 | ] 539 | }, 540 | "node_modules/finalhandler": { 541 | "version": "1.2.0", 542 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 543 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 544 | "dependencies": { 545 | "debug": "2.6.9", 546 | "encodeurl": "~1.0.2", 547 | "escape-html": "~1.0.3", 548 | "on-finished": "2.4.1", 549 | "parseurl": "~1.3.3", 550 | "statuses": "2.0.1", 551 | "unpipe": "~1.0.0" 552 | }, 553 | "engines": { 554 | "node": ">= 0.8" 555 | } 556 | }, 557 | "node_modules/finalhandler/node_modules/debug": { 558 | "version": "2.6.9", 559 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 560 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 561 | "dependencies": { 562 | "ms": "2.0.0" 563 | } 564 | }, 565 | "node_modules/finalhandler/node_modules/ms": { 566 | "version": "2.0.0", 567 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 568 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 569 | }, 570 | "node_modules/forwarded": { 571 | "version": "0.2.0", 572 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 573 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 574 | "engines": { 575 | "node": ">= 0.6" 576 | } 577 | }, 578 | "node_modules/fresh": { 579 | "version": "0.5.2", 580 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 581 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 582 | "engines": { 583 | "node": ">= 0.6" 584 | } 585 | }, 586 | "node_modules/fs-constants": { 587 | "version": "1.0.0", 588 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 589 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" 590 | }, 591 | "node_modules/function-bind": { 592 | "version": "1.1.1", 593 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 594 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 595 | }, 596 | "node_modules/get-intrinsic": { 597 | "version": "1.2.0", 598 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", 599 | "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", 600 | "dependencies": { 601 | "function-bind": "^1.1.1", 602 | "has": "^1.0.3", 603 | "has-symbols": "^1.0.3" 604 | }, 605 | "funding": { 606 | "url": "https://github.com/sponsors/ljharb" 607 | } 608 | }, 609 | "node_modules/has": { 610 | "version": "1.0.3", 611 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 612 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 613 | "dependencies": { 614 | "function-bind": "^1.1.1" 615 | }, 616 | "engines": { 617 | "node": ">= 0.4.0" 618 | } 619 | }, 620 | "node_modules/has-symbols": { 621 | "version": "1.0.3", 622 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 623 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 624 | "engines": { 625 | "node": ">= 0.4" 626 | }, 627 | "funding": { 628 | "url": "https://github.com/sponsors/ljharb" 629 | } 630 | }, 631 | "node_modules/http-errors": { 632 | "version": "2.0.0", 633 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 634 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 635 | "dependencies": { 636 | "depd": "2.0.0", 637 | "inherits": "2.0.4", 638 | "setprototypeof": "1.2.0", 639 | "statuses": "2.0.1", 640 | "toidentifier": "1.0.1" 641 | }, 642 | "engines": { 643 | "node": ">= 0.8" 644 | } 645 | }, 646 | "node_modules/iconv-lite": { 647 | "version": "0.4.24", 648 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 649 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 650 | "dependencies": { 651 | "safer-buffer": ">= 2.1.2 < 3" 652 | }, 653 | "engines": { 654 | "node": ">=0.10.0" 655 | } 656 | }, 657 | "node_modules/ieee754": { 658 | "version": "1.2.1", 659 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 660 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 661 | "funding": [ 662 | { 663 | "type": "github", 664 | "url": "https://github.com/sponsors/feross" 665 | }, 666 | { 667 | "type": "patreon", 668 | "url": "https://www.patreon.com/feross" 669 | }, 670 | { 671 | "type": "consulting", 672 | "url": "https://feross.org/support" 673 | } 674 | ] 675 | }, 676 | "node_modules/inherits": { 677 | "version": "2.0.4", 678 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 679 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 680 | }, 681 | "node_modules/ipaddr.js": { 682 | "version": "1.9.1", 683 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 684 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 685 | "engines": { 686 | "node": ">= 0.10" 687 | } 688 | }, 689 | "node_modules/isarray": { 690 | "version": "0.0.1", 691 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 692 | "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" 693 | }, 694 | "node_modules/media-typer": { 695 | "version": "0.3.0", 696 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 697 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 698 | "engines": { 699 | "node": ">= 0.6" 700 | } 701 | }, 702 | "node_modules/merge-descriptors": { 703 | "version": "1.0.1", 704 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 705 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 706 | }, 707 | "node_modules/methods": { 708 | "version": "1.1.2", 709 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 710 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 711 | "engines": { 712 | "node": ">= 0.6" 713 | } 714 | }, 715 | "node_modules/mime": { 716 | "version": "1.6.0", 717 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 718 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 719 | "bin": { 720 | "mime": "cli.js" 721 | }, 722 | "engines": { 723 | "node": ">=4" 724 | } 725 | }, 726 | "node_modules/mime-db": { 727 | "version": "1.52.0", 728 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 729 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 730 | "engines": { 731 | "node": ">= 0.6" 732 | } 733 | }, 734 | "node_modules/mime-types": { 735 | "version": "2.1.35", 736 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 737 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 738 | "dependencies": { 739 | "mime-db": "1.52.0" 740 | }, 741 | "engines": { 742 | "node": ">= 0.6" 743 | } 744 | }, 745 | "node_modules/mkdirp-classic": { 746 | "version": "0.5.3", 747 | "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", 748 | "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" 749 | }, 750 | "node_modules/ms": { 751 | "version": "2.1.2", 752 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 753 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 754 | }, 755 | "node_modules/nan": { 756 | "version": "2.17.0", 757 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", 758 | "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", 759 | "optional": true 760 | }, 761 | "node_modules/negotiator": { 762 | "version": "0.6.3", 763 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 764 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 765 | "engines": { 766 | "node": ">= 0.6" 767 | } 768 | }, 769 | "node_modules/object-assign": { 770 | "version": "4.1.1", 771 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 772 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 773 | "engines": { 774 | "node": ">=0.10.0" 775 | } 776 | }, 777 | "node_modules/object-inspect": { 778 | "version": "1.12.3", 779 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", 780 | "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", 781 | "funding": { 782 | "url": "https://github.com/sponsors/ljharb" 783 | } 784 | }, 785 | "node_modules/on-finished": { 786 | "version": "2.4.1", 787 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 788 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 789 | "dependencies": { 790 | "ee-first": "1.1.1" 791 | }, 792 | "engines": { 793 | "node": ">= 0.8" 794 | } 795 | }, 796 | "node_modules/once": { 797 | "version": "1.4.0", 798 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 799 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 800 | "dependencies": { 801 | "wrappy": "1" 802 | } 803 | }, 804 | "node_modules/parseurl": { 805 | "version": "1.3.3", 806 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 807 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 808 | "engines": { 809 | "node": ">= 0.8" 810 | } 811 | }, 812 | "node_modules/path-to-regexp": { 813 | "version": "0.1.7", 814 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 815 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 816 | }, 817 | "node_modules/proxy-addr": { 818 | "version": "2.0.7", 819 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 820 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 821 | "dependencies": { 822 | "forwarded": "0.2.0", 823 | "ipaddr.js": "1.9.1" 824 | }, 825 | "engines": { 826 | "node": ">= 0.10" 827 | } 828 | }, 829 | "node_modules/pump": { 830 | "version": "3.0.0", 831 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 832 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 833 | "dependencies": { 834 | "end-of-stream": "^1.1.0", 835 | "once": "^1.3.1" 836 | } 837 | }, 838 | "node_modules/qs": { 839 | "version": "6.11.0", 840 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 841 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 842 | "dependencies": { 843 | "side-channel": "^1.0.4" 844 | }, 845 | "engines": { 846 | "node": ">=0.6" 847 | }, 848 | "funding": { 849 | "url": "https://github.com/sponsors/ljharb" 850 | } 851 | }, 852 | "node_modules/querystringify": { 853 | "version": "2.2.0", 854 | "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", 855 | "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" 856 | }, 857 | "node_modules/range-parser": { 858 | "version": "1.2.1", 859 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 860 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 861 | "engines": { 862 | "node": ">= 0.6" 863 | } 864 | }, 865 | "node_modules/raw-body": { 866 | "version": "2.5.1", 867 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 868 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 869 | "dependencies": { 870 | "bytes": "3.1.2", 871 | "http-errors": "2.0.0", 872 | "iconv-lite": "0.4.24", 873 | "unpipe": "1.0.0" 874 | }, 875 | "engines": { 876 | "node": ">= 0.8" 877 | } 878 | }, 879 | "node_modules/readable-stream": { 880 | "version": "1.1.14", 881 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 882 | "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", 883 | "dependencies": { 884 | "core-util-is": "~1.0.0", 885 | "inherits": "~2.0.1", 886 | "isarray": "0.0.1", 887 | "string_decoder": "~0.10.x" 888 | } 889 | }, 890 | "node_modules/requires-port": { 891 | "version": "1.0.0", 892 | "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", 893 | "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" 894 | }, 895 | "node_modules/safe-buffer": { 896 | "version": "5.1.2", 897 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 898 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 899 | }, 900 | "node_modules/safer-buffer": { 901 | "version": "2.1.2", 902 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 903 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 904 | }, 905 | "node_modules/send": { 906 | "version": "0.18.0", 907 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 908 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 909 | "dependencies": { 910 | "debug": "2.6.9", 911 | "depd": "2.0.0", 912 | "destroy": "1.2.0", 913 | "encodeurl": "~1.0.2", 914 | "escape-html": "~1.0.3", 915 | "etag": "~1.8.1", 916 | "fresh": "0.5.2", 917 | "http-errors": "2.0.0", 918 | "mime": "1.6.0", 919 | "ms": "2.1.3", 920 | "on-finished": "2.4.1", 921 | "range-parser": "~1.2.1", 922 | "statuses": "2.0.1" 923 | }, 924 | "engines": { 925 | "node": ">= 0.8.0" 926 | } 927 | }, 928 | "node_modules/send/node_modules/debug": { 929 | "version": "2.6.9", 930 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 931 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 932 | "dependencies": { 933 | "ms": "2.0.0" 934 | } 935 | }, 936 | "node_modules/send/node_modules/debug/node_modules/ms": { 937 | "version": "2.0.0", 938 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 939 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 940 | }, 941 | "node_modules/send/node_modules/ms": { 942 | "version": "2.1.3", 943 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 944 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 945 | }, 946 | "node_modules/serve-static": { 947 | "version": "1.15.0", 948 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 949 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 950 | "dependencies": { 951 | "encodeurl": "~1.0.2", 952 | "escape-html": "~1.0.3", 953 | "parseurl": "~1.3.3", 954 | "send": "0.18.0" 955 | }, 956 | "engines": { 957 | "node": ">= 0.8.0" 958 | } 959 | }, 960 | "node_modules/setprototypeof": { 961 | "version": "1.2.0", 962 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 963 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 964 | }, 965 | "node_modules/side-channel": { 966 | "version": "1.0.4", 967 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 968 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 969 | "dependencies": { 970 | "call-bind": "^1.0.0", 971 | "get-intrinsic": "^1.0.2", 972 | "object-inspect": "^1.9.0" 973 | }, 974 | "funding": { 975 | "url": "https://github.com/sponsors/ljharb" 976 | } 977 | }, 978 | "node_modules/split-ca": { 979 | "version": "1.0.1", 980 | "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", 981 | "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==" 982 | }, 983 | "node_modules/ssh2": { 984 | "version": "1.12.0", 985 | "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.12.0.tgz", 986 | "integrity": "sha512-7mcLu8biO6/BjQQ1iCjCmuBiF0hXxo+JlHpJBPDTVsxU7evscWWiRUgYF5XIs4gLKmiPRHA0maund11QLWyDJg==", 987 | "hasInstallScript": true, 988 | "dependencies": { 989 | "asn1": "^0.2.4", 990 | "bcrypt-pbkdf": "^1.0.2" 991 | }, 992 | "engines": { 993 | "node": ">=10.16.0" 994 | }, 995 | "optionalDependencies": { 996 | "cpu-features": "~0.0.6", 997 | "nan": "^2.17.0" 998 | } 999 | }, 1000 | "node_modules/statuses": { 1001 | "version": "2.0.1", 1002 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1003 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1004 | "engines": { 1005 | "node": ">= 0.8" 1006 | } 1007 | }, 1008 | "node_modules/string_decoder": { 1009 | "version": "0.10.31", 1010 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 1011 | "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" 1012 | }, 1013 | "node_modules/tar-fs": { 1014 | "version": "2.0.1", 1015 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", 1016 | "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", 1017 | "dependencies": { 1018 | "chownr": "^1.1.1", 1019 | "mkdirp-classic": "^0.5.2", 1020 | "pump": "^3.0.0", 1021 | "tar-stream": "^2.0.0" 1022 | } 1023 | }, 1024 | "node_modules/tar-stream": { 1025 | "version": "2.2.0", 1026 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", 1027 | "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", 1028 | "dependencies": { 1029 | "bl": "^4.0.3", 1030 | "end-of-stream": "^1.4.1", 1031 | "fs-constants": "^1.0.0", 1032 | "inherits": "^2.0.3", 1033 | "readable-stream": "^3.1.1" 1034 | }, 1035 | "engines": { 1036 | "node": ">=6" 1037 | } 1038 | }, 1039 | "node_modules/tar-stream/node_modules/readable-stream": { 1040 | "version": "3.6.2", 1041 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 1042 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 1043 | "dependencies": { 1044 | "inherits": "^2.0.3", 1045 | "string_decoder": "^1.1.1", 1046 | "util-deprecate": "^1.0.1" 1047 | }, 1048 | "engines": { 1049 | "node": ">= 6" 1050 | } 1051 | }, 1052 | "node_modules/tar-stream/node_modules/safe-buffer": { 1053 | "version": "5.2.1", 1054 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1055 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1056 | "funding": [ 1057 | { 1058 | "type": "github", 1059 | "url": "https://github.com/sponsors/feross" 1060 | }, 1061 | { 1062 | "type": "patreon", 1063 | "url": "https://www.patreon.com/feross" 1064 | }, 1065 | { 1066 | "type": "consulting", 1067 | "url": "https://feross.org/support" 1068 | } 1069 | ] 1070 | }, 1071 | "node_modules/tar-stream/node_modules/string_decoder": { 1072 | "version": "1.3.0", 1073 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 1074 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 1075 | "dependencies": { 1076 | "safe-buffer": "~5.2.0" 1077 | } 1078 | }, 1079 | "node_modules/toidentifier": { 1080 | "version": "1.0.1", 1081 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1082 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 1083 | "engines": { 1084 | "node": ">=0.6" 1085 | } 1086 | }, 1087 | "node_modules/tweetnacl": { 1088 | "version": "0.14.5", 1089 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 1090 | "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" 1091 | }, 1092 | "node_modules/type-is": { 1093 | "version": "1.6.18", 1094 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1095 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1096 | "dependencies": { 1097 | "media-typer": "0.3.0", 1098 | "mime-types": "~2.1.24" 1099 | }, 1100 | "engines": { 1101 | "node": ">= 0.6" 1102 | } 1103 | }, 1104 | "node_modules/unpipe": { 1105 | "version": "1.0.0", 1106 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1107 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 1108 | "engines": { 1109 | "node": ">= 0.8" 1110 | } 1111 | }, 1112 | "node_modules/url-parse": { 1113 | "version": "1.5.10", 1114 | "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", 1115 | "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", 1116 | "dependencies": { 1117 | "querystringify": "^2.1.1", 1118 | "requires-port": "^1.0.0" 1119 | } 1120 | }, 1121 | "node_modules/util-deprecate": { 1122 | "version": "1.0.2", 1123 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1124 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" 1125 | }, 1126 | "node_modules/utils-merge": { 1127 | "version": "1.0.1", 1128 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1129 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 1130 | "engines": { 1131 | "node": ">= 0.4.0" 1132 | } 1133 | }, 1134 | "node_modules/uuid": { 1135 | "version": "9.0.0", 1136 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", 1137 | "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", 1138 | "bin": { 1139 | "uuid": "dist/bin/uuid" 1140 | } 1141 | }, 1142 | "node_modules/vary": { 1143 | "version": "1.1.2", 1144 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1145 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 1146 | "engines": { 1147 | "node": ">= 0.8" 1148 | } 1149 | }, 1150 | "node_modules/wrappy": { 1151 | "version": "1.0.2", 1152 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1153 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 1154 | } 1155 | } 1156 | } 1157 | --------------------------------------------------------------------------------