Commit ab5bc7773afb7f2b2909c7b36ac9b31fdbe5f0b7

Authored by Igor Kulikov
Committed by GitHub
2 parents e3c523cc d117cec0

Merge pull request #4667 from smatvienko-tb/js-executors-kafka-batches

Js executors kafka batches
  1 +/*
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +const config = require('config'),
  17 + logger = require('../config/logger')._logger('httpServer'),
  18 + express = require('express');
  19 +
  20 +const httpPort = Number(config.get('http_port'));
  21 +
  22 +const app = express();
  23 +
  24 +app.get('/livenessProbe', async (req, res) => {
  25 + const date = new Date();
  26 + const message = { now: date.toISOString() };
  27 + res.send(message);
  28 +})
  29 +
  30 +app.listen(httpPort, () => logger.info(`Started http endpoint on port ${httpPort}. Please, use /livenessProbe !`))
\ No newline at end of file
... ...
... ... @@ -25,6 +25,7 @@ const config = require('config'),
25 25 Utils = require('./utils'),
26 26 JsExecutor = require('./jsExecutor');
27 27
  28 +const statFrequency = Number(config.get('script.stat_print_frequency'));
28 29 const scriptBodyTraceFrequency = Number(config.get('script.script_body_trace_frequency'));
29 30 const useSandbox = config.get('script.use_sandbox') === 'true';
30 31 const maxActiveScripts = Number(config.get('script.max_active_scripts'));
... ... @@ -34,15 +35,15 @@ const slowQueryLogBody = config.get('script.slow_query_log_body') === 'true';
34 35 const {performance} = require('perf_hooks');
35 36
36 37 function JsInvokeMessageProcessor(producer) {
37   - console.log("Producer:", producer);
38 38 this.producer = producer;
39 39 this.executor = new JsExecutor(useSandbox);
40   - this.scriptMap = {};
  40 + this.scriptMap = new Map();
41 41 this.scriptIds = [];
42 42 this.executedScriptsCounter = 0;
  43 + this.lastStatTime = performance.now();
43 44 }
44 45
45   -JsInvokeMessageProcessor.prototype.onJsInvokeMessage = function(message) {
  46 +JsInvokeMessageProcessor.prototype.onJsInvokeMessage = function (message) {
46 47 var tStart = performance.now();
47 48 let requestId;
48 49 let responseTopic;
... ... @@ -77,13 +78,13 @@ JsInvokeMessageProcessor.prototype.onJsInvokeMessage = function(message) {
77 78 var tFinish = performance.now();
78 79 var tTook = tFinish - tStart;
79 80
80   - if ( tTook > slowQueryLogMs ) {
  81 + if (tTook > slowQueryLogMs) {
81 82 let functionName;
82 83 if (request.invokeRequest) {
83 84 try {
84 85 buf = Buffer.from(request.invokeRequest['functionName']);
85 86 functionName = buf.toString('utf8');
86   - } catch (err){
  87 + } catch (err) {
87 88 logger.error('[%s] Failed to read functionName from message header: %s', requestId, err.message);
88 89 logger.error(err.stack);
89 90 }
... ... @@ -96,7 +97,7 @@ JsInvokeMessageProcessor.prototype.onJsInvokeMessage = function(message) {
96 97
97 98 }
98 99
99   -JsInvokeMessageProcessor.prototype.processCompileRequest = function(requestId, responseTopic, headers, compileRequest) {
  100 +JsInvokeMessageProcessor.prototype.processCompileRequest = function (requestId, responseTopic, headers, compileRequest) {
100 101 var scriptId = getScriptId(compileRequest);
101 102 logger.debug('[%s] Processing compile request, scriptId: [%s]', requestId, scriptId);
102 103
... ... @@ -115,15 +116,20 @@ JsInvokeMessageProcessor.prototype.processCompileRequest = function(requestId, r
115 116 );
116 117 }
117 118
118   -JsInvokeMessageProcessor.prototype.processInvokeRequest = function(requestId, responseTopic, headers, invokeRequest) {
  119 +JsInvokeMessageProcessor.prototype.processInvokeRequest = function (requestId, responseTopic, headers, invokeRequest) {
119 120 var scriptId = getScriptId(invokeRequest);
120 121 logger.debug('[%s] Processing invoke request, scriptId: [%s]', requestId, scriptId);
121 122 this.executedScriptsCounter++;
122   - if ( this.executedScriptsCounter >= scriptBodyTraceFrequency ) {
123   - this.executedScriptsCounter = 0;
124   - if (logger.levels[logger.level] >= logger.levels['debug']) {
125   - logger.debug('[%s] Executing script body: [%s]', scriptId, invokeRequest.scriptBody);
126   - }
  123 + if (this.executedScriptsCounter % statFrequency == 0) {
  124 + const nowMs = performance.now();
  125 + const msSinceLastStat = nowMs - this.lastStatTime;
  126 + const requestsPerSec = msSinceLastStat == 0 ? statFrequency : statFrequency / msSinceLastStat * 1000;
  127 + this.lastStatTime = nowMs;
  128 + logger.info('STAT[%s]: requests [%s], took [%s]ms, request/s [%s]', this.executedScriptsCounter, statFrequency, msSinceLastStat, requestsPerSec);
  129 + }
  130 +
  131 + if (this.executedScriptsCounter % scriptBodyTraceFrequency == 0) {
  132 + logger.info('[%s] Executing script body: [%s]', scriptId, invokeRequest.scriptBody);
127 133 }
128 134 this.getOrCompileScript(scriptId, invokeRequest.scriptBody).then(
129 135 (script) => {
... ... @@ -154,15 +160,15 @@ JsInvokeMessageProcessor.prototype.processInvokeRequest = function(requestId, re
154 160 );
155 161 }
156 162
157   -JsInvokeMessageProcessor.prototype.processReleaseRequest = function(requestId, responseTopic, headers, releaseRequest) {
  163 +JsInvokeMessageProcessor.prototype.processReleaseRequest = function (requestId, responseTopic, headers, releaseRequest) {
158 164 var scriptId = getScriptId(releaseRequest);
159 165 logger.debug('[%s] Processing release request, scriptId: [%s]', requestId, scriptId);
160   - if (this.scriptMap[scriptId]) {
  166 + if (this.scriptMap.has(scriptId)) {
161 167 var index = this.scriptIds.indexOf(scriptId);
162 168 if (index > -1) {
163 169 this.scriptIds.splice(index, 1);
164 170 }
165   - delete this.scriptMap[scriptId];
  171 + this.scriptMap.delete(scriptId);
166 172 }
167 173 var releaseResponse = createReleaseResponse(scriptId, true);
168 174 logger.debug('[%s] Sending success release response, scriptId: [%s]', requestId, scriptId);
... ... @@ -173,6 +179,7 @@ JsInvokeMessageProcessor.prototype.sendResponse = function (requestId, responseT
173 179 var tStartSending = performance.now();
174 180 var remoteResponse = createRemoteResponse(requestId, compileResponse, invokeResponse, releaseResponse);
175 181 var rawResponse = Buffer.from(JSON.stringify(remoteResponse), 'utf8');
  182 + logger.debug('[%s] Sending response to queue, scriptId: [%s]', requestId, scriptId);
176 183 this.producer.send(responseTopic, scriptId, rawResponse, headers).then(
177 184 () => {
178 185 logger.debug('[%s] Response sent to queue, took [%s]ms, scriptId: [%s]', requestId, (performance.now() - tStartSending), scriptId);
... ... @@ -186,16 +193,17 @@ JsInvokeMessageProcessor.prototype.sendResponse = function (requestId, responseT
186 193 );
187 194 }
188 195
189   -JsInvokeMessageProcessor.prototype.getOrCompileScript = function(scriptId, scriptBody) {
  196 +JsInvokeMessageProcessor.prototype.getOrCompileScript = function (scriptId, scriptBody) {
190 197 var self = this;
191   - return new Promise(function(resolve, reject) {
192   - if (self.scriptMap[scriptId]) {
193   - resolve(self.scriptMap[scriptId]);
  198 + return new Promise(function (resolve, reject) {
  199 + const script = self.scriptMap.get(scriptId);
  200 + if (script) {
  201 + resolve(script);
194 202 } else {
195 203 self.executor.compileScript(scriptBody).then(
196   - (script) => {
197   - self.cacheScript(scriptId, script);
198   - resolve(script);
  204 + (compiledScript) => {
  205 + self.cacheScript(scriptId, compiledScript);
  206 + resolve(compiledScript);
199 207 },
200 208 (err) => {
201 209 reject(err);
... ... @@ -205,56 +213,57 @@ JsInvokeMessageProcessor.prototype.getOrCompileScript = function(scriptId, scrip
205 213 });
206 214 }
207 215
208   -JsInvokeMessageProcessor.prototype.cacheScript = function(scriptId, script) {
209   - if (!this.scriptMap[scriptId]) {
  216 +JsInvokeMessageProcessor.prototype.cacheScript = function (scriptId, script) {
  217 + if (!this.scriptMap.has(scriptId)) {
210 218 this.scriptIds.push(scriptId);
211 219 while (this.scriptIds.length > maxActiveScripts) {
212 220 logger.info('Active scripts count [%s] exceeds maximum limit [%s]', this.scriptIds.length, maxActiveScripts);
213 221 const prevScriptId = this.scriptIds.shift();
214 222 logger.info('Removing active script with id [%s]', prevScriptId);
215   - delete this.scriptMap[prevScriptId];
  223 + this.scriptMap.delete(prevScriptId);
216 224 }
217 225 }
218   - this.scriptMap[scriptId] = script;
  226 + this.scriptMap.set(scriptId, script);
  227 + logger.info("scriptMap size is [%s]", this.scriptMap.size);
219 228 }
220 229
221 230 function createRemoteResponse(requestId, compileResponse, invokeResponse, releaseResponse) {
222 231 const requestIdBits = Utils.UUIDToBits(requestId);
223 232 return {
224   - requestIdMSB: requestIdBits[0],
225   - requestIdLSB: requestIdBits[1],
226   - compileResponse: compileResponse,
227   - invokeResponse: invokeResponse,
228   - releaseResponse: releaseResponse
  233 + requestIdMSB: requestIdBits[0],
  234 + requestIdLSB: requestIdBits[1],
  235 + compileResponse: compileResponse,
  236 + invokeResponse: invokeResponse,
  237 + releaseResponse: releaseResponse
229 238 };
230 239 }
231 240
232 241 function createCompileResponse(scriptId, success, errorCode, err) {
233 242 const scriptIdBits = Utils.UUIDToBits(scriptId);
234   - return {
235   - errorCode: errorCode,
236   - success: success,
237   - errorDetails: parseJsErrorDetails(err),
238   - scriptIdMSB: scriptIdBits[0],
239   - scriptIdLSB: scriptIdBits[1]
  243 + return {
  244 + errorCode: errorCode,
  245 + success: success,
  246 + errorDetails: parseJsErrorDetails(err),
  247 + scriptIdMSB: scriptIdBits[0],
  248 + scriptIdLSB: scriptIdBits[1]
240 249 };
241 250 }
242 251
243 252 function createInvokeResponse(result, success, errorCode, err) {
244   - return {
245   - errorCode: errorCode,
246   - success: success,
247   - errorDetails: parseJsErrorDetails(err),
248   - result: result
  253 + return {
  254 + errorCode: errorCode,
  255 + success: success,
  256 + errorDetails: parseJsErrorDetails(err),
  257 + result: result
249 258 };
250 259 }
251 260
252 261 function createReleaseResponse(scriptId, success) {
253 262 const scriptIdBits = Utils.UUIDToBits(scriptId);
254 263 return {
255   - success: success,
256   - scriptIdMSB: scriptIdBits[0],
257   - scriptIdLSB: scriptIdBits[1]
  264 + success: success,
  265 + scriptIdMSB: scriptIdBits[0],
  266 + scriptIdLSB: scriptIdBits[1]
258 267 };
259 268 }
260 269
... ...
... ... @@ -16,6 +16,7 @@
16 16
17 17 queue_type: "TB_QUEUE_TYPE" #kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ)
18 18 request_topic: "REMOTE_JS_EVAL_REQUEST_TOPIC"
  19 +http_port: "HTTP_PORT" # /livenessProbe
19 20
20 21 js:
21 22 response_poll_interval: "REMOTE_JS_RESPONSE_POLL_INTERVAL_MS"
... ... @@ -26,6 +27,9 @@ kafka:
26 27 servers: "TB_KAFKA_SERVERS"
27 28 replication_factor: "TB_QUEUE_KAFKA_REPLICATION_FACTOR"
28 29 acks: "TB_KAFKA_ACKS" # -1 = all; 0 = no acknowledgments; 1 = only waits for the leader to acknowledge
  30 + batch_size: "TB_KAFKA_BATCH_SIZE" # for producer
  31 + linger_ms: "TB_KAFKA_LINGER_MS" # for producer
  32 + partitions_consumed_concurrently: "TB_KAFKA_PARTITIONS_CONSUMED_CONCURRENTLY" # (EXPERIMENTAL) increase this value if you are planning to handle more than one partition (scale up, scale down) - this will decrease the latency
29 33 requestTimeout: "TB_QUEUE_KAFKA_REQUEST_TIMEOUT_MS"
30 34 compression: "TB_QUEUE_KAFKA_COMPRESSION" # gzip or uncompressed
31 35 topic_properties: "TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES"
... ... @@ -70,6 +74,7 @@ logger:
70 74
71 75 script:
72 76 use_sandbox: "SCRIPT_USE_SANDBOX"
  77 + stat_print_frequency: "SCRIPT_STAT_PRINT_FREQUENCY"
73 78 script_body_trace_frequency: "SCRIPT_BODY_TRACE_FREQUENCY"
74 79 max_active_scripts: "MAX_ACTIVE_SCRIPTS"
75 80 slow_query_log_ms: "SLOW_QUERY_LOG_MS" #1.123456
... ...
... ... @@ -16,6 +16,7 @@
16 16
17 17 queue_type: "kafka"
18 18 request_topic: "js_eval.requests"
  19 +http_port: "8888" # /livenessProbe
19 20
20 21 js:
21 22 response_poll_interval: "25"
... ... @@ -26,6 +27,9 @@ kafka:
26 27 servers: "localhost:9092"
27 28 replication_factor: "1"
28 29 acks: "1" # -1 = all; 0 = no acknowledgments; 1 = only waits for the leader to acknowledge
  30 + batch_size: "128" # for producer
  31 + linger_ms: "1" # for producer
  32 + partitions_consumed_concurrently: "1" # (EXPERIMENTAL) increase this value if you are planning to handle more than one partition (scale up, scale down) - this will decrease the latency
29 33 requestTimeout: "30000" # The default value in kafkajs is: 30000
30 34 compression: "gzip" # gzip or uncompressed
31 35 topic_properties: "retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100;min.insync.replicas:1"
... ... @@ -59,7 +63,8 @@ logger:
59 63
60 64 script:
61 65 use_sandbox: "true"
62   - script_body_trace_frequency: "1000"
  66 + script_body_trace_frequency: "10000"
  67 + stat_print_frequency: "10000"
63 68 max_active_scripts: "1000"
64   - slow_query_log_ms: "1.000000" #millis
  69 + slow_query_log_ms: "5.000000" #millis
65 70 slow_query_log_body: "false"
... ...
... ... @@ -18,6 +18,7 @@
18 18 "aws-sdk": "^2.741.0",
19 19 "azure-sb": "^0.11.1",
20 20 "config": "^3.3.1",
  21 + "express": "^4.17.1",
21 22 "js-yaml": "^3.14.0",
22 23 "kafkajs": "^1.15.0",
23 24 "long": "^4.0.0",
... ...
... ... @@ -23,8 +23,11 @@ const replicationFactor = Number(config.get('kafka.replication_factor'));
23 23 const topicProperties = config.get('kafka.topic_properties');
24 24 const kafkaClientId = config.get('kafka.client_id');
25 25 const acks = Number(config.get('kafka.acks'));
  26 +const maxBatchSize = Number(config.get('kafka.batch_size'));
  27 +const linger = Number(config.get('kafka.linger_ms'));
26 28 const requestTimeout = Number(config.get('kafka.requestTimeout'));
27 29 const compressionType = (config.get('kafka.compression') === "gzip") ? CompressionTypes.GZIP : CompressionTypes.None;
  30 +const partitionsConsumedConcurrently = Number(config.get('kafka.partitions_consumed_concurrently'));
28 31
29 32 let kafkaClient;
30 33 let kafkaAdmin;
... ... @@ -33,22 +36,65 @@ let producer;
33 36
34 37 const configEntries = [];
35 38
  39 +let batchMessages = [];
  40 +let sendLoopInstance;
  41 +
36 42 function KafkaProducer() {
37 43 this.send = async (responseTopic, scriptId, rawResponse, headers) => {
38   - return producer.send(
39   - {
40   - topic: responseTopic,
  44 + logger.debug('Pending queue response, scriptId: [%s]', scriptId);
  45 + const message = {
  46 + topic: responseTopic,
  47 + messages: [{
  48 + key: scriptId,
  49 + value: rawResponse,
  50 + headers: headers.data
  51 + }]
  52 + };
  53 +
  54 + await pushMessageToSendLater(message);
  55 + }
  56 +}
  57 +
  58 +async function pushMessageToSendLater(message) {
  59 + batchMessages.push(message);
  60 + if (batchMessages.length >= maxBatchSize) {
  61 + await sendMessagesAsBatch(true);
  62 + }
  63 +}
  64 +
  65 +function sendLoopWithLinger() {
  66 + if (sendLoopInstance) {
  67 + clearTimeout(sendLoopInstance);
  68 + } else {
  69 + logger.debug("Starting new send loop with linger [%s]", linger)
  70 + }
  71 + sendLoopInstance = setTimeout(sendMessagesAsBatch, linger);
  72 +}
  73 +
  74 +async function sendMessagesAsBatch(isImmediately) {
  75 + if (sendLoopInstance) {
  76 + logger.debug("sendMessagesAsBatch: Clear sendLoop scheduler. Starting new send loop with linger [%s]", linger);
  77 + clearTimeout(sendLoopInstance);
  78 + }
  79 + sendLoopInstance = null;
  80 + if (batchMessages.length > 0) {
  81 + logger.debug('sendMessagesAsBatch, length: [%s], %s', batchMessages.length, isImmediately ? 'immediately' : '');
  82 + const messagesToSend = batchMessages;
  83 + batchMessages = [];
  84 + try {
  85 + await producer.sendBatch({
  86 + topicMessages: messagesToSend,
41 87 acks: acks,
42   - compression: compressionType,
43   - messages: [
44   - {
45   - key: scriptId,
46   - value: rawResponse,
47   - headers: headers.data
48   - }
49   - ]
50   - });
  88 + compression: compressionType
  89 + })
  90 + logger.debug('Response batch sent to kafka, length: [%s]', messagesToSend.length);
  91 + } catch(err) {
  92 + logger.error('Failed batch send to kafka, length: [%s], pending to reprocess msgs', messagesToSend.length);
  93 + logger.error(err.stack);
  94 + batchMessages = messagesToSend.concat(batchMessages);
  95 + }
51 96 }
  97 + sendLoopWithLinger();
52 98 }
53 99
54 100 (async () => {
... ... @@ -64,8 +110,8 @@ function KafkaProducer() {
64 110
65 111 let kafkaConfig = {
66 112 brokers: kafkaBootstrapServers.split(','),
67   - logLevel: logLevel.INFO,
68   - logCreator: KafkaJsWinstonLogCreator
  113 + logLevel: logLevel.INFO,
  114 + logCreator: KafkaJsWinstonLogCreator
69 115 };
70 116
71 117 if (kafkaClientId) {
... ... @@ -114,14 +160,45 @@ function KafkaProducer() {
114 160
115 161 consumer = kafkaClient.consumer({groupId: 'js-executor-group'});
116 162 producer = kafkaClient.producer();
  163 +
  164 +/*
  165 + //producer event instrumentation to debug
  166 + const { CONNECT } = producer.events;
  167 + const removeListenerC = producer.on(CONNECT, e => logger.info(`producer CONNECT`));
  168 + const { DISCONNECT } = producer.events;
  169 + const removeListenerD = producer.on(DISCONNECT, e => logger.info(`producer DISCONNECT`));
  170 + const { REQUEST } = producer.events;
  171 + const removeListenerR = producer.on(REQUEST, e => logger.info(`producer REQUEST ${e.payload.broker}`));
  172 + const { REQUEST_TIMEOUT } = producer.events;
  173 + const removeListenerRT = producer.on(REQUEST_TIMEOUT, e => logger.info(`producer REQUEST_TIMEOUT ${e.payload.broker}`));
  174 + const { REQUEST_QUEUE_SIZE } = producer.events;
  175 + const removeListenerRQS = producer.on(REQUEST_QUEUE_SIZE, e => logger.info(`producer REQUEST_QUEUE_SIZE ${e.payload.broker} size ${e.queueSize}`));
  176 +*/
  177 +
  178 +/*
  179 + //consumer event instrumentation to debug
  180 + const removeListeners = {}
  181 + const { FETCH_START } = consumer.events;
  182 + removeListeners[FETCH_START] = consumer.on(FETCH_START, e => logger.info(`consumer FETCH_START`));
  183 + const { FETCH } = consumer.events;
  184 + removeListeners[FETCH] = consumer.on(FETCH, e => logger.info(`consumer FETCH numberOfBatches ${e.payload.numberOfBatches} duration ${e.payload.duration}`));
  185 + const { START_BATCH_PROCESS } = consumer.events;
  186 + removeListeners[START_BATCH_PROCESS] = consumer.on(START_BATCH_PROCESS, e => logger.info(`consumer START_BATCH_PROCESS topic ${e.payload.topic} batchSize ${e.payload.batchSize}`));
  187 + const { END_BATCH_PROCESS } = consumer.events;
  188 + removeListeners[END_BATCH_PROCESS] = consumer.on(END_BATCH_PROCESS, e => logger.info(`consumer END_BATCH_PROCESS topic ${e.payload.topic} batchSize ${e.payload.batchSize}`));
  189 + const { COMMIT_OFFSETS } = consumer.events;
  190 + removeListeners[COMMIT_OFFSETS] = consumer.on(COMMIT_OFFSETS, e => logger.info(`consumer COMMIT_OFFSETS topics ${e.payload.topics}`));
  191 +*/
  192 +
117 193 const messageProcessor = new JsInvokeMessageProcessor(new KafkaProducer());
118 194 await consumer.connect();
119 195 await producer.connect();
  196 + sendLoopWithLinger();
120 197 await consumer.subscribe({topic: requestTopic});
121 198
122 199 logger.info('Started ThingsBoard JavaScript Executor Microservice.');
123 200 await consumer.run({
124   - //partitionsConsumedConcurrently: 1, // Default: 1
  201 + partitionsConsumedConcurrently: partitionsConsumedConcurrently,
125 202 eachMessage: async ({topic, partition, message}) => {
126 203 let headers = message.headers;
127 204 let key = message.key;
... ... @@ -197,6 +274,9 @@ async function disconnectProducer() {
197 274 var _producer = producer;
198 275 producer = null;
199 276 try {
  277 + logger.info('Stopping loop...');
  278 + clearTimeout(sendLoopInstance);
  279 + await sendMessagesAsBatch();
200 280 await _producer.disconnect();
201 281 logger.info('Kafka Producer stopped.');
202 282 } catch (e) {
... ...
... ... @@ -51,3 +51,5 @@ switch (serviceType) {
51 51 process.exit(-1);
52 52 }
53 53
  54 +require('./api/httpServer');
  55 +
... ...
... ... @@ -418,6 +418,14 @@ abort-controller@^3.0.0:
418 418 dependencies:
419 419 event-target-shim "^5.0.0"
420 420
  421 +accepts@~1.3.7:
  422 + version "1.3.7"
  423 + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
  424 + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
  425 + dependencies:
  426 + mime-types "~2.1.24"
  427 + negotiator "0.6.2"
  428 +
421 429 agent-base@6:
422 430 version "6.0.1"
423 431 resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.1.tgz#808007e4e5867decb0ab6ab2f928fbdb5a596db4"
... ... @@ -487,6 +495,11 @@ argparse@^1.0.7:
487 495 dependencies:
488 496 sprintf-js "~1.0.2"
489 497
  498 +array-flatten@1.1.1:
  499 + version "1.1.1"
  500 + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
  501 + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
  502 +
490 503 array-union@^2.1.0:
491 504 version "2.1.0"
492 505 resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
... ... @@ -621,6 +634,22 @@ bluebird@^3.5.2:
621 634 resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
622 635 integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
623 636
  637 +body-parser@1.19.0:
  638 + version "1.19.0"
  639 + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
  640 + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
  641 + dependencies:
  642 + bytes "3.1.0"
  643 + content-type "~1.0.4"
  644 + debug "2.6.9"
  645 + depd "~1.1.2"
  646 + http-errors "1.7.2"
  647 + iconv-lite "0.4.24"
  648 + on-finished "~2.3.0"
  649 + qs "6.7.0"
  650 + raw-body "2.4.0"
  651 + type-is "~1.6.17"
  652 +
624 653 boxen@^4.2.0:
625 654 version "4.2.0"
626 655 resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64"
... ... @@ -682,6 +711,11 @@ byline@^5.0.0:
682 711 resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
683 712 integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=
684 713
  714 +bytes@3.1.0:
  715 + version "3.1.0"
  716 + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
  717 + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
  718 +
685 719 cacheable-request@^6.0.0:
686 720 version "6.1.0"
687 721 resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
... ... @@ -838,6 +872,28 @@ configstore@^5.0.1:
838 872 write-file-atomic "^3.0.0"
839 873 xdg-basedir "^4.0.0"
840 874
  875 +content-disposition@0.5.3:
  876 + version "0.5.3"
  877 + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd"
  878 + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
  879 + dependencies:
  880 + safe-buffer "5.1.2"
  881 +
  882 +content-type@~1.0.4:
  883 + version "1.0.4"
  884 + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
  885 + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
  886 +
  887 +cookie-signature@1.0.6:
  888 + version "1.0.6"
  889 + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
  890 + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
  891 +
  892 +cookie@0.4.0:
  893 + version "0.4.0"
  894 + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
  895 + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
  896 +
841 897 core-util-is@1.0.2, core-util-is@~1.0.0:
842 898 version "1.0.2"
843 899 resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
... ... @@ -867,6 +923,13 @@ dateformat@1.0.2-1.2.3:
867 923 dependencies:
868 924 ms "^2.1.1"
869 925
  926 +debug@2.6.9, debug@^2.2.0, debug@~2.6.9:
  927 + version "2.6.9"
  928 + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
  929 + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
  930 + dependencies:
  931 + ms "2.0.0"
  932 +
870 933 debug@4, debug@^4.1.1:
871 934 version "4.1.1"
872 935 resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
... ... @@ -874,13 +937,6 @@ debug@4, debug@^4.1.1:
874 937 dependencies:
875 938 ms "^2.1.1"
876 939
877   -debug@^2.2.0, debug@~2.6.9:
878   - version "2.6.9"
879   - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
880   - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
881   - dependencies:
882   - ms "2.0.0"
883   -
884 940 decamelize@^1.2.0:
885 941 version "1.2.0"
886 942 resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
... ... @@ -913,6 +969,16 @@ delayed-stream@~1.0.0:
913 969 resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
914 970 integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
915 971
  972 +depd@~1.1.2:
  973 + version "1.1.2"
  974 + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
  975 + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
  976 +
  977 +destroy@~1.0.4:
  978 + version "1.0.4"
  979 + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
  980 + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
  981 +
916 982 dir-glob@^3.0.1:
917 983 version "3.0.1"
918 984 resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
... ... @@ -962,6 +1028,11 @@ ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11:
962 1028 dependencies:
963 1029 safe-buffer "^5.0.1"
964 1030
  1031 +ee-first@1.1.1:
  1032 + version "1.1.1"
  1033 + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
  1034 + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
  1035 +
965 1036 emoji-regex@^7.0.1:
966 1037 version "7.0.3"
967 1038 resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
... ... @@ -977,6 +1048,11 @@ enabled@2.0.x:
977 1048 resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2"
978 1049 integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==
979 1050
  1051 +encodeurl@~1.0.2:
  1052 + version "1.0.2"
  1053 + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
  1054 + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
  1055 +
980 1056 end-of-stream@^1.0.0, end-of-stream@^1.1.0:
981 1057 version "1.4.4"
982 1058 resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
... ... @@ -994,6 +1070,11 @@ escape-goat@^2.0.0:
994 1070 resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
995 1071 integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==
996 1072
  1073 +escape-html@~1.0.3:
  1074 + version "1.0.3"
  1075 + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
  1076 + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
  1077 +
997 1078 escodegen@^1.14.1:
998 1079 version "1.14.3"
999 1080 resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503"
... ... @@ -1021,6 +1102,11 @@ esutils@^2.0.2:
1021 1102 resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
1022 1103 integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
1023 1104
  1105 +etag@~1.8.1:
  1106 + version "1.8.1"
  1107 + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
  1108 + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
  1109 +
1024 1110 event-target-shim@^5.0.0:
1025 1111 version "5.0.1"
1026 1112 resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
... ... @@ -1041,6 +1127,42 @@ expand-template@^2.0.3:
1041 1127 resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
1042 1128 integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
1043 1129
  1130 +express@^4.17.1:
  1131 + version "4.17.1"
  1132 + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
  1133 + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==
  1134 + dependencies:
  1135 + accepts "~1.3.7"
  1136 + array-flatten "1.1.1"
  1137 + body-parser "1.19.0"
  1138 + content-disposition "0.5.3"
  1139 + content-type "~1.0.4"
  1140 + cookie "0.4.0"
  1141 + cookie-signature "1.0.6"
  1142 + debug "2.6.9"
  1143 + depd "~1.1.2"
  1144 + encodeurl "~1.0.2"
  1145 + escape-html "~1.0.3"
  1146 + etag "~1.8.1"
  1147 + finalhandler "~1.1.2"
  1148 + fresh "0.5.2"
  1149 + merge-descriptors "1.0.1"
  1150 + methods "~1.1.2"
  1151 + on-finished "~2.3.0"
  1152 + parseurl "~1.3.3"
  1153 + path-to-regexp "0.1.7"
  1154 + proxy-addr "~2.0.5"
  1155 + qs "6.7.0"
  1156 + range-parser "~1.2.1"
  1157 + safe-buffer "5.1.2"
  1158 + send "0.17.1"
  1159 + serve-static "1.14.1"
  1160 + setprototypeof "1.1.1"
  1161 + statuses "~1.5.0"
  1162 + type-is "~1.6.18"
  1163 + utils-merge "1.0.1"
  1164 + vary "~1.1.2"
  1165 +
1044 1166 extend@^3.0.2, extend@~3.0.2:
1045 1167 version "3.0.2"
1046 1168 resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
... ... @@ -1119,6 +1241,19 @@ fill-range@^7.0.1:
1119 1241 dependencies:
1120 1242 to-regex-range "^5.0.1"
1121 1243
  1244 +finalhandler@~1.1.2:
  1245 + version "1.1.2"
  1246 + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
  1247 + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
  1248 + dependencies:
  1249 + debug "2.6.9"
  1250 + encodeurl "~1.0.2"
  1251 + escape-html "~1.0.3"
  1252 + on-finished "~2.3.0"
  1253 + parseurl "~1.3.3"
  1254 + statuses "~1.5.0"
  1255 + unpipe "~1.0.0"
  1256 +
1122 1257 find-up@^4.1.0:
1123 1258 version "4.1.0"
1124 1259 resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
... ... @@ -1155,6 +1290,16 @@ form-data@~2.3.2:
1155 1290 combined-stream "^1.0.6"
1156 1291 mime-types "^2.1.12"
1157 1292
  1293 +forwarded@0.2.0:
  1294 + version "0.2.0"
  1295 + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
  1296 + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
  1297 +
  1298 +fresh@0.5.2:
  1299 + version "0.5.2"
  1300 + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
  1301 + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
  1302 +
1158 1303 from2@^2.3.0:
1159 1304 version "2.3.0"
1160 1305 resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
... ... @@ -1384,6 +1529,28 @@ http-cache-semantics@^4.0.0:
1384 1529 resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
1385 1530 integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
1386 1531
  1532 +http-errors@1.7.2:
  1533 + version "1.7.2"
  1534 + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
  1535 + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
  1536 + dependencies:
  1537 + depd "~1.1.2"
  1538 + inherits "2.0.3"
  1539 + setprototypeof "1.1.1"
  1540 + statuses ">= 1.5.0 < 2"
  1541 + toidentifier "1.0.0"
  1542 +
  1543 +http-errors@~1.7.2:
  1544 + version "1.7.3"
  1545 + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
  1546 + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
  1547 + dependencies:
  1548 + depd "~1.1.2"
  1549 + inherits "2.0.4"
  1550 + setprototypeof "1.1.1"
  1551 + statuses ">= 1.5.0 < 2"
  1552 + toidentifier "1.0.0"
  1553 +
1387 1554 http-signature@~1.2.0:
1388 1555 version "1.2.0"
1389 1556 resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
... ... @@ -1401,6 +1568,13 @@ https-proxy-agent@^5.0.0:
1401 1568 agent-base "6"
1402 1569 debug "4"
1403 1570
  1571 +iconv-lite@0.4.24:
  1572 + version "0.4.24"
  1573 + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
  1574 + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
  1575 + dependencies:
  1576 + safer-buffer ">= 2.1.2 < 3"
  1577 +
1404 1578 ieee754@1.1.13, ieee754@^1.1.4:
1405 1579 version "1.1.13"
1406 1580 resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
... ... @@ -1431,7 +1605,7 @@ inherits@2.0.3:
1431 1605 resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
1432 1606 integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
1433 1607
1434   -inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
  1608 +inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
1435 1609 version "2.0.4"
1436 1610 resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
1437 1611 integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
... ... @@ -1449,6 +1623,11 @@ into-stream@^5.1.1:
1449 1623 from2 "^2.3.0"
1450 1624 p-is-promise "^3.0.0"
1451 1625
  1626 +ipaddr.js@1.9.1:
  1627 + version "1.9.1"
  1628 + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
  1629 + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
  1630 +
1452 1631 is-arrayish@^0.3.1:
1453 1632 version "0.3.2"
1454 1633 resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
... ... @@ -1764,11 +1943,26 @@ make-dir@^3.0.0:
1764 1943 dependencies:
1765 1944 semver "^6.0.0"
1766 1945
  1946 +media-typer@0.3.0:
  1947 + version "0.3.0"
  1948 + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
  1949 + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
  1950 +
  1951 +merge-descriptors@1.0.1:
  1952 + version "1.0.1"
  1953 + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
  1954 + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
  1955 +
1767 1956 merge2@^1.3.0:
1768 1957 version "1.4.1"
1769 1958 resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
1770 1959 integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
1771 1960
  1961 +methods@~1.1.2:
  1962 + version "1.1.2"
  1963 + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
  1964 + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
  1965 +
1772 1966 micromatch@^4.0.2:
1773 1967 version "4.0.2"
1774 1968 resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
... ... @@ -1782,6 +1976,11 @@ mime-db@1.44.0:
1782 1976 resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92"
1783 1977 integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==
1784 1978
  1979 +mime-db@1.48.0:
  1980 + version "1.48.0"
  1981 + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d"
  1982 + integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==
  1983 +
1785 1984 mime-types@^2.1.12, mime-types@~2.1.19:
1786 1985 version "2.1.27"
1787 1986 resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
... ... @@ -1789,6 +1988,18 @@ mime-types@^2.1.12, mime-types@~2.1.19:
1789 1988 dependencies:
1790 1989 mime-db "1.44.0"
1791 1990
  1991 +mime-types@~2.1.24:
  1992 + version "2.1.31"
  1993 + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b"
  1994 + integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==
  1995 + dependencies:
  1996 + mime-db "1.48.0"
  1997 +
  1998 +mime@1.6.0:
  1999 + version "1.6.0"
  2000 + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
  2001 + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
  2002 +
1792 2003 mime@^2.2.0:
1793 2004 version "2.4.6"
1794 2005 resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1"
... ... @@ -1833,6 +2044,11 @@ ms@2.0.0:
1833 2044 resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
1834 2045 integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
1835 2046
  2047 +ms@2.1.1:
  2048 + version "2.1.1"
  2049 + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
  2050 + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
  2051 +
1836 2052 ms@^2.1.1:
1837 2053 version "2.1.2"
1838 2054 resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
... ... @@ -1846,6 +2062,11 @@ multistream@^2.1.1:
1846 2062 inherits "^2.0.1"
1847 2063 readable-stream "^2.0.5"
1848 2064
  2065 +negotiator@0.6.2:
  2066 + version "0.6.2"
  2067 + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
  2068 + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
  2069 +
1849 2070 node-fetch@^2.3.0, node-fetch@^2.6.0:
1850 2071 version "2.6.0"
1851 2072 resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
... ... @@ -1899,6 +2120,13 @@ object-hash@^2.0.1:
1899 2120 resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea"
1900 2121 integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==
1901 2122
  2123 +on-finished@~2.3.0:
  2124 + version "2.3.0"
  2125 + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
  2126 + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
  2127 + dependencies:
  2128 + ee-first "1.1.1"
  2129 +
1902 2130 once@^1.3.1, once@^1.4.0:
1903 2131 version "1.4.0"
1904 2132 resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
... ... @@ -1974,6 +2202,11 @@ package-json@^6.3.0:
1974 2202 registry-url "^5.0.0"
1975 2203 semver "^6.2.0"
1976 2204
  2205 +parseurl@~1.3.3:
  2206 + version "1.3.3"
  2207 + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
  2208 + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
  2209 +
1977 2210 path-exists@^4.0.0:
1978 2211 version "4.0.0"
1979 2212 resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
... ... @@ -1984,6 +2217,11 @@ path-parse@^1.0.6:
1984 2217 resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
1985 2218 integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
1986 2219
  2220 +path-to-regexp@0.1.7:
  2221 + version "0.1.7"
  2222 + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
  2223 + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
  2224 +
1987 2225 path-type@^4.0.0:
1988 2226 version "4.0.0"
1989 2227 resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
... ... @@ -2079,6 +2317,14 @@ protobufjs@^6.8.6, protobufjs@^6.9.0:
2079 2317 "@types/node" "^13.7.0"
2080 2318 long "^4.0.0"
2081 2319
  2320 +proxy-addr@~2.0.5:
  2321 + version "2.0.7"
  2322 + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
  2323 + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
  2324 + dependencies:
  2325 + forwarded "0.2.0"
  2326 + ipaddr.js "1.9.1"
  2327 +
2082 2328 psl@^1.1.28, psl@^1.1.33:
2083 2329 version "1.8.0"
2084 2330 resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
... ... @@ -2114,6 +2360,11 @@ pupa@^2.0.1:
2114 2360 dependencies:
2115 2361 escape-goat "^2.0.0"
2116 2362
  2363 +qs@6.7.0:
  2364 + version "6.7.0"
  2365 + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
  2366 + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
  2367 +
2117 2368 qs@~6.5.2:
2118 2369 version "6.5.2"
2119 2370 resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
... ... @@ -2129,6 +2380,21 @@ querystringify@^2.1.1:
2129 2380 resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
2130 2381 integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
2131 2382
  2383 +range-parser@~1.2.1:
  2384 + version "1.2.1"
  2385 + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
  2386 + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
  2387 +
  2388 +raw-body@2.4.0:
  2389 + version "2.4.0"
  2390 + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
  2391 + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==
  2392 + dependencies:
  2393 + bytes "3.1.0"
  2394 + http-errors "1.7.2"
  2395 + iconv-lite "0.4.24"
  2396 + unpipe "1.0.0"
  2397 +
2132 2398 rc@^1.2.8:
2133 2399 version "1.2.8"
2134 2400 resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
... ... @@ -2292,17 +2558,17 @@ run-parallel@^1.1.9:
2292 2558 resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679"
2293 2559 integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==
2294 2560
  2561 +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1, safe-buffer@~5.1.2:
  2562 + version "5.1.2"
  2563 + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
  2564 + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
  2565 +
2295 2566 safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
2296 2567 version "5.2.1"
2297 2568 resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
2298 2569 integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
2299 2570
2300   -safe-buffer@~5.1.0, safe-buffer@~5.1.1, safe-buffer@~5.1.2:
2301   - version "5.1.2"
2302   - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
2303   - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
2304   -
2305   -safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
  2571 +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
2306 2572 version "2.1.2"
2307 2573 resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
2308 2574 integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
... ... @@ -2339,11 +2605,45 @@ semver@^7.1.3:
2339 2605 resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
2340 2606 integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
2341 2607
  2608 +send@0.17.1:
  2609 + version "0.17.1"
  2610 + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
  2611 + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==
  2612 + dependencies:
  2613 + debug "2.6.9"
  2614 + depd "~1.1.2"
  2615 + destroy "~1.0.4"
  2616 + encodeurl "~1.0.2"
  2617 + escape-html "~1.0.3"
  2618 + etag "~1.8.1"
  2619 + fresh "0.5.2"
  2620 + http-errors "~1.7.2"
  2621 + mime "1.6.0"
  2622 + ms "2.1.1"
  2623 + on-finished "~2.3.0"
  2624 + range-parser "~1.2.1"
  2625 + statuses "~1.5.0"
  2626 +
  2627 +serve-static@1.14.1:
  2628 + version "1.14.1"
  2629 + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9"
  2630 + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==
  2631 + dependencies:
  2632 + encodeurl "~1.0.2"
  2633 + escape-html "~1.0.3"
  2634 + parseurl "~1.3.3"
  2635 + send "0.17.1"
  2636 +
2342 2637 set-blocking@^2.0.0:
2343 2638 version "2.0.0"
2344 2639 resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
2345 2640 integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
2346 2641
  2642 +setprototypeof@1.1.1:
  2643 + version "1.1.1"
  2644 + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
  2645 + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
  2646 +
2347 2647 signal-exit@^3.0.2:
2348 2648 version "3.0.3"
2349 2649 resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
... ... @@ -2391,6 +2691,11 @@ stack-trace@0.0.x:
2391 2691 resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
2392 2692 integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
2393 2693
  2694 +"statuses@>= 1.5.0 < 2", statuses@~1.5.0:
  2695 + version "1.5.0"
  2696 + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
  2697 + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
  2698 +
2394 2699 stream-browserify@^2.0.2:
2395 2700 version "2.0.2"
2396 2701 resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
... ... @@ -2513,6 +2818,11 @@ to-regex-range@^5.0.1:
2513 2818 dependencies:
2514 2819 is-number "^7.0.0"
2515 2820
  2821 +toidentifier@1.0.0:
  2822 + version "1.0.0"
  2823 + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
  2824 + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
  2825 +
2516 2826 touch@^3.1.0:
2517 2827 version "3.1.0"
2518 2828 resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b"
... ... @@ -2581,6 +2891,14 @@ type-fest@^0.8.1:
2581 2891 resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
2582 2892 integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
2583 2893
  2894 +type-is@~1.6.17, type-is@~1.6.18:
  2895 + version "1.6.18"
  2896 + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
  2897 + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
  2898 + dependencies:
  2899 + media-typer "0.3.0"
  2900 + mime-types "~2.1.24"
  2901 +
2584 2902 typedarray-to-buffer@^3.1.5:
2585 2903 version "3.1.5"
2586 2904 resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
... ... @@ -2636,6 +2954,11 @@ universalify@^1.0.0:
2636 2954 resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d"
2637 2955 integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==
2638 2956
  2957 +unpipe@1.0.0, unpipe@~1.0.0:
  2958 + version "1.0.0"
  2959 + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
  2960 + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
  2961 +
2639 2962 update-notifier@^4.0.0:
2640 2963 version "4.1.1"
2641 2964 resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.1.tgz#895fc8562bbe666179500f9f2cebac4f26323746"
... ... @@ -2705,6 +3028,11 @@ util@^0.11.1:
2705 3028 dependencies:
2706 3029 inherits "2.0.3"
2707 3030
  3031 +utils-merge@1.0.1:
  3032 + version "1.0.1"
  3033 + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
  3034 + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
  3035 +
2708 3036 uuid-parse@^1.1.0:
2709 3037 version "1.1.0"
2710 3038 resolved "https://registry.yarnpkg.com/uuid-parse/-/uuid-parse-1.1.0.tgz#7061c5a1384ae0e1f943c538094597e1b5f3a65b"
... ... @@ -2735,6 +3063,11 @@ validator@^9.4.1:
2735 3063 resolved "https://registry.yarnpkg.com/validator/-/validator-9.4.1.tgz#abf466d398b561cd243050112c6ff1de6cc12663"
2736 3064 integrity sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==
2737 3065
  3066 +vary@~1.1.2:
  3067 + version "1.1.2"
  3068 + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
  3069 + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
  3070 +
2738 3071 verror@1.10.0:
2739 3072 version "1.10.0"
2740 3073 resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
... ...