@vpalmisano/throttler 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/src/throttle.d.ts +2 -0
- package/build/src/throttle.js +17 -13
- package/build/src/throttle.js.map +1 -1
- package/build/src/utils.js +3 -0
- package/build/src/utils.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/throttle.ts +21 -13
- package/src/utils.ts +2 -0
- package/throttler.js +1 -1
package/build/src/throttle.d.ts
CHANGED
package/build/src/throttle.js
CHANGED
|
@@ -3,12 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.throttleNotifier = void 0;
|
|
6
7
|
exports.startThrottle = startThrottle;
|
|
7
8
|
exports.stopThrottle = stopThrottle;
|
|
8
9
|
exports.getSessionThrottleIndex = getSessionThrottleIndex;
|
|
9
10
|
exports.getSessionThrottleValues = getSessionThrottleValues;
|
|
10
11
|
exports.throttleLauncher = throttleLauncher;
|
|
11
12
|
const child_process_1 = require("child_process");
|
|
13
|
+
const events_1 = require("events");
|
|
12
14
|
const fs_1 = __importDefault(require("fs"));
|
|
13
15
|
const json5_1 = __importDefault(require("json5"));
|
|
14
16
|
const os_1 = __importDefault(require("os"));
|
|
@@ -21,6 +23,12 @@ const throttleCurrentValues = {
|
|
|
21
23
|
up: new Map(),
|
|
22
24
|
down: new Map(),
|
|
23
25
|
};
|
|
26
|
+
exports.throttleNotifier = new events_1.EventEmitter();
|
|
27
|
+
async function runShellCommandIfLinux(cmd, verbose = false) {
|
|
28
|
+
if (os_1.default.platform() === 'linux') {
|
|
29
|
+
await (0, utils_1.runShellCommand)(cmd, verbose);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
24
32
|
async function cleanup() {
|
|
25
33
|
await Promise.allSettled([...captureStops.values()].map(stop => stop()));
|
|
26
34
|
captureStops.clear();
|
|
@@ -28,11 +36,12 @@ async function cleanup() {
|
|
|
28
36
|
ruleTimeouts.clear();
|
|
29
37
|
throttleCurrentValues.up.clear();
|
|
30
38
|
throttleCurrentValues.down.clear();
|
|
39
|
+
exports.throttleNotifier.emit('change');
|
|
31
40
|
let device = throttleConfig?.length ? throttleConfig[0].device : '';
|
|
32
41
|
if (!device) {
|
|
33
42
|
device = await (0, utils_1.getDefaultNetworkInterface)();
|
|
34
43
|
}
|
|
35
|
-
await (
|
|
44
|
+
await runShellCommandIfLinux(`\
|
|
36
45
|
sudo -n tc qdisc del dev ${device} root || true;
|
|
37
46
|
sudo -n tc class del dev ${device} || true;
|
|
38
47
|
sudo -n tc filter del dev ${device} || true;
|
|
@@ -92,7 +101,7 @@ sudo -n tc filter add dev ${device} \
|
|
|
92
101
|
flowid 1:${handle};
|
|
93
102
|
`;
|
|
94
103
|
try {
|
|
95
|
-
await (
|
|
104
|
+
await runShellCommandIfLinux(cmd, true);
|
|
96
105
|
}
|
|
97
106
|
catch (err) {
|
|
98
107
|
log.error(`error running "${cmd}": ${err.stack}`);
|
|
@@ -138,7 +147,7 @@ sudo -n tc filter add dev ${device} \
|
|
|
138
147
|
desc += ` gap ${reorderGap}`;
|
|
139
148
|
}
|
|
140
149
|
}
|
|
141
|
-
log.info(`applying rules on ${device} (${mark}): ${desc}`);
|
|
150
|
+
log.info(`applying rules on ${device} (${mark}): ${desc.trim()}`);
|
|
142
151
|
const cmd = `\
|
|
143
152
|
sudo -n tc qdisc change dev ${device} \
|
|
144
153
|
parent 1:${handle} \
|
|
@@ -146,13 +155,14 @@ sudo -n tc qdisc change dev ${device} \
|
|
|
146
155
|
netem ${desc}`;
|
|
147
156
|
try {
|
|
148
157
|
ruleTimeouts.delete(timeoutId);
|
|
149
|
-
await (
|
|
158
|
+
await runShellCommandIfLinux(cmd);
|
|
150
159
|
throttleCurrentValues[direction].set(index, {
|
|
151
160
|
rate: rate ? 1000 * rate : undefined,
|
|
152
161
|
delay: delay || undefined,
|
|
153
162
|
loss: loss || undefined,
|
|
154
163
|
queue: limit || undefined,
|
|
155
164
|
});
|
|
165
|
+
exports.throttleNotifier.emit('change');
|
|
156
166
|
}
|
|
157
167
|
catch (err) {
|
|
158
168
|
log.error(`error running "${cmd}": ${err.stack}`);
|
|
@@ -177,7 +187,7 @@ async function start() {
|
|
|
177
187
|
if (!device) {
|
|
178
188
|
device = await (0, utils_1.getDefaultNetworkInterface)();
|
|
179
189
|
}
|
|
180
|
-
await (
|
|
190
|
+
await runShellCommandIfLinux(`\
|
|
181
191
|
set -e;
|
|
182
192
|
|
|
183
193
|
sudo -n modprobe ifb || true;
|
|
@@ -209,7 +219,7 @@ sudo -n tc filter add dev ${device} \
|
|
|
209
219
|
if (config.down) {
|
|
210
220
|
await applyRules(config, 'down', 'ifb0', index, config.protocol, config.match);
|
|
211
221
|
}
|
|
212
|
-
if (config.capture) {
|
|
222
|
+
if (config.capture && os_1.default.platform() === 'linux') {
|
|
213
223
|
captureStops.set(index, capturePackets(index, config.capture, config.protocol));
|
|
214
224
|
}
|
|
215
225
|
index++;
|
|
@@ -220,9 +230,6 @@ sudo -n tc filter add dev ${device} \
|
|
|
220
230
|
* @param config A JSON5 configuration parsed as {@link ThrottleConfig}.
|
|
221
231
|
*/
|
|
222
232
|
async function startThrottle(config) {
|
|
223
|
-
if (os_1.default.platform() !== 'linux') {
|
|
224
|
-
throw new Error('Throttle option is only supported on Linux');
|
|
225
|
-
}
|
|
226
233
|
try {
|
|
227
234
|
throttleConfig = json5_1.default.parse(config);
|
|
228
235
|
log.debug('Starting throttle with config:', throttleConfig);
|
|
@@ -239,9 +246,6 @@ async function startThrottle(config) {
|
|
|
239
246
|
* Stops the network throttle.
|
|
240
247
|
*/
|
|
241
248
|
async function stopThrottle() {
|
|
242
|
-
if (os_1.default.platform() !== 'linux') {
|
|
243
|
-
throw new Error('Throttle option is only supported on Linux');
|
|
244
|
-
}
|
|
245
249
|
try {
|
|
246
250
|
log.debug('Stopping throttle');
|
|
247
251
|
await cleanup();
|
|
@@ -332,7 +336,7 @@ async function cleanupRules() {
|
|
|
332
336
|
return;
|
|
333
337
|
log.debug(`cleanupRules (${throttleConfig.length})`);
|
|
334
338
|
try {
|
|
335
|
-
await (
|
|
339
|
+
await runShellCommandIfLinux(`\
|
|
336
340
|
for i in $(seq 0 ${throttleConfig.length}); do
|
|
337
341
|
rule=$(sudo -n iptables -t mangle -L OUTPUT --line-numbers | grep "owner GID match throttler\${i}" | awk '{print $1}');
|
|
338
342
|
if [ -n "$rule" ]; then
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttle.js","sourceRoot":"","sources":["../../src/throttle.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from 'child_process'\nimport fs from 'fs'\nimport JSON5 from 'json5'\nimport os from 'os'\n\nimport {\n checkNetworkInterface,\n getDefaultNetworkInterface,\n logger,\n runShellCommand,\n toPrecision,\n} from './utils'\n\nconst log = logger('throttler:throttle')\n\nlet throttleConfig: ThrottleConfig[] | null = null\n\nconst ruleTimeouts = new Set<NodeJS.Timeout>()\n\nconst captureStops = new Map<number, () => Promise<void>>()\n\nconst throttleCurrentValues = {\n up: new Map<\n number,\n {\n rate?: number\n delay?: number\n delayJitter?: number\n delayJitterCorrelation?: number\n loss?: number\n lossBurst?: number\n queue?: number\n }\n >(),\n down: new Map<\n number,\n {\n rate?: number\n delay?: number\n delayJitterCorrelation?: number\n loss?: number\n lossBurst?: number\n queue?: number\n }\n >(),\n}\n\nasync function cleanup(): Promise<void> {\n await Promise.allSettled([...captureStops.values()].map(stop => stop()))\n captureStops.clear()\n ruleTimeouts.forEach(timeoutId => clearTimeout(timeoutId))\n ruleTimeouts.clear()\n throttleCurrentValues.up.clear()\n throttleCurrentValues.down.clear()\n let device = throttleConfig?.length ? throttleConfig[0].device : ''\n if (!device) {\n device = await getDefaultNetworkInterface()\n }\n await runShellCommand(`\\\nsudo -n tc qdisc del dev ${device} root || true;\nsudo -n tc class del dev ${device} || true;\nsudo -n tc filter del dev ${device} || true;\nsudo -n tc qdisc del dev ${device} ingress || true;\n\nsudo -n tc qdisc del dev ifb0 root || true;\nsudo -n tc class del dev ifb0 root || true;\nsudo -n tc filter del dev ifb0 root || true;\n`)\n await cleanupRules()\n}\n\nfunction calculateBufferedPackets(\n rate: number,\n delay: number,\n mtu = 1500,\n): number {\n // https://lists.linuxfoundation.org/pipermail/netem/2007-March/001094.html\n return Math.ceil((((1.5 * rate * 1000) / 8) * (delay / 1000)) / mtu)\n}\n\n/** The network throttle rules to be applied to uplink or downlink. */\nexport type ThrottleRule = {\n /** The available bandwidth (Kbps). */\n rate?: number\n /** The one-way delay (ms). */\n delay?: number\n /** The one-way delay jitter (ms). */\n delayJitter?: number\n /** The one-way delay jitter correlation. */\n delayJitterCorrelation?: number\n /** The delay distribution. */\n delayDistribution?: 'uniform' | 'normal' | 'pareto' | 'paretonormal'\n /** The packet reordering percentage. */\n reorder?: number\n /** The packet reordering correlation. */\n reorderCorrelation?: number\n /** The packet reordering gap. */\n reorderGap?: number\n /** The packet loss percentage. */\n loss?: number\n /** The packet loss burst. */\n lossBurst?: number\n /** The packet queue size. */\n queue?: number\n /** If set, the rule will be applied after the specified number of seconds. */\n at?: number\n}\n\n/**\n * The network throttling rules.\n * Specify multiple {@link ThrottleRule} with different `at` values to schedule\n * network bandwidth/delay fluctuations during the test run, e.g.:\n *\n * ```javascript\n * {\n device: \"eth0\",\n sessions: \"0-1\",\n protocol: \"udp\",\n down: [\n { rate: 1000000, delay: 50, loss: 0, queue: 5 },\n { rate: 200000, delay: 100, loss: 5, queue: 5, at: 60},\n ],\n up: { rate: 100000, delay: 50, queue: 5 },\n capture: 'capture.pcap',\n }\n * ```\n */\nexport type ThrottleConfig = {\n /** The network interface to throttle. If not specified, the default interface will be used. */\n device?: string\n /** The sessions to throttle. It could be a single index (\"0\"), a range (\"0-2\") or a comma-separated list (\"0,3,4\"). */\n sessions?: string\n /** The protocol to throttle. */\n protocol?: 'udp' | 'tcp'\n /** A comma-separated list of source ports that will not be throttled. */\n skipSourcePorts?: string\n /** A comma-separated list of destination ports that will not be throttled. */\n skipDestinationPorts?: string\n /** An additional IPTables packet filter rule. */\n filter?: string\n /** An additional TC match expression used to filter packets (https://man7.org/linux/man-pages/man8/tc-ematch.8.html). */\n match?: string\n /** If set, the packets matching the provided session and protocol will be captured at that file location. */\n capture?: string\n /** The uplink throttle rules. */\n up?: ThrottleRule | ThrottleRule[]\n /** The downlink throttle rules. */\n down?: ThrottleRule | ThrottleRule[]\n}\n\nasync function applyRules(\n config: ThrottleConfig,\n direction: 'up' | 'down',\n device: string,\n index: number,\n protocol?: 'udp' | 'tcp',\n match?: string,\n): Promise<void> {\n let rules = config[direction]\n if (!rules) return\n log.info(\n `applyRules device=${device} index=${index} protocol=${protocol} match=${match} ${JSON.stringify(\n rules,\n )}`,\n )\n if (!Array.isArray(rules)) {\n rules = [rules]\n }\n rules.sort((a, b) => {\n return (a.at || 0) - (b.at || 0)\n })\n\n for (const [i, rule] of rules.entries()) {\n const {\n rate,\n delay,\n delayJitter,\n delayJitterCorrelation,\n delayDistribution,\n reorder,\n reorderCorrelation,\n reorderGap,\n loss,\n lossBurst,\n queue,\n at,\n } = rule\n const limit = queue ?? calculateBufferedPackets(rate || 0, delay || 0)\n const mark = index + 1\n const handle = index + 2\n\n if (i === 0) {\n const matches = [`'meta(nf_mark eq ${mark})'`]\n if (protocol === 'udp') {\n matches.push(\"'cmp(u8 at 9 layer network eq 0x11)'\")\n } else if (protocol === 'tcp') {\n matches.push(\"'cmp(u8 at 9 layer network eq 0x6)'\")\n }\n if (match) {\n matches.push(match)\n }\n const cmd = `\\\nset -e;\n\nsudo -n tc class add dev ${device} parent 1: classid 1:${handle} htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ${device} \\\n parent 1:${handle} \\\n handle ${handle}: \\\n netem; \\\n\nsudo -n tc filter add dev ${device} \\\n parent 1: \\\n protocol ip \\\n basic match ${matches.join(' and ')} \\\n flowid 1:${handle};\n`\n try {\n await runShellCommand(cmd, true)\n } catch (err) {\n log.error(`error running \"${cmd}\": ${(err as Error).stack}`)\n throw err\n }\n }\n\n const timeoutId = setTimeout(\n async () => {\n let desc = ''\n\n if (rate && rate > 0) {\n desc += ` rate ${rate}kbit`\n }\n\n if (limit && limit > 0) {\n desc += ` limit ${limit}`\n }\n\n if (delay && delay > 0) {\n desc += ` delay ${delay}ms`\n if (delayJitter && delayJitter > 0) {\n desc += ` ${delayJitter}ms`\n if (delayJitterCorrelation && delayJitterCorrelation > 0) {\n desc += ` ${delayJitterCorrelation}`\n }\n }\n if (delayDistribution) {\n desc += ` distribution ${delayDistribution}`\n }\n }\n\n if (loss && loss > 0) {\n if (lossBurst && lossBurst > 0) {\n const p = (100 * loss) / (lossBurst * (100 - loss))\n const r = 100 / lossBurst\n desc += ` loss gemodel ${toPrecision(p, 2)} ${toPrecision(r, 2)}`\n } else {\n desc += ` loss ${toPrecision(loss, 2)}%`\n }\n }\n\n if (reorder && reorder > 0) {\n desc += ` reorder ${toPrecision(reorder, 2)}%`\n if (reorderCorrelation && reorderCorrelation > 0) {\n desc += ` ${toPrecision(reorderCorrelation, 2)}`\n }\n if (reorderGap && reorderGap > 0) {\n desc += ` gap ${reorderGap}`\n }\n }\n\n log.info(`applying rules on ${device} (${mark}): ${desc}`)\n const cmd = `\\\nsudo -n tc qdisc change dev ${device} \\\n parent 1:${handle} \\\n handle ${handle}: \\\n netem ${desc}`\n try {\n ruleTimeouts.delete(timeoutId)\n\n await runShellCommand(cmd)\n\n throttleCurrentValues[direction].set(index, {\n rate: rate ? 1000 * rate : undefined,\n delay: delay || undefined,\n loss: loss || undefined,\n queue: limit || undefined,\n })\n } catch (err) {\n log.error(`error running \"${cmd}\": ${(err as Error).stack}`)\n }\n },\n (at || 0) * 1000,\n )\n\n ruleTimeouts.add(timeoutId)\n }\n}\n\nasync function start(): Promise<void> {\n if (!throttleConfig || !throttleConfig.length) return\n\n let device = throttleConfig[0].device\n if (device) {\n try {\n await checkNetworkInterface(device)\n } catch (_err) {\n log.warn(`Network interface ${device} not found, using default.`)\n device = ''\n }\n }\n if (!device) {\n device = await getDefaultNetworkInterface()\n }\n\n await runShellCommand(\n `\\\nset -e;\n\nsudo -n modprobe ifb || true;\nsudo -n ip link add ifb0 type ifb || true;\nsudo -n ip link set dev ifb0 up;\n\nsudo -n tc qdisc add dev ${device} root handle 1: htb default 1;\nsudo -n tc class add dev ${device} parent 1: classid 1:1 htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ifb0 root handle 1: htb default 1;\nsudo -n tc class add dev ifb0 parent 1: classid 1:1 htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ${device} ingress handle ffff: || true;\nsudo -n tc filter add dev ${device} \\\n parent ffff: \\\n protocol ip \\\n u32 \\\n match u32 0 0 \\\n action connmark \\\n action mirred egress \\\n redirect dev ifb0 \\\n flowid 1:1;\n`,\n true,\n )\n\n let index = 0\n for (const config of throttleConfig) {\n if (config.up) {\n await applyRules(\n config,\n 'up',\n device,\n index,\n config.protocol,\n config.match,\n )\n }\n if (config.down) {\n await applyRules(\n config,\n 'down',\n 'ifb0',\n index,\n config.protocol,\n config.match,\n )\n }\n if (config.capture) {\n captureStops.set(\n index,\n capturePackets(index, config.capture, config.protocol),\n )\n }\n index++\n }\n}\n\n/**\n * Starts a network throttle configuration\n * @param config A JSON5 configuration parsed as {@link ThrottleConfig}.\n */\nexport async function startThrottle(config: string): Promise<void> {\n if (os.platform() !== 'linux') {\n throw new Error('Throttle option is only supported on Linux')\n }\n try {\n throttleConfig = JSON5.parse(config) as ThrottleConfig[]\n log.debug('Starting throttle with config:', throttleConfig)\n await cleanup()\n await start()\n } catch (err) {\n log.error(`startThrottle \"${config}\" error: ${(err as Error).stack}`)\n await stopThrottle()\n throw err\n }\n}\n\n/**\n * Stops the network throttle.\n */\nexport async function stopThrottle(): Promise<void> {\n if (os.platform() !== 'linux') {\n throw new Error('Throttle option is only supported on Linux')\n }\n try {\n log.debug('Stopping throttle')\n await cleanup()\n log.debug('Stopping throttle done')\n throttleConfig = null\n } catch (err) {\n log.error(`Stop throttle error: ${(err as Error).stack}`)\n }\n}\n\nexport function getSessionThrottleIndex(sessionId: number): number {\n if (!throttleConfig) return -1\n\n for (const [index, config] of throttleConfig.entries()) {\n if (config.sessions === undefined || config.sessions === '') {\n continue\n }\n try {\n if (config.sessions.includes('-')) {\n const [start, end] = config.sessions.split('-').map(Number)\n if (sessionId >= start && sessionId <= end) {\n return index\n }\n } else if (config.sessions.includes(',')) {\n const sessions = config.sessions.split(',').map(Number)\n if (sessions.includes(sessionId)) {\n return index\n }\n } else if (sessionId === Number(config.sessions)) {\n return index\n }\n } catch (err) {\n log.error(\n `getSessionThrottleId sessionId=${sessionId} error: ${(err as Error).stack}`,\n )\n }\n }\n\n return -1\n}\n\nexport function getSessionThrottleValues(\n index: number,\n direction: 'up' | 'down',\n): {\n rate?: number\n delay?: number\n loss?: number\n queue?: number\n} {\n if (index < 0) {\n return {}\n }\n return throttleCurrentValues[direction].get(index) || {}\n}\n\nexport async function throttleLauncher(\n executablePath: string,\n index: number,\n): Promise<string> {\n log.debug(`throttleLauncher executablePath=${executablePath} index=${index}`)\n if (!throttleConfig || index < 0) {\n return executablePath\n }\n const config = throttleConfig[index]\n const mark = index + 1\n const launcherPath = `/tmp/throttler-launcher-${index}`\n const group = `throttler${index}`\n const filters = `${config.protocol ? `-p ${config.protocol}` : ''}\\\n${config.skipSourcePorts ? ` -m multiport ! --sports ${config.skipSourcePorts}` : ''}\\\n${config.skipDestinationPorts ? ` -m multiport ! --dports ${config.skipDestinationPorts}` : ''}\\\n${config.filter ? ` ${config.filter}` : ''}`\n await fs.promises.writeFile(\n launcherPath,\n `#!/bin/bash\ngetent group ${group} >/dev/null || sudo -n addgroup --system ${group}\nsudo -n adduser $USER ${group} --quiet\n\nrule=$(sudo -n iptables -t mangle -L OUTPUT --line-numbers | grep \"owner GID match ${group}\" | awk '{print $1}')\nif [ -n \"$rule\" ]; then\n sudo -n iptables -t mangle -R OUTPUT \\${rule} ${filters} -m owner --gid-owner ${group} -j MARK --set-mark ${mark} \nelse\n sudo -n iptables -t mangle -I OUTPUT 1 ${filters} -m owner --gid-owner ${group} -j MARK --set-mark ${mark}\nfi\n\nsudo -n iptables -t mangle -L PREROUTING | grep -q \"CONNMARK restore\" || sudo -n iptables -t mangle -I PREROUTING 1 -j CONNMARK --restore-mark\nsudo -n iptables -t mangle -L POSTROUTING | grep -q \"CONNMARK save\" || sudo -n iptables -t mangle -I POSTROUTING 1 -j CONNMARK --save-mark\n\nfunction stop() {\n echo \"Stopping throttler\"\n}\ntrap stop SIGINT SIGTERM\n\necho \"running: ${executablePath} $@\"\nexec newgrp ${group} <<EOF\n${executablePath} $@\nEOF`,\n )\n await fs.promises.chmod(launcherPath, 0o755)\n return launcherPath\n}\n\nasync function cleanupRules(): Promise<void> {\n if (!throttleConfig?.length) return\n log.debug(`cleanupRules (${throttleConfig.length})`)\n try {\n await runShellCommand(`\\\nfor i in $(seq 0 ${throttleConfig.length}); do\n rule=$(sudo -n iptables -t mangle -L OUTPUT --line-numbers | grep \"owner GID match throttler\\${i}\" | awk '{print $1}');\n if [ -n \"$rule\" ]; then\n sudo -n iptables -t mangle -D OUTPUT \\${rule};\n fi;\ndone;`)\n } catch (err) {\n log.error(`cleanupRules error: ${(err as Error).stack}`)\n }\n}\n\nfunction capturePackets(\n index: number,\n filePath: string,\n protocol?: string,\n): () => Promise<void> {\n const mark = index + 1\n log.info(`Starting capture ${filePath}`)\n const cmd = `#!/bin/bash\nsudo -n iptables -L INPUT | grep -q \"nflog-group ${mark}\" || sudo -n iptables -I INPUT 1 ${protocol ? `-p ${protocol}` : ''} -m connmark --mark ${mark} -j NFLOG --nflog-group ${mark}\nsudo -n iptables -L OUTPUT | grep -q \"nflog-group ${mark}\" || sudo -n iptables -I OUTPUT 1 ${protocol ? `-p ${protocol}` : ''} -m connmark --mark ${mark} -j NFLOG --nflog-group ${mark}\nexec dumpcap -q -i nflog:${mark} -w ${filePath}\n`\n const proc = spawn(cmd, {\n shell: true,\n stdio: ['ignore', 'ignore', 'pipe'],\n detached: true,\n })\n let stderr = ''\n proc.stderr.on('data', data => {\n stderr += data\n })\n proc.on('error', err => {\n log.error(`Error running command capturePackets ${err}: ${stderr}`)\n })\n proc.once('exit', code => {\n if (code) {\n log.error(`capturePackets exited with code ${code}: ${stderr}`)\n } else {\n log.info(`capturePackets exited`)\n }\n })\n\n const stop = async () => {\n log.info(`Stopping capture ${filePath}`)\n proc.kill('SIGINT')\n await runShellCommand(`#!/bin/bash\nsudo -n iptables -D INPUT ${protocol ? `-p ${protocol}` : ''} -m connmark --mark ${mark} -j NFLOG --nflog-group ${mark}\nsudo -n iptables -D OUTPUT ${protocol ? `-p ${protocol}` : ''} -m connmark --mark ${mark} -j NFLOG --nflog-group ${mark}\n`)\n }\n\n return stop\n}\n"]}
|
|
1
|
+
{"version":3,"file":"throttle.js","sourceRoot":"","sources":["../../src/throttle.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from 'child_process'\nimport { EventEmitter } from 'events'\nimport fs from 'fs'\nimport JSON5 from 'json5'\nimport os from 'os'\n\nimport {\n checkNetworkInterface,\n getDefaultNetworkInterface,\n logger,\n runShellCommand,\n toPrecision,\n} from './utils'\n\nconst log = logger('throttler:throttle')\n\nlet throttleConfig: ThrottleConfig[] | null = null\n\nconst ruleTimeouts = new Set<NodeJS.Timeout>()\n\nconst captureStops = new Map<number, () => Promise<void>>()\n\nconst throttleCurrentValues = {\n up: new Map<\n number,\n {\n rate?: number\n delay?: number\n delayJitter?: number\n delayJitterCorrelation?: number\n loss?: number\n lossBurst?: number\n queue?: number\n }\n >(),\n down: new Map<\n number,\n {\n rate?: number\n delay?: number\n delayJitterCorrelation?: number\n loss?: number\n lossBurst?: number\n queue?: number\n }\n >(),\n}\n\nexport const throttleNotifier = new EventEmitter()\n\nasync function runShellCommandIfLinux(\n cmd: string,\n verbose = false,\n): Promise<void> {\n if (os.platform() === 'linux') {\n await runShellCommand(cmd, verbose)\n }\n}\n\nasync function cleanup(): Promise<void> {\n await Promise.allSettled([...captureStops.values()].map(stop => stop()))\n captureStops.clear()\n ruleTimeouts.forEach(timeoutId => clearTimeout(timeoutId))\n ruleTimeouts.clear()\n throttleCurrentValues.up.clear()\n throttleCurrentValues.down.clear()\n throttleNotifier.emit('change')\n let device = throttleConfig?.length ? throttleConfig[0].device : ''\n if (!device) {\n device = await getDefaultNetworkInterface()\n }\n await runShellCommandIfLinux(`\\\nsudo -n tc qdisc del dev ${device} root || true;\nsudo -n tc class del dev ${device} || true;\nsudo -n tc filter del dev ${device} || true;\nsudo -n tc qdisc del dev ${device} ingress || true;\n\nsudo -n tc qdisc del dev ifb0 root || true;\nsudo -n tc class del dev ifb0 root || true;\nsudo -n tc filter del dev ifb0 root || true;\n`)\n await cleanupRules()\n}\n\nfunction calculateBufferedPackets(\n rate: number,\n delay: number,\n mtu = 1500,\n): number {\n // https://lists.linuxfoundation.org/pipermail/netem/2007-March/001094.html\n return Math.ceil((((1.5 * rate * 1000) / 8) * (delay / 1000)) / mtu)\n}\n\n/** The network throttle rules to be applied to uplink or downlink. */\nexport type ThrottleRule = {\n /** The available bandwidth (Kbps). */\n rate?: number\n /** The one-way delay (ms). */\n delay?: number\n /** The one-way delay jitter (ms). */\n delayJitter?: number\n /** The one-way delay jitter correlation. */\n delayJitterCorrelation?: number\n /** The delay distribution. */\n delayDistribution?: 'uniform' | 'normal' | 'pareto' | 'paretonormal'\n /** The packet reordering percentage. */\n reorder?: number\n /** The packet reordering correlation. */\n reorderCorrelation?: number\n /** The packet reordering gap. */\n reorderGap?: number\n /** The packet loss percentage. */\n loss?: number\n /** The packet loss burst. */\n lossBurst?: number\n /** The packet queue size. */\n queue?: number\n /** If set, the rule will be applied after the specified number of seconds. */\n at?: number\n}\n\n/**\n * The network throttling rules.\n * Specify multiple {@link ThrottleRule} with different `at` values to schedule\n * network bandwidth/delay fluctuations during the test run, e.g.:\n *\n * ```javascript\n * {\n device: \"eth0\",\n sessions: \"0-1\",\n protocol: \"udp\",\n down: [\n { rate: 1000000, delay: 50, loss: 0, queue: 5 },\n { rate: 200000, delay: 100, loss: 5, queue: 5, at: 60},\n ],\n up: { rate: 100000, delay: 50, queue: 5 },\n capture: 'capture.pcap',\n }\n * ```\n */\nexport type ThrottleConfig = {\n /** The network interface to throttle. If not specified, the default interface will be used. */\n device?: string\n /** The sessions to throttle. It could be a single index (\"0\"), a range (\"0-2\") or a comma-separated list (\"0,3,4\"). */\n sessions?: string\n /** The protocol to throttle. */\n protocol?: 'udp' | 'tcp'\n /** A comma-separated list of source ports that will not be throttled. */\n skipSourcePorts?: string\n /** A comma-separated list of destination ports that will not be throttled. */\n skipDestinationPorts?: string\n /** An additional IPTables packet filter rule. */\n filter?: string\n /** An additional TC match expression used to filter packets (https://man7.org/linux/man-pages/man8/tc-ematch.8.html). */\n match?: string\n /** If set, the packets matching the provided session and protocol will be captured at that file location. */\n capture?: string\n /** The uplink throttle rules. */\n up?: ThrottleRule | ThrottleRule[]\n /** The downlink throttle rules. */\n down?: ThrottleRule | ThrottleRule[]\n}\n\nasync function applyRules(\n config: ThrottleConfig,\n direction: 'up' | 'down',\n device: string,\n index: number,\n protocol?: 'udp' | 'tcp',\n match?: string,\n): Promise<void> {\n let rules = config[direction]\n if (!rules) return\n log.info(\n `applyRules device=${device} index=${index} protocol=${protocol} match=${match} ${JSON.stringify(\n rules,\n )}`,\n )\n if (!Array.isArray(rules)) {\n rules = [rules]\n }\n rules.sort((a, b) => {\n return (a.at || 0) - (b.at || 0)\n })\n\n for (const [i, rule] of rules.entries()) {\n const {\n rate,\n delay,\n delayJitter,\n delayJitterCorrelation,\n delayDistribution,\n reorder,\n reorderCorrelation,\n reorderGap,\n loss,\n lossBurst,\n queue,\n at,\n } = rule\n const limit = queue ?? calculateBufferedPackets(rate || 0, delay || 0)\n const mark = index + 1\n const handle = index + 2\n\n if (i === 0) {\n const matches = [`'meta(nf_mark eq ${mark})'`]\n if (protocol === 'udp') {\n matches.push(\"'cmp(u8 at 9 layer network eq 0x11)'\")\n } else if (protocol === 'tcp') {\n matches.push(\"'cmp(u8 at 9 layer network eq 0x6)'\")\n }\n if (match) {\n matches.push(match)\n }\n const cmd = `\\\nset -e;\n\nsudo -n tc class add dev ${device} parent 1: classid 1:${handle} htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ${device} \\\n parent 1:${handle} \\\n handle ${handle}: \\\n netem; \\\n\nsudo -n tc filter add dev ${device} \\\n parent 1: \\\n protocol ip \\\n basic match ${matches.join(' and ')} \\\n flowid 1:${handle};\n`\n try {\n await runShellCommandIfLinux(cmd, true)\n } catch (err) {\n log.error(`error running \"${cmd}\": ${(err as Error).stack}`)\n throw err\n }\n }\n\n const timeoutId = setTimeout(\n async () => {\n let desc = ''\n\n if (rate && rate > 0) {\n desc += ` rate ${rate}kbit`\n }\n\n if (limit && limit > 0) {\n desc += ` limit ${limit}`\n }\n\n if (delay && delay > 0) {\n desc += ` delay ${delay}ms`\n if (delayJitter && delayJitter > 0) {\n desc += ` ${delayJitter}ms`\n if (delayJitterCorrelation && delayJitterCorrelation > 0) {\n desc += ` ${delayJitterCorrelation}`\n }\n }\n if (delayDistribution) {\n desc += ` distribution ${delayDistribution}`\n }\n }\n\n if (loss && loss > 0) {\n if (lossBurst && lossBurst > 0) {\n const p = (100 * loss) / (lossBurst * (100 - loss))\n const r = 100 / lossBurst\n desc += ` loss gemodel ${toPrecision(p, 2)} ${toPrecision(r, 2)}`\n } else {\n desc += ` loss ${toPrecision(loss, 2)}%`\n }\n }\n\n if (reorder && reorder > 0) {\n desc += ` reorder ${toPrecision(reorder, 2)}%`\n if (reorderCorrelation && reorderCorrelation > 0) {\n desc += ` ${toPrecision(reorderCorrelation, 2)}`\n }\n if (reorderGap && reorderGap > 0) {\n desc += ` gap ${reorderGap}`\n }\n }\n\n log.info(`applying rules on ${device} (${mark}): ${desc.trim()}`)\n const cmd = `\\\nsudo -n tc qdisc change dev ${device} \\\n parent 1:${handle} \\\n handle ${handle}: \\\n netem ${desc}`\n try {\n ruleTimeouts.delete(timeoutId)\n\n await runShellCommandIfLinux(cmd)\n\n throttleCurrentValues[direction].set(index, {\n rate: rate ? 1000 * rate : undefined,\n delay: delay || undefined,\n loss: loss || undefined,\n queue: limit || undefined,\n })\n throttleNotifier.emit('change')\n } catch (err) {\n log.error(`error running \"${cmd}\": ${(err as Error).stack}`)\n }\n },\n (at || 0) * 1000,\n )\n\n ruleTimeouts.add(timeoutId)\n }\n}\n\nasync function start(): Promise<void> {\n if (!throttleConfig || !throttleConfig.length) return\n\n let device = throttleConfig[0].device\n if (device) {\n try {\n await checkNetworkInterface(device)\n } catch (_err) {\n log.warn(`Network interface ${device} not found, using default.`)\n device = ''\n }\n }\n if (!device) {\n device = await getDefaultNetworkInterface()\n }\n\n await runShellCommandIfLinux(\n `\\\nset -e;\n\nsudo -n modprobe ifb || true;\nsudo -n ip link add ifb0 type ifb || true;\nsudo -n ip link set dev ifb0 up;\n\nsudo -n tc qdisc add dev ${device} root handle 1: htb default 1;\nsudo -n tc class add dev ${device} parent 1: classid 1:1 htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ifb0 root handle 1: htb default 1;\nsudo -n tc class add dev ifb0 parent 1: classid 1:1 htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ${device} ingress handle ffff: || true;\nsudo -n tc filter add dev ${device} \\\n parent ffff: \\\n protocol ip \\\n u32 \\\n match u32 0 0 \\\n action connmark \\\n action mirred egress \\\n redirect dev ifb0 \\\n flowid 1:1;\n`,\n true,\n )\n\n let index = 0\n for (const config of throttleConfig) {\n if (config.up) {\n await applyRules(\n config,\n 'up',\n device,\n index,\n config.protocol,\n config.match,\n )\n }\n if (config.down) {\n await applyRules(\n config,\n 'down',\n 'ifb0',\n index,\n config.protocol,\n config.match,\n )\n }\n if (config.capture && os.platform() === 'linux') {\n captureStops.set(\n index,\n capturePackets(index, config.capture, config.protocol),\n )\n }\n index++\n }\n}\n\n/**\n * Starts a network throttle configuration\n * @param config A JSON5 configuration parsed as {@link ThrottleConfig}.\n */\nexport async function startThrottle(config: string): Promise<void> {\n try {\n throttleConfig = JSON5.parse(config) as ThrottleConfig[]\n log.debug('Starting throttle with config:', throttleConfig)\n await cleanup()\n await start()\n } catch (err) {\n log.error(`startThrottle \"${config}\" error: ${(err as Error).stack}`)\n await stopThrottle()\n throw err\n }\n}\n\n/**\n * Stops the network throttle.\n */\nexport async function stopThrottle(): Promise<void> {\n try {\n log.debug('Stopping throttle')\n await cleanup()\n log.debug('Stopping throttle done')\n throttleConfig = null\n } catch (err) {\n log.error(`Stop throttle error: ${(err as Error).stack}`)\n }\n}\n\nexport function getSessionThrottleIndex(sessionId: number): number {\n if (!throttleConfig) return -1\n\n for (const [index, config] of throttleConfig.entries()) {\n if (config.sessions === undefined || config.sessions === '') {\n continue\n }\n try {\n if (config.sessions.includes('-')) {\n const [start, end] = config.sessions.split('-').map(Number)\n if (sessionId >= start && sessionId <= end) {\n return index\n }\n } else if (config.sessions.includes(',')) {\n const sessions = config.sessions.split(',').map(Number)\n if (sessions.includes(sessionId)) {\n return index\n }\n } else if (sessionId === Number(config.sessions)) {\n return index\n }\n } catch (err) {\n log.error(\n `getSessionThrottleId sessionId=${sessionId} error: ${(err as Error).stack}`,\n )\n }\n }\n\n return -1\n}\n\nexport function getSessionThrottleValues(\n index: number,\n direction: 'up' | 'down',\n): {\n rate?: number\n delay?: number\n loss?: number\n queue?: number\n} {\n if (index < 0) {\n return {}\n }\n return throttleCurrentValues[direction].get(index) || {}\n}\n\nexport async function throttleLauncher(\n executablePath: string,\n index: number,\n): Promise<string> {\n log.debug(`throttleLauncher executablePath=${executablePath} index=${index}`)\n if (!throttleConfig || index < 0) {\n return executablePath\n }\n const config = throttleConfig[index]\n const mark = index + 1\n const launcherPath = `/tmp/throttler-launcher-${index}`\n const group = `throttler${index}`\n const filters = `${config.protocol ? `-p ${config.protocol}` : ''}\\\n${config.skipSourcePorts ? ` -m multiport ! --sports ${config.skipSourcePorts}` : ''}\\\n${config.skipDestinationPorts ? ` -m multiport ! --dports ${config.skipDestinationPorts}` : ''}\\\n${config.filter ? ` ${config.filter}` : ''}`\n await fs.promises.writeFile(\n launcherPath,\n `#!/bin/bash\ngetent group ${group} >/dev/null || sudo -n addgroup --system ${group}\nsudo -n adduser $USER ${group} --quiet\n\nrule=$(sudo -n iptables -t mangle -L OUTPUT --line-numbers | grep \"owner GID match ${group}\" | awk '{print $1}')\nif [ -n \"$rule\" ]; then\n sudo -n iptables -t mangle -R OUTPUT \\${rule} ${filters} -m owner --gid-owner ${group} -j MARK --set-mark ${mark} \nelse\n sudo -n iptables -t mangle -I OUTPUT 1 ${filters} -m owner --gid-owner ${group} -j MARK --set-mark ${mark}\nfi\n\nsudo -n iptables -t mangle -L PREROUTING | grep -q \"CONNMARK restore\" || sudo -n iptables -t mangle -I PREROUTING 1 -j CONNMARK --restore-mark\nsudo -n iptables -t mangle -L POSTROUTING | grep -q \"CONNMARK save\" || sudo -n iptables -t mangle -I POSTROUTING 1 -j CONNMARK --save-mark\n\nfunction stop() {\n echo \"Stopping throttler\"\n}\ntrap stop SIGINT SIGTERM\n\necho \"running: ${executablePath} $@\"\nexec newgrp ${group} <<EOF\n${executablePath} $@\nEOF`,\n )\n await fs.promises.chmod(launcherPath, 0o755)\n return launcherPath\n}\n\nasync function cleanupRules(): Promise<void> {\n if (!throttleConfig?.length) return\n log.debug(`cleanupRules (${throttleConfig.length})`)\n try {\n await runShellCommandIfLinux(`\\\nfor i in $(seq 0 ${throttleConfig.length}); do\n rule=$(sudo -n iptables -t mangle -L OUTPUT --line-numbers | grep \"owner GID match throttler\\${i}\" | awk '{print $1}');\n if [ -n \"$rule\" ]; then\n sudo -n iptables -t mangle -D OUTPUT \\${rule};\n fi;\ndone;`)\n } catch (err) {\n log.error(`cleanupRules error: ${(err as Error).stack}`)\n }\n}\n\nfunction capturePackets(\n index: number,\n filePath: string,\n protocol?: string,\n): () => Promise<void> {\n const mark = index + 1\n log.info(`Starting capture ${filePath}`)\n const cmd = `#!/bin/bash\nsudo -n iptables -L INPUT | grep -q \"nflog-group ${mark}\" || sudo -n iptables -I INPUT 1 ${protocol ? `-p ${protocol}` : ''} -m connmark --mark ${mark} -j NFLOG --nflog-group ${mark}\nsudo -n iptables -L OUTPUT | grep -q \"nflog-group ${mark}\" || sudo -n iptables -I OUTPUT 1 ${protocol ? `-p ${protocol}` : ''} -m connmark --mark ${mark} -j NFLOG --nflog-group ${mark}\nexec dumpcap -q -i nflog:${mark} -w ${filePath}\n`\n const proc = spawn(cmd, {\n shell: true,\n stdio: ['ignore', 'ignore', 'pipe'],\n detached: true,\n })\n let stderr = ''\n proc.stderr.on('data', data => {\n stderr += data\n })\n proc.on('error', err => {\n log.error(`Error running command capturePackets ${err}: ${stderr}`)\n })\n proc.once('exit', code => {\n if (code) {\n log.error(`capturePackets exited with code ${code}: ${stderr}`)\n } else {\n log.info(`capturePackets exited`)\n }\n })\n\n const stop = async () => {\n log.info(`Stopping capture ${filePath}`)\n proc.kill('SIGINT')\n await runShellCommand(`#!/bin/bash\nsudo -n iptables -D INPUT ${protocol ? `-p ${protocol}` : ''} -m connmark --mark ${mark} -j NFLOG --nflog-group ${mark}\nsudo -n iptables -D OUTPUT ${protocol ? `-p ${protocol}` : ''} -m connmark --mark ${mark} -j NFLOG --nflog-group ${mark}\n`)\n }\n\n return stop\n}\n"]}
|
package/build/src/utils.js
CHANGED
|
@@ -16,6 +16,7 @@ exports.runExitHandlersNow = runExitHandlersNow;
|
|
|
16
16
|
exports.getProcessChildren = getProcessChildren;
|
|
17
17
|
const child_process_1 = require("child_process");
|
|
18
18
|
const fs_1 = __importDefault(require("fs"));
|
|
19
|
+
const os_1 = __importDefault(require("os"));
|
|
19
20
|
const path_1 = __importDefault(require("path"));
|
|
20
21
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
21
22
|
exports.Log = require('debug-level').Log;
|
|
@@ -81,6 +82,8 @@ function toPrecision(value, precision = 3) {
|
|
|
81
82
|
return (Math.round(value * 10 ** precision) / 10 ** precision).toFixed(precision);
|
|
82
83
|
}
|
|
83
84
|
async function getDefaultNetworkInterface() {
|
|
85
|
+
if (os_1.default.platform() !== 'linux')
|
|
86
|
+
return 'lo';
|
|
84
87
|
const { stdout } = await runShellCommand(`ip route | awk '/default/ {print $5; exit}' | tr -d ''`);
|
|
85
88
|
return stdout.trim();
|
|
86
89
|
}
|
package/build/src/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from 'child_process'\nimport fs from 'fs'\nimport path from 'path'\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nexport const { Log } = require('debug-level')\n\ntype Logger = {\n error: (...args: unknown[]) => void\n warn: (...args: unknown[]) => void\n info: (...args: unknown[]) => void\n debug: (...args: unknown[]) => void\n log: (...args: unknown[]) => void\n}\n\nexport function logger(name: string, options = {}): Logger {\n return new Log(name, { splitLine: false, ...options })\n}\n\nexport class LoggerInterface {\n name?: string\n\n private logInit(args: unknown[]): void {\n if (this.name) {\n args.unshift(`[${this.name}]`)\n }\n }\n\n debug(...args: unknown[]): void {\n this.logInit(args)\n log.debug(...args)\n }\n\n info(...args: unknown[]): void {\n this.logInit(args)\n log.info(...args)\n }\n\n warn(...args: unknown[]): void {\n this.logInit(args)\n log.warn(...args)\n }\n\n error(...args: unknown[]): void {\n this.logInit(args)\n log.error(...args)\n }\n\n log(...args: unknown[]): void {\n this.logInit(args)\n log.log(...args)\n }\n}\n\nconst log = logger('webrtcperf:utils')\n\n/**\n * Resolves the absolute path from the package installation directory.\n * @param relativePath The relative path.\n * @returns The absolute path.\n */\nexport function resolvePackagePath(relativePath: string): string {\n if ('__nexe' in process) {\n return relativePath\n }\n if (process.env.WEBPACK) {\n return path.join(path.dirname(__filename), relativePath)\n }\n for (const d of ['..', '../..']) {\n const p = path.join(__dirname, d, relativePath)\n if (fs.existsSync(p)) {\n return require.resolve(p)\n }\n }\n throw new Error(`resolvePackagePath: ${relativePath} not found`)\n}\n\n/**\n * Format number to the specified precision.\n * @param value value to format\n * @param precision precision\n */\nexport function toPrecision(value: number, precision = 3): string {\n return (Math.round(value * 10 ** precision) / 10 ** precision).toFixed(\n precision,\n )\n}\n\nexport async function getDefaultNetworkInterface(): Promise<string> {\n const { stdout } = await runShellCommand(\n `ip route | awk '/default/ {print $5; exit}' | tr -d ''`,\n )\n return stdout.trim()\n}\n\nexport async function checkNetworkInterface(device: string): Promise<void> {\n if (device === 'lo') return\n await runShellCommand(`ip route | grep -q \"dev ${device}\"`)\n}\n\n/** Runs the shell command asynchronously. */\nexport async function runShellCommand(\n cmd: string,\n verbose = false,\n): Promise<{ stdout: string; stderr: string }> {\n if (verbose) log.debug(`runShellCommand cmd: ${cmd}`)\n return new Promise((resolve, reject) => {\n const p = spawn(cmd, {\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: true,\n })\n let stdout = ''\n let stderr = ''\n p.stdout.on('data', data => {\n if (stdout.length > 512 * 1024) {\n stdout = stdout.slice(data.length)\n }\n stdout += data\n })\n p.stderr.on('data', data => {\n if (stderr.length > 512 * 1024) {\n stderr = stderr.slice(data.length)\n }\n stderr += data\n })\n p.once('error', err => reject(err))\n p.once('close', code => {\n if (code !== 0) {\n reject(\n new Error(\n `runShellCommand cmd: ${cmd} failed with code ${code}: ${stderr}`,\n ),\n )\n } else {\n if (verbose)\n log.debug(`runShellCommand cmd: ${cmd} done`, { stdout, stderr })\n resolve({ stdout, stderr })\n }\n })\n })\n}\n\n/** Exit handler callback. */\nexport type ExitHandler = (signal?: string) => Promise<void>\n\nconst exitHandlers = new Set<ExitHandler>()\n\n/**\n * Register an {@link ExitHandler} callback that will be executed at the\n * nodejs process exit.\n * @param exitHandler\n */\nexport function registerExitHandler(exitHandler: ExitHandler): void {\n exitHandlers.add(exitHandler)\n}\n\n/**\n * Un-registers the {@link ExitHandler} callback.\n * @param exitHandler\n */\nexport function unregisterExitHandler(exitHandler: ExitHandler): void {\n exitHandlers.delete(exitHandler)\n}\n\nconst runExitHandlers = async (signal?: string): Promise<void> => {\n let i = 0\n for (const exitHandler of exitHandlers.values()) {\n const id = `${i + 1}/${exitHandlers.size}`\n log.debug(`running exitHandler ${id}`)\n try {\n await exitHandler(signal)\n log.debug(` exitHandler ${id} done`)\n } catch (err) {\n log.error(`exitHandler ${id} error: ${err}`)\n }\n i++\n }\n exitHandlers.clear()\n}\n\nlet runExitHandlersPromise: Promise<void> | null = null\n\n/**\n * Runs the registered exit handlers immediately.\n * @param signal The process exit signal.\n */\nexport async function runExitHandlersNow(signal?: string): Promise<void> {\n if (!runExitHandlersPromise) {\n runExitHandlersPromise = runExitHandlers(signal)\n }\n await runExitHandlersPromise\n}\n\nconst SIGNALS = [\n 'beforeExit',\n 'uncaughtException',\n 'unhandledRejection',\n 'SIGHUP',\n 'SIGINT',\n 'SIGQUIT',\n 'SIGILL',\n 'SIGTRAP',\n 'SIGABRT',\n 'SIGBUS',\n 'SIGFPE',\n 'SIGUSR1',\n 'SIGSEGV',\n 'SIGUSR2',\n 'SIGTERM',\n]\nprocess.setMaxListeners(process.getMaxListeners() + SIGNALS.length)\nSIGNALS.forEach(event =>\n process.once(event, async signal => {\n if (signal instanceof Error) {\n log.error(`Exit on error: ${signal.stack || signal.message}`)\n } else {\n log.debug(`Exit on signal: ${signal}`)\n }\n await runExitHandlersNow(signal)\n process.exit(0)\n }),\n)\n\nexport async function getProcessChildren(pid: number): Promise<number[]> {\n log.debug(`getProcessChildren pid=${pid}`)\n const pids = []\n try {\n const p = await runShellCommand(`pgrep -P ${pid}`)\n for (const pid of p.stdout.trim().split('\\n').map(Number)) {\n pids.push(pid)\n try {\n const childPids = await getProcessChildren(pid)\n for (const p of childPids) {\n pids.push(p)\n }\n } catch (err) {\n log.debug(\n `Error getting process ${pid} children: ${(err as Error).message}`,\n )\n }\n }\n } catch (err) {\n log.debug(\n `Error getting process ${pid} children: ${(err as Error).message}`,\n )\n }\n return pids\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from 'child_process'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nexport const { Log } = require('debug-level')\n\ntype Logger = {\n error: (...args: unknown[]) => void\n warn: (...args: unknown[]) => void\n info: (...args: unknown[]) => void\n debug: (...args: unknown[]) => void\n log: (...args: unknown[]) => void\n}\n\nexport function logger(name: string, options = {}): Logger {\n return new Log(name, { splitLine: false, ...options })\n}\n\nexport class LoggerInterface {\n name?: string\n\n private logInit(args: unknown[]): void {\n if (this.name) {\n args.unshift(`[${this.name}]`)\n }\n }\n\n debug(...args: unknown[]): void {\n this.logInit(args)\n log.debug(...args)\n }\n\n info(...args: unknown[]): void {\n this.logInit(args)\n log.info(...args)\n }\n\n warn(...args: unknown[]): void {\n this.logInit(args)\n log.warn(...args)\n }\n\n error(...args: unknown[]): void {\n this.logInit(args)\n log.error(...args)\n }\n\n log(...args: unknown[]): void {\n this.logInit(args)\n log.log(...args)\n }\n}\n\nconst log = logger('webrtcperf:utils')\n\n/**\n * Resolves the absolute path from the package installation directory.\n * @param relativePath The relative path.\n * @returns The absolute path.\n */\nexport function resolvePackagePath(relativePath: string): string {\n if ('__nexe' in process) {\n return relativePath\n }\n if (process.env.WEBPACK) {\n return path.join(path.dirname(__filename), relativePath)\n }\n for (const d of ['..', '../..']) {\n const p = path.join(__dirname, d, relativePath)\n if (fs.existsSync(p)) {\n return require.resolve(p)\n }\n }\n throw new Error(`resolvePackagePath: ${relativePath} not found`)\n}\n\n/**\n * Format number to the specified precision.\n * @param value value to format\n * @param precision precision\n */\nexport function toPrecision(value: number, precision = 3): string {\n return (Math.round(value * 10 ** precision) / 10 ** precision).toFixed(\n precision,\n )\n}\n\nexport async function getDefaultNetworkInterface(): Promise<string> {\n if (os.platform() !== 'linux') return 'lo'\n const { stdout } = await runShellCommand(\n `ip route | awk '/default/ {print $5; exit}' | tr -d ''`,\n )\n return stdout.trim()\n}\n\nexport async function checkNetworkInterface(device: string): Promise<void> {\n if (device === 'lo') return\n await runShellCommand(`ip route | grep -q \"dev ${device}\"`)\n}\n\n/** Runs the shell command asynchronously. */\nexport async function runShellCommand(\n cmd: string,\n verbose = false,\n): Promise<{ stdout: string; stderr: string }> {\n if (verbose) log.debug(`runShellCommand cmd: ${cmd}`)\n return new Promise((resolve, reject) => {\n const p = spawn(cmd, {\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: true,\n })\n let stdout = ''\n let stderr = ''\n p.stdout.on('data', data => {\n if (stdout.length > 512 * 1024) {\n stdout = stdout.slice(data.length)\n }\n stdout += data\n })\n p.stderr.on('data', data => {\n if (stderr.length > 512 * 1024) {\n stderr = stderr.slice(data.length)\n }\n stderr += data\n })\n p.once('error', err => reject(err))\n p.once('close', code => {\n if (code !== 0) {\n reject(\n new Error(\n `runShellCommand cmd: ${cmd} failed with code ${code}: ${stderr}`,\n ),\n )\n } else {\n if (verbose)\n log.debug(`runShellCommand cmd: ${cmd} done`, { stdout, stderr })\n resolve({ stdout, stderr })\n }\n })\n })\n}\n\n/** Exit handler callback. */\nexport type ExitHandler = (signal?: string) => Promise<void>\n\nconst exitHandlers = new Set<ExitHandler>()\n\n/**\n * Register an {@link ExitHandler} callback that will be executed at the\n * nodejs process exit.\n * @param exitHandler\n */\nexport function registerExitHandler(exitHandler: ExitHandler): void {\n exitHandlers.add(exitHandler)\n}\n\n/**\n * Un-registers the {@link ExitHandler} callback.\n * @param exitHandler\n */\nexport function unregisterExitHandler(exitHandler: ExitHandler): void {\n exitHandlers.delete(exitHandler)\n}\n\nconst runExitHandlers = async (signal?: string): Promise<void> => {\n let i = 0\n for (const exitHandler of exitHandlers.values()) {\n const id = `${i + 1}/${exitHandlers.size}`\n log.debug(`running exitHandler ${id}`)\n try {\n await exitHandler(signal)\n log.debug(` exitHandler ${id} done`)\n } catch (err) {\n log.error(`exitHandler ${id} error: ${err}`)\n }\n i++\n }\n exitHandlers.clear()\n}\n\nlet runExitHandlersPromise: Promise<void> | null = null\n\n/**\n * Runs the registered exit handlers immediately.\n * @param signal The process exit signal.\n */\nexport async function runExitHandlersNow(signal?: string): Promise<void> {\n if (!runExitHandlersPromise) {\n runExitHandlersPromise = runExitHandlers(signal)\n }\n await runExitHandlersPromise\n}\n\nconst SIGNALS = [\n 'beforeExit',\n 'uncaughtException',\n 'unhandledRejection',\n 'SIGHUP',\n 'SIGINT',\n 'SIGQUIT',\n 'SIGILL',\n 'SIGTRAP',\n 'SIGABRT',\n 'SIGBUS',\n 'SIGFPE',\n 'SIGUSR1',\n 'SIGSEGV',\n 'SIGUSR2',\n 'SIGTERM',\n]\nprocess.setMaxListeners(process.getMaxListeners() + SIGNALS.length)\nSIGNALS.forEach(event =>\n process.once(event, async signal => {\n if (signal instanceof Error) {\n log.error(`Exit on error: ${signal.stack || signal.message}`)\n } else {\n log.debug(`Exit on signal: ${signal}`)\n }\n await runExitHandlersNow(signal)\n process.exit(0)\n }),\n)\n\nexport async function getProcessChildren(pid: number): Promise<number[]> {\n log.debug(`getProcessChildren pid=${pid}`)\n const pids = []\n try {\n const p = await runShellCommand(`pgrep -P ${pid}`)\n for (const pid of p.stdout.trim().split('\\n').map(Number)) {\n pids.push(pid)\n try {\n const childPids = await getProcessChildren(pid)\n for (const p of childPids) {\n pids.push(p)\n }\n } catch (err) {\n log.debug(\n `Error getting process ${pid} children: ${(err as Error).message}`,\n )\n }\n }\n } catch (err) {\n log.debug(\n `Error getting process ${pid} children: ${(err as Error).message}`,\n )\n }\n return pids\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"fileNames":["../node_modules/typescript/lib/lib.es5.d.ts","../node_modules/typescript/lib/lib.es2015.d.ts","../node_modules/typescript/lib/lib.es2016.d.ts","../node_modules/typescript/lib/lib.es2017.d.ts","../node_modules/typescript/lib/lib.es2018.d.ts","../node_modules/typescript/lib/lib.es2019.d.ts","../node_modules/typescript/lib/lib.es2020.d.ts","../node_modules/typescript/lib/lib.es2021.d.ts","../node_modules/typescript/lib/lib.es2022.d.ts","../node_modules/typescript/lib/lib.dom.d.ts","../node_modules/typescript/lib/lib.dom.iterable.d.ts","../node_modules/typescript/lib/lib.dom.asynciterable.d.ts","../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../node_modules/typescript/lib/lib.scripthost.d.ts","../node_modules/typescript/lib/lib.es2015.core.d.ts","../node_modules/typescript/lib/lib.es2015.collection.d.ts","../node_modules/typescript/lib/lib.es2015.generator.d.ts","../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../node_modules/typescript/lib/lib.es2015.promise.d.ts","../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../node_modules/typescript/lib/lib.es2016.intl.d.ts","../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../node_modules/typescript/lib/lib.es2017.date.d.ts","../node_modules/typescript/lib/lib.es2017.object.d.ts","../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2017.string.d.ts","../node_modules/typescript/lib/lib.es2017.intl.d.ts","../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../node_modules/typescript/lib/lib.es2018.intl.d.ts","../node_modules/typescript/lib/lib.es2018.promise.d.ts","../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../node_modules/typescript/lib/lib.es2019.array.d.ts","../node_modules/typescript/lib/lib.es2019.object.d.ts","../node_modules/typescript/lib/lib.es2019.string.d.ts","../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../node_modules/typescript/lib/lib.es2019.intl.d.ts","../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../node_modules/typescript/lib/lib.es2020.date.d.ts","../node_modules/typescript/lib/lib.es2020.promise.d.ts","../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2020.string.d.ts","../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2020.intl.d.ts","../node_modules/typescript/lib/lib.es2020.number.d.ts","../node_modules/typescript/lib/lib.es2021.promise.d.ts","../node_modules/typescript/lib/lib.es2021.string.d.ts","../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../node_modules/typescript/lib/lib.es2021.intl.d.ts","../node_modules/typescript/lib/lib.es2022.array.d.ts","../node_modules/typescript/lib/lib.es2022.error.d.ts","../node_modules/typescript/lib/lib.es2022.intl.d.ts","../node_modules/typescript/lib/lib.es2022.object.d.ts","../node_modules/typescript/lib/lib.es2022.string.d.ts","../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../node_modules/typescript/lib/lib.decorators.d.ts","../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../node_modules/typescript/lib/lib.es2022.full.d.ts","../node_modules/no-case/dist/index.d.ts","../node_modules/pascal-case/dist/index.d.ts","../node_modules/camel-case/dist/index.d.ts","../node_modules/capital-case/dist/index.d.ts","../node_modules/constant-case/dist/index.d.ts","../node_modules/dot-case/dist/index.d.ts","../node_modules/header-case/dist/index.d.ts","../node_modules/param-case/dist/index.d.ts","../node_modules/path-case/dist/index.d.ts","../node_modules/sentence-case/dist/index.d.ts","../node_modules/snake-case/dist/index.d.ts","../node_modules/change-case/dist/index.d.ts","../node_modules/json5/lib/parse.d.ts","../node_modules/json5/lib/stringify.d.ts","../node_modules/json5/lib/index.d.ts","../node_modules/word-wrap/index.d.ts","../node_modules/@types/node/compatibility/disposable.d.ts","../node_modules/@types/node/compatibility/indexable.d.ts","../node_modules/@types/node/compatibility/iterators.d.ts","../node_modules/@types/node/compatibility/index.d.ts","../node_modules/@types/node/globals.typedarray.d.ts","../node_modules/@types/node/buffer.buffer.d.ts","../node_modules/buffer/index.d.ts","../node_modules/undici-types/header.d.ts","../node_modules/undici-types/readable.d.ts","../node_modules/undici-types/file.d.ts","../node_modules/undici-types/fetch.d.ts","../node_modules/undici-types/formdata.d.ts","../node_modules/undici-types/connector.d.ts","../node_modules/undici-types/client.d.ts","../node_modules/undici-types/errors.d.ts","../node_modules/undici-types/dispatcher.d.ts","../node_modules/undici-types/global-dispatcher.d.ts","../node_modules/undici-types/global-origin.d.ts","../node_modules/undici-types/pool-stats.d.ts","../node_modules/undici-types/pool.d.ts","../node_modules/undici-types/handlers.d.ts","../node_modules/undici-types/balanced-pool.d.ts","../node_modules/undici-types/agent.d.ts","../node_modules/undici-types/mock-interceptor.d.ts","../node_modules/undici-types/mock-agent.d.ts","../node_modules/undici-types/mock-client.d.ts","../node_modules/undici-types/mock-pool.d.ts","../node_modules/undici-types/mock-errors.d.ts","../node_modules/undici-types/proxy-agent.d.ts","../node_modules/undici-types/env-http-proxy-agent.d.ts","../node_modules/undici-types/retry-handler.d.ts","../node_modules/undici-types/retry-agent.d.ts","../node_modules/undici-types/api.d.ts","../node_modules/undici-types/interceptors.d.ts","../node_modules/undici-types/util.d.ts","../node_modules/undici-types/cookies.d.ts","../node_modules/undici-types/patch.d.ts","../node_modules/undici-types/websocket.d.ts","../node_modules/undici-types/eventsource.d.ts","../node_modules/undici-types/filereader.d.ts","../node_modules/undici-types/diagnostics-channel.d.ts","../node_modules/undici-types/content-type.d.ts","../node_modules/undici-types/cache.d.ts","../node_modules/undici-types/index.d.ts","../node_modules/@types/node/globals.d.ts","../node_modules/@types/node/assert.d.ts","../node_modules/@types/node/assert/strict.d.ts","../node_modules/@types/node/async_hooks.d.ts","../node_modules/@types/node/buffer.d.ts","../node_modules/@types/node/child_process.d.ts","../node_modules/@types/node/cluster.d.ts","../node_modules/@types/node/console.d.ts","../node_modules/@types/node/constants.d.ts","../node_modules/@types/node/crypto.d.ts","../node_modules/@types/node/dgram.d.ts","../node_modules/@types/node/diagnostics_channel.d.ts","../node_modules/@types/node/dns.d.ts","../node_modules/@types/node/dns/promises.d.ts","../node_modules/@types/node/domain.d.ts","../node_modules/@types/node/dom-events.d.ts","../node_modules/@types/node/events.d.ts","../node_modules/@types/node/fs.d.ts","../node_modules/@types/node/fs/promises.d.ts","../node_modules/@types/node/http.d.ts","../node_modules/@types/node/http2.d.ts","../node_modules/@types/node/https.d.ts","../node_modules/@types/node/inspector.d.ts","../node_modules/@types/node/module.d.ts","../node_modules/@types/node/net.d.ts","../node_modules/@types/node/os.d.ts","../node_modules/@types/node/path.d.ts","../node_modules/@types/node/perf_hooks.d.ts","../node_modules/@types/node/process.d.ts","../node_modules/@types/node/punycode.d.ts","../node_modules/@types/node/querystring.d.ts","../node_modules/@types/node/readline.d.ts","../node_modules/@types/node/readline/promises.d.ts","../node_modules/@types/node/repl.d.ts","../node_modules/@types/node/sea.d.ts","../node_modules/@types/node/sqlite.d.ts","../node_modules/@types/node/stream.d.ts","../node_modules/@types/node/stream/promises.d.ts","../node_modules/@types/node/stream/consumers.d.ts","../node_modules/@types/node/stream/web.d.ts","../node_modules/@types/node/string_decoder.d.ts","../node_modules/@types/node/test.d.ts","../node_modules/@types/node/timers.d.ts","../node_modules/@types/node/timers/promises.d.ts","../node_modules/@types/node/tls.d.ts","../node_modules/@types/node/trace_events.d.ts","../node_modules/@types/node/tty.d.ts","../node_modules/@types/node/url.d.ts","../node_modules/@types/node/util.d.ts","../node_modules/@types/node/v8.d.ts","../node_modules/@types/node/vm.d.ts","../node_modules/@types/node/wasi.d.ts","../node_modules/@types/node/worker_threads.d.ts","../node_modules/@types/node/zlib.d.ts","../node_modules/@types/node/index.d.ts","../node_modules/@types/convict/index.d.ts","../node_modules/@types/convict-format-with-validator/index.d.ts","../src/utils.ts","../src/config.ts","../src/throttle.ts","../src/app.ts","../src/generate-config-docs.ts","../src/index.ts","../node_modules/@types/estree/index.d.ts","../node_modules/@types/json-schema/index.d.ts","../node_modules/@types/eslint/use-at-your-own-risk.d.ts","../node_modules/@types/eslint/index.d.ts","../node_modules/@types/eslint-scope/index.d.ts","../node_modules/@types/unist/index.d.ts","../node_modules/@types/hast/index.d.ts","../node_modules/@types/json5/index.d.ts","../node_modules/@types/normalize-package-data/index.d.ts","../node_modules/@types/semver/classes/semver.d.ts","../node_modules/@types/semver/functions/parse.d.ts","../node_modules/@types/semver/functions/valid.d.ts","../node_modules/@types/semver/functions/clean.d.ts","../node_modules/@types/semver/functions/inc.d.ts","../node_modules/@types/semver/functions/diff.d.ts","../node_modules/@types/semver/functions/major.d.ts","../node_modules/@types/semver/functions/minor.d.ts","../node_modules/@types/semver/functions/patch.d.ts","../node_modules/@types/semver/functions/prerelease.d.ts","../node_modules/@types/semver/functions/compare.d.ts","../node_modules/@types/semver/functions/rcompare.d.ts","../node_modules/@types/semver/functions/compare-loose.d.ts","../node_modules/@types/semver/functions/compare-build.d.ts","../node_modules/@types/semver/functions/sort.d.ts","../node_modules/@types/semver/functions/rsort.d.ts","../node_modules/@types/semver/functions/gt.d.ts","../node_modules/@types/semver/functions/lt.d.ts","../node_modules/@types/semver/functions/eq.d.ts","../node_modules/@types/semver/functions/neq.d.ts","../node_modules/@types/semver/functions/gte.d.ts","../node_modules/@types/semver/functions/lte.d.ts","../node_modules/@types/semver/functions/cmp.d.ts","../node_modules/@types/semver/functions/coerce.d.ts","../node_modules/@types/semver/classes/comparator.d.ts","../node_modules/@types/semver/classes/range.d.ts","../node_modules/@types/semver/functions/satisfies.d.ts","../node_modules/@types/semver/ranges/max-satisfying.d.ts","../node_modules/@types/semver/ranges/min-satisfying.d.ts","../node_modules/@types/semver/ranges/to-comparators.d.ts","../node_modules/@types/semver/ranges/min-version.d.ts","../node_modules/@types/semver/ranges/valid.d.ts","../node_modules/@types/semver/ranges/outside.d.ts","../node_modules/@types/semver/ranges/gtr.d.ts","../node_modules/@types/semver/ranges/ltr.d.ts","../node_modules/@types/semver/ranges/intersects.d.ts","../node_modules/@types/semver/ranges/simplify.d.ts","../node_modules/@types/semver/ranges/subset.d.ts","../node_modules/@types/semver/internals/identifiers.d.ts","../node_modules/@types/semver/index.d.ts"],"fileIdsList":[[85,128,179],[85,128,178],[85,128,187,190],[85,128,187,188,189],[85,128,190],[85,128],[85,128,192],[85,125,128],[85,127,128],[128],[85,128,133,163],[85,128,129,134,140,141,148,160,171],[85,128,129,130,140,148],[80,81,82,85,128],[85,128,131,172],[85,128,132,133,141,149],[85,128,133,160,168],[85,128,134,136,140,148],[85,127,128,135],[85,128,136,137],[85,128,140],[85,128,138,140],[85,127,128,140],[85,128,140,141,142,160,171],[85,128,140,141,142,155,160,163],[85,123,128,176],[85,123,128,136,140,143,148,160,171],[85,128,140,141,143,144,148,160,168,171],[85,128,143,145,160,168,171],[83,84,85,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177],[85,128,140,146],[85,128,147,171],[85,128,136,140,148,160],[85,128,149],[85,128,150],[85,127,128,151],[85,125,126,127,128,129,130,131,132,133,134,135,136,137,138,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177],[85,128,153],[85,128,154],[85,128,140,155,156],[85,128,155,157,172,174],[85,128,140,160,161,162,163],[85,128,160,162],[85,128,160,161],[85,128,163],[85,128,164],[85,125,128,160],[85,128,140,166,167],[85,128,166,167],[85,128,133,148,160,168],[85,128,169],[85,128,148,170],[85,128,143,154,171],[85,128,133,172],[85,128,160,173],[85,128,147,174],[85,128,175],[85,128,133,140,142,151,160,171,174,176],[85,128,160,177],[85,128,196,235],[85,128,196,220,235],[85,128,235],[85,128,196],[85,128,196,221,235],[85,128,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234],[85,128,221,235],[65,85,128],[64,85,128],[64,65,66,67,68,69,70,71,72,73,74,85,128],[67,85,128],[76,77,85,128],[69,85,128],[85,95,99,128,171],[85,95,128,160,171],[85,90,128],[85,92,95,128,168,171],[85,128,148,168],[85,90,128,178],[85,92,95,128,148,171],[85,87,88,91,94,128,140,160,171],[85,95,102,128],[85,87,93,128],[85,95,116,117,128],[85,91,95,128,163,171,178],[85,116,128,178],[85,89,90,128,178],[85,95,128],[85,89,90,91,92,93,94,95,96,97,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,117,118,119,120,121,122,128],[85,95,110,128],[85,95,102,103,128],[85,93,95,103,104,128],[85,94,128],[85,87,90,95,128],[85,95,99,103,104,128],[85,99,128],[85,93,95,98,128,171],[85,87,92,95,102,128],[85,128,160],[85,90,95,116,128,176,178],[75,78,79,85,128,129,141,181,182,183],[85,128,141,179,180,181],[85,128,142,182],[85,128,181,182,183,184],[78,85,128,129,141,149,181],[85,128,129,141,150]],"fileInfos":[{"version":"69684132aeb9b5642cbcd9e22dff7818ff0ee1aa831728af0ecf97d3364d5546","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"092c2bfe125ce69dbb1223c85d68d4d2397d7d8411867b5cc03cec902c233763","affectsGlobalScope":true,"impliedFormat":1},{"version":"07f073f19d67f74d732b1adea08e1dc66b1b58d77cb5b43931dee3d798a2fd53","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7a3c8b952931daebdfc7a2897c53c0a1c73624593fa070e46bd537e64dcd20a","affectsGlobalScope":true,"impliedFormat":1},{"version":"80e18897e5884b6723488d4f5652167e7bb5024f946743134ecc4aa4ee731f89","affectsGlobalScope":true,"impliedFormat":1},{"version":"cd034f499c6cdca722b60c04b5b1b78e058487a7085a8e0d6fb50809947ee573","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"b5ce7a470bc3628408429040c4e3a53a27755022a32fd05e2cb694e7015386c7","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"3cbad9a1ba4453443026ed38e4b8be018abb26565fa7c944376463ad9df07c41","impliedFormat":1},{"version":"b4e123af1af6049685c93073a15868b50aebdad666d422edc72fa2b585fa8a37","impliedFormat":1},{"version":"f86c04a744ebcede96bac376f9a2c90f2bd3c422740d91dda4ca6233199d4977","impliedFormat":1},{"version":"6ae1bddee5c790439bd992abd063b9b46e0cadd676c2a8562268d1869213ff60","impliedFormat":1},{"version":"606244fc97a6a74b877f2e924ba7e55b233bc6acb57d7bf40ba84a5be2d9adb0","impliedFormat":1},{"version":"4a1cabac71036b8a14f5db1b753b579f0c901c7d7b9227e6872dadf6efb104e8","impliedFormat":1},{"version":"062959a1d825b96639d87be35fe497cbd3f89544bf06fdad577bbfb85fcf604c","impliedFormat":1},{"version":"4c3672dc8f4e4fdd3d18525b22b31f1b5481f5a415db96550d3ac5163a6c3dd3","impliedFormat":1},{"version":"f9a69ca445010b91fe08f08c06e0f86d79c0d776905f9bdb828477cb2a1eb7fc","impliedFormat":1},{"version":"ad7fd0e7ee457d4884b3aaecbcbd2a80b6803407c4ce2540c296170d4c7918ef","impliedFormat":1},{"version":"a50ef21605f41c6acad6c3ef0307e5311b94963c846ca093c764b80cdb5318d6","impliedFormat":1},{"version":"74b4035dd26d09a417c44ca23ab5ee69b173f8c2f6b2e47350ab0795cf2d4a17","impliedFormat":1},{"version":"918f86ee2b19cc38cb8b1a4cf8f223eb228aaa39df3604c42f700fac2f0b3ea1","impliedFormat":1},{"version":"88a3a6f8c2a1640d8d5fd30d8d86462f8babd86a1e52fab0e8b7f7c141fb348e","impliedFormat":1},{"version":"345f76c854da724803c96f727a3f9c75e26cf95c6e7b8c1064dbc4e7727b74e6","impliedFormat":1},{"version":"ab7b7a15a5d73eb0cfc2b973e580f357f07492bff6608669d7e899e2d49ac9a3","impliedFormat":1},{"version":"14e27c8804ce2fe36fe1cfdbea2c0625cb97f4c20394fa9973567fb09cc03406","impliedFormat":1},{"version":"70521b6ab0dcba37539e5303104f29b721bfb2940b2776da4cc818c07e1fefc1","affectsGlobalScope":true,"impliedFormat":1},{"version":"030e350db2525514580ed054f712ffb22d273e6bc7eddc1bb7eda1e0ba5d395e","affectsGlobalScope":true,"impliedFormat":1},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"a79e62f1e20467e11a904399b8b18b18c0c6eea6b50c1168bf215356d5bebfaf","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fd06258805d26c72f5997e07a23155d322d5f05387adb3744a791fe6a0b042d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"24bd580b5743dc56402c440dc7f9a4f5d592ad7a419f25414d37a7bfe11e342b","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"6bdc71028db658243775263e93a7db2fd2abfce3ca569c3cca5aee6ed5eb186d","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"d2bc987ae352271d0d615a420dcf98cc886aa16b87fb2b569358c1fe0ca0773d","affectsGlobalScope":true,"impliedFormat":1},{"version":"f52e8dacc97d71dcc96af29e49584353f9c54cb916d132e3e768d8b8129c928d","impliedFormat":1},{"version":"7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","impliedFormat":1},{"version":"76103716ba397bbb61f9fa9c9090dca59f39f9047cb1352b2179c5d8e7f4e8d0","impliedFormat":1},{"version":"53eac70430b30089a3a1959d8306b0f9cfaf0de75224b68ef25243e0b5ad1ca3","affectsGlobalScope":true,"impliedFormat":1},{"version":"4314c7a11517e221f7296b46547dbc4df047115b182f544d072bdccffa57fc72","impliedFormat":1},{"version":"115971d64632ea4742b5b115fb64ed04bcaae2c3c342f13d9ba7e3f9ee39c4e7","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"a40826e8476694e90da94aa008283a7de50d1dafd37beada623863f1901cb7fb","impliedFormat":1},{"version":"86956cc2eb9dd371d6fab493d326a574afedebf76eef3fa7833b8e0d9b52d6f1","affectsGlobalScope":true,"impliedFormat":1},{"version":"91c1a729db5b28b2fc32bafa7a53611d417bc3f03f649278d4fd948aa4dec898","impliedFormat":1},{"version":"e6f5a38687bebe43a4cef426b69d34373ef68be9a6b1538ec0a371e69f309354","impliedFormat":1},{"version":"a6bf63d17324010ca1fbf0389cab83f93389bb0b9a01dc8a346d092f65b3605f","impliedFormat":1},{"version":"e009777bef4b023a999b2e5b9a136ff2cde37dc3f77c744a02840f05b18be8ff","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"ee1ee365d88c4c6c0c0a5a5701d66ebc27ccd0bcfcfaa482c6e2e7fe7b98edf7","affectsGlobalScope":true,"impliedFormat":1},{"version":"88bc59b32d0d5b4e5d9632ac38edea23454057e643684c3c0b94511296f2998c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1ff5a53a58e756d2661b73ba60ffe274231a4432d21f7a2d0d9e4f6aa99f4283","impliedFormat":1},{"version":"eaf9ee1d90a35d56264f0bf39842282c58b9219e112ac7d0c1bce98c6c5da672","impliedFormat":1},{"version":"c15c4427ae7fd1dcd7f312a8a447ac93581b0d4664ddf151ecd07de4bf2bb9d7","impliedFormat":1},{"version":"5135bdd72cc05a8192bd2e92f0914d7fc43ee077d1293dc622a049b7035a0afb","impliedFormat":1},{"version":"4f80de3a11c0d2f1329a72e92c7416b2f7eab14f67e92cac63bb4e8d01c6edc8","impliedFormat":1},{"version":"6d386bc0d7f3afa1d401afc3e00ed6b09205a354a9795196caed937494a713e6","impliedFormat":1},{"version":"c72ccc191348ac1933226cab7a814cfda8b29a827d1df5dbebfe516a6fd734a8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8bea55446a296d289fbc762f61954a0e3e38ffbcacc06e47e0cba491030e3235","impliedFormat":1},{"version":"b1b6ee0d012aeebe11d776a155d8979730440082797695fc8e2a5c326285678f","impliedFormat":1},{"version":"45875bcae57270aeb3ebc73a5e3fb4c7b9d91d6b045f107c1d8513c28ece71c0","impliedFormat":1},{"version":"3eb62baae4df08c9173e6903d3ca45942ccec8c3659b0565684a75f3292cffbb","affectsGlobalScope":true,"impliedFormat":1},{"version":"42aaa94addeed66a04b61e433c14e829c43d1efd653cf2fda480c5fb3d722ed8","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"c6b4e0a02545304935ecbf7de7a8e056a31bb50939b5b321c9d50a405b5a0bba","impliedFormat":1},{"version":"fab29e6d649aa074a6b91e3bdf2bff484934a46067f6ee97a30fcd9762ae2213","impliedFormat":1},{"version":"8145e07aad6da5f23f2fcd8c8e4c5c13fb26ee986a79d03b0829b8fce152d8b2","impliedFormat":1},{"version":"e1120271ebbc9952fdc7b2dd3e145560e52e06956345e6fdf91d70ca4886464f","impliedFormat":1},{"version":"15c5e91b5f08be34a78e3d976179bf5b7a9cc28dc0ef1ffebffeb3c7812a2dca","impliedFormat":1},{"version":"d63ff33a2fa221b36a4da0dd5a3dad3156f3dd0fe1baf43a186e607d4ba5af99","impliedFormat":1},{"version":"553870e516f8c772b89f3820576152ebc70181d7994d96917bb943e37da7f8a7","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"93452d394fdd1dc551ec62f5042366f011a00d342d36d50793b3529bfc9bd633","impliedFormat":1},{"version":"745c4240220559bd340c8aeb6e3c5270a709d3565e934dc22a69c304703956bc","affectsGlobalScope":true,"impliedFormat":1},{"version":"2754d8221d77c7b382096651925eb476f1066b3348da4b73fe71ced7801edada","impliedFormat":1},{"version":"9212c6e9d80cb45441a3614e95afd7235a55a18584c2ed32d6c1aca5a0c53d93","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef91efa0baea5d0e0f0f27b574a8bc100ce62a6d7e70220a0d58af6acab5e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"282fd2a1268a25345b830497b4b7bf5037a5e04f6a9c44c840cb605e19fea841","impliedFormat":1},{"version":"5360a27d3ebca11b224d7d3e38e3e2c63f8290cb1fcf6c3610401898f8e68bc3","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"7d6ff413e198d25639f9f01f16673e7df4e4bd2875a42455afd4ecc02ef156da","affectsGlobalScope":true,"impliedFormat":1},{"version":"1f58ebc40c84046ba4c25cf7e86e1ae92c3f064fb641af6c46a5acebf0b8b20b","affectsGlobalScope":true,"impliedFormat":1},{"version":"f689c4237b70ae6be5f0e4180e8833f34ace40529d1acc0676ab8fb8f70457d7","impliedFormat":1},{"version":"ae25afbbf1ed5df63a177d67b9048bf7481067f1b8dc9c39212e59db94fc9fc6","impliedFormat":1},{"version":"ac5ed35e649cdd8143131964336ab9076937fa91802ec760b3ea63b59175c10a","impliedFormat":1},{"version":"52a8e7e8a1454b6d1b5ad428efae3870ffc56f2c02d923467f2940c454aa9aec","affectsGlobalScope":true,"impliedFormat":1},{"version":"78dc0513cc4f1642906b74dda42146bcbd9df7401717d6e89ea6d72d12ecb539","impliedFormat":1},{"version":"ad90122e1cb599b3bc06a11710eb5489101be678f2920f2322b0ac3e195af78d","impliedFormat":1},{"version":"03d0e8cd16f16b504879544f6323f0e0a9ca9a6e70277c15bf3db9eeedb435cc","impliedFormat":1},{"version":"92d4cd0e80a54da81b6dca627c6b7f3357f91227ee5a2f807fe170c5e1486c85","impliedFormat":1},{"version":"a57607fb753ac4ba86a76812b09f8f812fd954c4f1570acc32dcc11ddb5a94a8","signature":"9135f578c1159fbc1a37339a1187c3d44459ec16090e2b84ed6c761900cf8afe","impliedFormat":1},{"version":"8648346b485f088f1171680a4cea70dc100f3cf7e6311a27cf520ffc9fab8ea1","signature":"bd28c9f28c2b9008b46ac5a90e3f397f8285f23b4f7c05171971d30649ffaaa0","impliedFormat":1},{"version":"c030d0f95d5f6aa35966d91d8b2f9a6a8f89267e84fd321bbb5a53ca60473a5c","signature":"50c7ed34600303162f6b1e1cefa0cfe8c9e3cba8ff7e86cbc45a8b79a0f075f0","impliedFormat":1},{"version":"c7b5914ff504aa3590ef5a98f6a41ead9ccd896aae5ef129cfca16945f9b1af2","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"f7368a5cb0c090073c3ed4426d884aaab84c861bfd5266cc01e52fa4911b8609","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"17c20b6076805a442682f4cb8fa35a6bbcaa6c0309fc3fd7ce2b82597a8882b3","signature":"99e19059c4bd18df586ee56283eb59b0aba861204fb89cde18e064d64f6dc0ec","impliedFormat":1},{"version":"785b9d575b49124ce01b46f5b9402157c7611e6532effa562ac6aebec0074dfc","impliedFormat":1},{"version":"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","impliedFormat":1},{"version":"a4a39b5714adfcadd3bbea6698ca2e942606d833bde62ad5fb6ec55f5e438ff8","impliedFormat":1},{"version":"bbc1d029093135d7d9bfa4b38cbf8761db505026cc458b5e9c8b74f4000e5e75","impliedFormat":1},{"version":"1f68ab0e055994eb337b67aa87d2a15e0200951e9664959b3866ee6f6b11a0fe","impliedFormat":1},{"version":"89121c1bf2990f5219bfd802a3e7fc557de447c62058d6af68d6b6348d64499a","impliedFormat":1},{"version":"79b4369233a12c6fa4a07301ecb7085802c98f3a77cf9ab97eee27e1656f82e6","impliedFormat":1},{"version":"96d14f21b7652903852eef49379d04dbda28c16ed36468f8c9fa08f7c14c9538","impliedFormat":1},{"version":"22293bd6fa12747929f8dfca3ec1684a3fe08638aa18023dd286ab337e88a592","impliedFormat":1},{"version":"cf3d384d082b933d987c4e2fe7bfb8710adfd9dc8155190056ed6695a25a559e","impliedFormat":1},{"version":"9871b7ee672bc16c78833bdab3052615834b08375cb144e4d2cba74473f4a589","impliedFormat":1},{"version":"c863198dae89420f3c552b5a03da6ed6d0acfa3807a64772b895db624b0de707","impliedFormat":1},{"version":"8b03a5e327d7db67112ebbc93b4f744133eda2c1743dbb0a990c61a8007823ef","impliedFormat":1},{"version":"86c73f2ee1752bac8eeeece234fd05dfcf0637a4fbd8032e4f5f43102faa8eec","impliedFormat":1},{"version":"42fad1f540271e35ca37cecda12c4ce2eef27f0f5cf0f8dd761d723c744d3159","impliedFormat":1},{"version":"ff3743a5de32bee10906aff63d1de726f6a7fd6ee2da4b8229054dfa69de2c34","impliedFormat":1},{"version":"83acd370f7f84f203e71ebba33ba61b7f1291ca027d7f9a662c6307d74e4ac22","impliedFormat":1},{"version":"1445cec898f90bdd18b2949b9590b3c012f5b7e1804e6e329fb0fe053946d5ec","impliedFormat":1},{"version":"0e5318ec2275d8da858b541920d9306650ae6ac8012f0e872fe66eb50321a669","impliedFormat":1},{"version":"cf530297c3fb3a92ec9591dd4fa229d58b5981e45fe6702a0bd2bea53a5e59be","impliedFormat":1},{"version":"c1f6f7d08d42148ddfe164d36d7aba91f467dbcb3caa715966ff95f55048b3a4","impliedFormat":1},{"version":"f4e9bf9103191ef3b3612d3ec0044ca4044ca5be27711fe648ada06fad4bcc85","impliedFormat":1},{"version":"0c1ee27b8f6a00097c2d6d91a21ee4d096ab52c1e28350f6362542b55380059a","impliedFormat":1},{"version":"7677d5b0db9e020d3017720f853ba18f415219fb3a9597343b1b1012cfd699f7","impliedFormat":1},{"version":"bc1c6bc119c1784b1a2be6d9c47addec0d83ef0d52c8fbe1f14a51b4dfffc675","impliedFormat":1},{"version":"52cf2ce99c2a23de70225e252e9822a22b4e0adb82643ab0b710858810e00bf1","impliedFormat":1},{"version":"770625067bb27a20b9826255a8d47b6b5b0a2d3dfcbd21f89904c731f671ba77","impliedFormat":1},{"version":"d1ed6765f4d7906a05968fb5cd6d1db8afa14dbe512a4884e8ea5c0f5e142c80","impliedFormat":1},{"version":"799c0f1b07c092626cf1efd71d459997635911bb5f7fc1196efe449bba87e965","impliedFormat":1},{"version":"2a184e4462b9914a30b1b5c41cf80c6d3428f17b20d3afb711fff3f0644001fd","impliedFormat":1},{"version":"9eabde32a3aa5d80de34af2c2206cdc3ee094c6504a8d0c2d6d20c7c179503cc","impliedFormat":1},{"version":"397c8051b6cfcb48aa22656f0faca2553c5f56187262135162ee79d2b2f6c966","impliedFormat":1},{"version":"a8ead142e0c87dcd5dc130eba1f8eeed506b08952d905c47621dc2f583b1bff9","impliedFormat":1},{"version":"a02f10ea5f73130efca046429254a4e3c06b5475baecc8f7b99a0014731be8b3","impliedFormat":1},{"version":"c2576a4083232b0e2d9bd06875dd43d371dee2e090325a9eac0133fd5650c1cb","impliedFormat":1},{"version":"4c9a0564bb317349de6a24eb4efea8bb79898fa72ad63a1809165f5bd42970dd","impliedFormat":1},{"version":"f40ac11d8859092d20f953aae14ba967282c3bb056431a37fced1866ec7a2681","impliedFormat":1},{"version":"cc11e9e79d4746cc59e0e17473a59d6f104692fd0eeea1bdb2e206eabed83b03","impliedFormat":1},{"version":"b444a410d34fb5e98aa5ee2b381362044f4884652e8bc8a11c8fe14bbd85518e","impliedFormat":1},{"version":"c35808c1f5e16d2c571aa65067e3cb95afeff843b259ecfa2fc107a9519b5392","impliedFormat":1},{"version":"14d5dc055143e941c8743c6a21fa459f961cbc3deedf1bfe47b11587ca4b3ef5","impliedFormat":1},{"version":"a3ad4e1fc542751005267d50a6298e6765928c0c3a8dce1572f2ba6ca518661c","impliedFormat":1},{"version":"f237e7c97a3a89f4591afd49ecb3bd8d14f51a1c4adc8fcae3430febedff5eb6","impliedFormat":1},{"version":"3ffdfbec93b7aed71082af62b8c3e0cc71261cc68d796665faa1e91604fbae8f","impliedFormat":1},{"version":"662201f943ed45b1ad600d03a90dffe20841e725203ced8b708c91fcd7f9379a","impliedFormat":1},{"version":"c9ef74c64ed051ea5b958621e7fb853fe3b56e8787c1587aefc6ea988b3c7e79","impliedFormat":1},{"version":"2462ccfac5f3375794b861abaa81da380f1bbd9401de59ffa43119a0b644253d","impliedFormat":1},{"version":"34baf65cfee92f110d6653322e2120c2d368ee64b3c7981dff08ed105c4f19b0","impliedFormat":1},{"version":"7d8ddf0f021c53099e34ee831a06c394d50371816caa98684812f089b4c6b3d4","impliedFormat":1}],"root":[[181,186]],"options":{"allowJs":false,"composite":true,"declaration":true,"esModuleInterop":true,"experimentalDecorators":true,"inlineSources":true,"module":100,"outDir":"./","rootDir":"..","skipLibCheck":true,"sourceMap":true,"strict":true,"target":9},"referencedMap":[[180,1],[179,2],[191,3],[190,4],[189,5],[187,6],[193,7],[188,6],[194,6],[125,8],[126,8],[127,9],[85,10],[128,11],[129,12],[130,13],[80,6],[83,14],[81,6],[82,6],[131,15],[132,16],[133,17],[134,18],[135,19],[136,20],[137,20],[139,21],[138,22],[140,23],[141,24],[142,25],[124,26],[84,6],[143,27],[144,28],[145,29],[178,30],[146,31],[147,32],[148,33],[149,34],[150,35],[151,36],[152,37],[153,38],[154,39],[155,40],[156,40],[157,41],[158,6],[159,6],[160,42],[162,43],[161,44],[163,45],[164,46],[165,47],[166,48],[167,49],[168,50],[169,51],[170,52],[171,53],[172,54],[173,55],[174,56],[175,57],[176,58],[177,59],[195,6],[220,60],[221,61],[196,62],[199,62],[218,60],[219,60],[209,60],[208,63],[206,60],[201,60],[214,60],[212,60],[216,60],[200,60],[213,60],[217,60],[202,60],[203,60],[215,60],[197,60],[204,60],[205,60],[207,60],[211,60],[222,64],[210,60],[198,60],[235,65],[234,6],[229,64],[231,66],[230,64],[223,64],[224,64],[226,64],[228,64],[232,66],[233,66],[225,66],[227,66],[192,6],[86,6],[66,67],[67,68],[75,69],[68,68],[69,68],[70,70],[78,71],[76,6],[77,6],[64,6],[71,72],[65,68],[72,72],[73,68],[74,72],[61,6],[62,6],[12,6],[10,6],[11,6],[16,6],[15,6],[2,6],[17,6],[18,6],[19,6],[20,6],[21,6],[22,6],[23,6],[24,6],[3,6],[25,6],[26,6],[4,6],[27,6],[31,6],[28,6],[29,6],[30,6],[32,6],[33,6],[34,6],[5,6],[35,6],[36,6],[37,6],[38,6],[6,6],[42,6],[39,6],[40,6],[41,6],[43,6],[7,6],[44,6],[49,6],[50,6],[45,6],[46,6],[47,6],[48,6],[8,6],[54,6],[51,6],[52,6],[53,6],[55,6],[9,6],[56,6],[63,6],[57,6],[58,6],[60,6],[59,6],[1,6],[14,6],[13,6],[102,73],[112,74],[101,73],[122,75],[93,76],[92,77],[121,2],[115,78],[120,79],[95,80],[109,81],[94,82],[118,83],[90,84],[89,2],[119,85],[91,86],[96,87],[97,6],[100,87],[87,6],[123,88],[113,89],[104,90],[105,91],[107,92],[103,93],[106,94],[116,2],[98,95],[99,96],[108,97],[88,98],[111,89],[110,87],[114,6],[117,99],[79,6],[184,100],[182,101],[185,102],[186,103],[183,104],[181,105]],"latestChangedDtsFile":"./src/index.d.ts","version":"5.8.3"}
|
|
1
|
+
{"fileNames":["../node_modules/typescript/lib/lib.es5.d.ts","../node_modules/typescript/lib/lib.es2015.d.ts","../node_modules/typescript/lib/lib.es2016.d.ts","../node_modules/typescript/lib/lib.es2017.d.ts","../node_modules/typescript/lib/lib.es2018.d.ts","../node_modules/typescript/lib/lib.es2019.d.ts","../node_modules/typescript/lib/lib.es2020.d.ts","../node_modules/typescript/lib/lib.es2021.d.ts","../node_modules/typescript/lib/lib.es2022.d.ts","../node_modules/typescript/lib/lib.dom.d.ts","../node_modules/typescript/lib/lib.dom.iterable.d.ts","../node_modules/typescript/lib/lib.dom.asynciterable.d.ts","../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../node_modules/typescript/lib/lib.scripthost.d.ts","../node_modules/typescript/lib/lib.es2015.core.d.ts","../node_modules/typescript/lib/lib.es2015.collection.d.ts","../node_modules/typescript/lib/lib.es2015.generator.d.ts","../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../node_modules/typescript/lib/lib.es2015.promise.d.ts","../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../node_modules/typescript/lib/lib.es2016.intl.d.ts","../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../node_modules/typescript/lib/lib.es2017.date.d.ts","../node_modules/typescript/lib/lib.es2017.object.d.ts","../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2017.string.d.ts","../node_modules/typescript/lib/lib.es2017.intl.d.ts","../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../node_modules/typescript/lib/lib.es2018.intl.d.ts","../node_modules/typescript/lib/lib.es2018.promise.d.ts","../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../node_modules/typescript/lib/lib.es2019.array.d.ts","../node_modules/typescript/lib/lib.es2019.object.d.ts","../node_modules/typescript/lib/lib.es2019.string.d.ts","../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../node_modules/typescript/lib/lib.es2019.intl.d.ts","../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../node_modules/typescript/lib/lib.es2020.date.d.ts","../node_modules/typescript/lib/lib.es2020.promise.d.ts","../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2020.string.d.ts","../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2020.intl.d.ts","../node_modules/typescript/lib/lib.es2020.number.d.ts","../node_modules/typescript/lib/lib.es2021.promise.d.ts","../node_modules/typescript/lib/lib.es2021.string.d.ts","../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../node_modules/typescript/lib/lib.es2021.intl.d.ts","../node_modules/typescript/lib/lib.es2022.array.d.ts","../node_modules/typescript/lib/lib.es2022.error.d.ts","../node_modules/typescript/lib/lib.es2022.intl.d.ts","../node_modules/typescript/lib/lib.es2022.object.d.ts","../node_modules/typescript/lib/lib.es2022.string.d.ts","../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../node_modules/typescript/lib/lib.decorators.d.ts","../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../node_modules/typescript/lib/lib.es2022.full.d.ts","../node_modules/no-case/dist/index.d.ts","../node_modules/pascal-case/dist/index.d.ts","../node_modules/camel-case/dist/index.d.ts","../node_modules/capital-case/dist/index.d.ts","../node_modules/constant-case/dist/index.d.ts","../node_modules/dot-case/dist/index.d.ts","../node_modules/header-case/dist/index.d.ts","../node_modules/param-case/dist/index.d.ts","../node_modules/path-case/dist/index.d.ts","../node_modules/sentence-case/dist/index.d.ts","../node_modules/snake-case/dist/index.d.ts","../node_modules/change-case/dist/index.d.ts","../node_modules/json5/lib/parse.d.ts","../node_modules/json5/lib/stringify.d.ts","../node_modules/json5/lib/index.d.ts","../node_modules/word-wrap/index.d.ts","../node_modules/@types/node/compatibility/disposable.d.ts","../node_modules/@types/node/compatibility/indexable.d.ts","../node_modules/@types/node/compatibility/iterators.d.ts","../node_modules/@types/node/compatibility/index.d.ts","../node_modules/@types/node/globals.typedarray.d.ts","../node_modules/@types/node/buffer.buffer.d.ts","../node_modules/buffer/index.d.ts","../node_modules/undici-types/header.d.ts","../node_modules/undici-types/readable.d.ts","../node_modules/undici-types/file.d.ts","../node_modules/undici-types/fetch.d.ts","../node_modules/undici-types/formdata.d.ts","../node_modules/undici-types/connector.d.ts","../node_modules/undici-types/client.d.ts","../node_modules/undici-types/errors.d.ts","../node_modules/undici-types/dispatcher.d.ts","../node_modules/undici-types/global-dispatcher.d.ts","../node_modules/undici-types/global-origin.d.ts","../node_modules/undici-types/pool-stats.d.ts","../node_modules/undici-types/pool.d.ts","../node_modules/undici-types/handlers.d.ts","../node_modules/undici-types/balanced-pool.d.ts","../node_modules/undici-types/agent.d.ts","../node_modules/undici-types/mock-interceptor.d.ts","../node_modules/undici-types/mock-agent.d.ts","../node_modules/undici-types/mock-client.d.ts","../node_modules/undici-types/mock-pool.d.ts","../node_modules/undici-types/mock-errors.d.ts","../node_modules/undici-types/proxy-agent.d.ts","../node_modules/undici-types/env-http-proxy-agent.d.ts","../node_modules/undici-types/retry-handler.d.ts","../node_modules/undici-types/retry-agent.d.ts","../node_modules/undici-types/api.d.ts","../node_modules/undici-types/interceptors.d.ts","../node_modules/undici-types/util.d.ts","../node_modules/undici-types/cookies.d.ts","../node_modules/undici-types/patch.d.ts","../node_modules/undici-types/websocket.d.ts","../node_modules/undici-types/eventsource.d.ts","../node_modules/undici-types/filereader.d.ts","../node_modules/undici-types/diagnostics-channel.d.ts","../node_modules/undici-types/content-type.d.ts","../node_modules/undici-types/cache.d.ts","../node_modules/undici-types/index.d.ts","../node_modules/@types/node/globals.d.ts","../node_modules/@types/node/assert.d.ts","../node_modules/@types/node/assert/strict.d.ts","../node_modules/@types/node/async_hooks.d.ts","../node_modules/@types/node/buffer.d.ts","../node_modules/@types/node/child_process.d.ts","../node_modules/@types/node/cluster.d.ts","../node_modules/@types/node/console.d.ts","../node_modules/@types/node/constants.d.ts","../node_modules/@types/node/crypto.d.ts","../node_modules/@types/node/dgram.d.ts","../node_modules/@types/node/diagnostics_channel.d.ts","../node_modules/@types/node/dns.d.ts","../node_modules/@types/node/dns/promises.d.ts","../node_modules/@types/node/domain.d.ts","../node_modules/@types/node/dom-events.d.ts","../node_modules/@types/node/events.d.ts","../node_modules/@types/node/fs.d.ts","../node_modules/@types/node/fs/promises.d.ts","../node_modules/@types/node/http.d.ts","../node_modules/@types/node/http2.d.ts","../node_modules/@types/node/https.d.ts","../node_modules/@types/node/inspector.d.ts","../node_modules/@types/node/module.d.ts","../node_modules/@types/node/net.d.ts","../node_modules/@types/node/os.d.ts","../node_modules/@types/node/path.d.ts","../node_modules/@types/node/perf_hooks.d.ts","../node_modules/@types/node/process.d.ts","../node_modules/@types/node/punycode.d.ts","../node_modules/@types/node/querystring.d.ts","../node_modules/@types/node/readline.d.ts","../node_modules/@types/node/readline/promises.d.ts","../node_modules/@types/node/repl.d.ts","../node_modules/@types/node/sea.d.ts","../node_modules/@types/node/sqlite.d.ts","../node_modules/@types/node/stream.d.ts","../node_modules/@types/node/stream/promises.d.ts","../node_modules/@types/node/stream/consumers.d.ts","../node_modules/@types/node/stream/web.d.ts","../node_modules/@types/node/string_decoder.d.ts","../node_modules/@types/node/test.d.ts","../node_modules/@types/node/timers.d.ts","../node_modules/@types/node/timers/promises.d.ts","../node_modules/@types/node/tls.d.ts","../node_modules/@types/node/trace_events.d.ts","../node_modules/@types/node/tty.d.ts","../node_modules/@types/node/url.d.ts","../node_modules/@types/node/util.d.ts","../node_modules/@types/node/v8.d.ts","../node_modules/@types/node/vm.d.ts","../node_modules/@types/node/wasi.d.ts","../node_modules/@types/node/worker_threads.d.ts","../node_modules/@types/node/zlib.d.ts","../node_modules/@types/node/index.d.ts","../node_modules/@types/convict/index.d.ts","../node_modules/@types/convict-format-with-validator/index.d.ts","../src/utils.ts","../src/config.ts","../src/throttle.ts","../src/app.ts","../src/generate-config-docs.ts","../src/index.ts","../node_modules/@types/estree/index.d.ts","../node_modules/@types/json-schema/index.d.ts","../node_modules/@types/eslint/use-at-your-own-risk.d.ts","../node_modules/@types/eslint/index.d.ts","../node_modules/@types/eslint-scope/index.d.ts","../node_modules/@types/unist/index.d.ts","../node_modules/@types/hast/index.d.ts","../node_modules/@types/json5/index.d.ts","../node_modules/@types/normalize-package-data/index.d.ts","../node_modules/@types/semver/classes/semver.d.ts","../node_modules/@types/semver/functions/parse.d.ts","../node_modules/@types/semver/functions/valid.d.ts","../node_modules/@types/semver/functions/clean.d.ts","../node_modules/@types/semver/functions/inc.d.ts","../node_modules/@types/semver/functions/diff.d.ts","../node_modules/@types/semver/functions/major.d.ts","../node_modules/@types/semver/functions/minor.d.ts","../node_modules/@types/semver/functions/patch.d.ts","../node_modules/@types/semver/functions/prerelease.d.ts","../node_modules/@types/semver/functions/compare.d.ts","../node_modules/@types/semver/functions/rcompare.d.ts","../node_modules/@types/semver/functions/compare-loose.d.ts","../node_modules/@types/semver/functions/compare-build.d.ts","../node_modules/@types/semver/functions/sort.d.ts","../node_modules/@types/semver/functions/rsort.d.ts","../node_modules/@types/semver/functions/gt.d.ts","../node_modules/@types/semver/functions/lt.d.ts","../node_modules/@types/semver/functions/eq.d.ts","../node_modules/@types/semver/functions/neq.d.ts","../node_modules/@types/semver/functions/gte.d.ts","../node_modules/@types/semver/functions/lte.d.ts","../node_modules/@types/semver/functions/cmp.d.ts","../node_modules/@types/semver/functions/coerce.d.ts","../node_modules/@types/semver/classes/comparator.d.ts","../node_modules/@types/semver/classes/range.d.ts","../node_modules/@types/semver/functions/satisfies.d.ts","../node_modules/@types/semver/ranges/max-satisfying.d.ts","../node_modules/@types/semver/ranges/min-satisfying.d.ts","../node_modules/@types/semver/ranges/to-comparators.d.ts","../node_modules/@types/semver/ranges/min-version.d.ts","../node_modules/@types/semver/ranges/valid.d.ts","../node_modules/@types/semver/ranges/outside.d.ts","../node_modules/@types/semver/ranges/gtr.d.ts","../node_modules/@types/semver/ranges/ltr.d.ts","../node_modules/@types/semver/ranges/intersects.d.ts","../node_modules/@types/semver/ranges/simplify.d.ts","../node_modules/@types/semver/ranges/subset.d.ts","../node_modules/@types/semver/internals/identifiers.d.ts","../node_modules/@types/semver/index.d.ts"],"fileIdsList":[[85,128,179],[85,128,178],[85,128,187,190],[85,128,187,188,189],[85,128,190],[85,128],[85,128,192],[85,125,128],[85,127,128],[128],[85,128,133,163],[85,128,129,134,140,141,148,160,171],[85,128,129,130,140,148],[80,81,82,85,128],[85,128,131,172],[85,128,132,133,141,149],[85,128,133,160,168],[85,128,134,136,140,148],[85,127,128,135],[85,128,136,137],[85,128,140],[85,128,138,140],[85,127,128,140],[85,128,140,141,142,160,171],[85,128,140,141,142,155,160,163],[85,123,128,176],[85,123,128,136,140,143,148,160,171],[85,128,140,141,143,144,148,160,168,171],[85,128,143,145,160,168,171],[83,84,85,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177],[85,128,140,146],[85,128,147,171],[85,128,136,140,148,160],[85,128,149],[85,128,150],[85,127,128,151],[85,125,126,127,128,129,130,131,132,133,134,135,136,137,138,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177],[85,128,153],[85,128,154],[85,128,140,155,156],[85,128,155,157,172,174],[85,128,140,160,161,162,163],[85,128,160,162],[85,128,160,161],[85,128,163],[85,128,164],[85,125,128,160],[85,128,140,166,167],[85,128,166,167],[85,128,133,148,160,168],[85,128,169],[85,128,148,170],[85,128,143,154,171],[85,128,133,172],[85,128,160,173],[85,128,147,174],[85,128,175],[85,128,133,140,142,151,160,171,174,176],[85,128,160,177],[85,128,196,235],[85,128,196,220,235],[85,128,235],[85,128,196],[85,128,196,221,235],[85,128,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234],[85,128,221,235],[65,85,128],[64,85,128],[64,65,66,67,68,69,70,71,72,73,74,85,128],[67,85,128],[76,77,85,128],[69,85,128],[85,95,99,128,171],[85,95,128,160,171],[85,90,128],[85,92,95,128,168,171],[85,128,148,168],[85,90,128,178],[85,92,95,128,148,171],[85,87,88,91,94,128,140,160,171],[85,95,102,128],[85,87,93,128],[85,95,116,117,128],[85,91,95,128,163,171,178],[85,116,128,178],[85,89,90,128,178],[85,95,128],[85,89,90,91,92,93,94,95,96,97,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,117,118,119,120,121,122,128],[85,95,110,128],[85,95,102,103,128],[85,93,95,103,104,128],[85,94,128],[85,87,90,95,128],[85,95,99,103,104,128],[85,99,128],[85,93,95,98,128,171],[85,87,92,95,102,128],[85,128,160],[85,90,95,116,128,176,178],[75,78,79,85,128,129,141,181,182,183],[85,128,141,179,180,181],[85,128,142,182],[85,128,181,182,183,184],[78,85,128,129,140,141,149,181],[85,128,129,141,149,150]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7a3c8b952931daebdfc7a2897c53c0a1c73624593fa070e46bd537e64dcd20a","affectsGlobalScope":true,"impliedFormat":1},{"version":"80e18897e5884b6723488d4f5652167e7bb5024f946743134ecc4aa4ee731f89","affectsGlobalScope":true,"impliedFormat":1},{"version":"cd034f499c6cdca722b60c04b5b1b78e058487a7085a8e0d6fb50809947ee573","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"3cbad9a1ba4453443026ed38e4b8be018abb26565fa7c944376463ad9df07c41","impliedFormat":1},{"version":"b4e123af1af6049685c93073a15868b50aebdad666d422edc72fa2b585fa8a37","impliedFormat":1},{"version":"f86c04a744ebcede96bac376f9a2c90f2bd3c422740d91dda4ca6233199d4977","impliedFormat":1},{"version":"6ae1bddee5c790439bd992abd063b9b46e0cadd676c2a8562268d1869213ff60","impliedFormat":1},{"version":"606244fc97a6a74b877f2e924ba7e55b233bc6acb57d7bf40ba84a5be2d9adb0","impliedFormat":1},{"version":"4a1cabac71036b8a14f5db1b753b579f0c901c7d7b9227e6872dadf6efb104e8","impliedFormat":1},{"version":"062959a1d825b96639d87be35fe497cbd3f89544bf06fdad577bbfb85fcf604c","impliedFormat":1},{"version":"4c3672dc8f4e4fdd3d18525b22b31f1b5481f5a415db96550d3ac5163a6c3dd3","impliedFormat":1},{"version":"f9a69ca445010b91fe08f08c06e0f86d79c0d776905f9bdb828477cb2a1eb7fc","impliedFormat":1},{"version":"ad7fd0e7ee457d4884b3aaecbcbd2a80b6803407c4ce2540c296170d4c7918ef","impliedFormat":1},{"version":"a50ef21605f41c6acad6c3ef0307e5311b94963c846ca093c764b80cdb5318d6","impliedFormat":1},{"version":"74b4035dd26d09a417c44ca23ab5ee69b173f8c2f6b2e47350ab0795cf2d4a17","impliedFormat":1},{"version":"918f86ee2b19cc38cb8b1a4cf8f223eb228aaa39df3604c42f700fac2f0b3ea1","impliedFormat":1},{"version":"88a3a6f8c2a1640d8d5fd30d8d86462f8babd86a1e52fab0e8b7f7c141fb348e","impliedFormat":1},{"version":"345f76c854da724803c96f727a3f9c75e26cf95c6e7b8c1064dbc4e7727b74e6","impliedFormat":1},{"version":"ab7b7a15a5d73eb0cfc2b973e580f357f07492bff6608669d7e899e2d49ac9a3","impliedFormat":1},{"version":"14e27c8804ce2fe36fe1cfdbea2c0625cb97f4c20394fa9973567fb09cc03406","impliedFormat":1},{"version":"70521b6ab0dcba37539e5303104f29b721bfb2940b2776da4cc818c07e1fefc1","affectsGlobalScope":true,"impliedFormat":1},{"version":"030e350db2525514580ed054f712ffb22d273e6bc7eddc1bb7eda1e0ba5d395e","affectsGlobalScope":true,"impliedFormat":1},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"a79e62f1e20467e11a904399b8b18b18c0c6eea6b50c1168bf215356d5bebfaf","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fd06258805d26c72f5997e07a23155d322d5f05387adb3744a791fe6a0b042d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"24bd580b5743dc56402c440dc7f9a4f5d592ad7a419f25414d37a7bfe11e342b","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"6bdc71028db658243775263e93a7db2fd2abfce3ca569c3cca5aee6ed5eb186d","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"d2bc987ae352271d0d615a420dcf98cc886aa16b87fb2b569358c1fe0ca0773d","affectsGlobalScope":true,"impliedFormat":1},{"version":"f52e8dacc97d71dcc96af29e49584353f9c54cb916d132e3e768d8b8129c928d","impliedFormat":1},{"version":"7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","impliedFormat":1},{"version":"76103716ba397bbb61f9fa9c9090dca59f39f9047cb1352b2179c5d8e7f4e8d0","impliedFormat":1},{"version":"53eac70430b30089a3a1959d8306b0f9cfaf0de75224b68ef25243e0b5ad1ca3","affectsGlobalScope":true,"impliedFormat":1},{"version":"4314c7a11517e221f7296b46547dbc4df047115b182f544d072bdccffa57fc72","impliedFormat":1},{"version":"115971d64632ea4742b5b115fb64ed04bcaae2c3c342f13d9ba7e3f9ee39c4e7","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"a40826e8476694e90da94aa008283a7de50d1dafd37beada623863f1901cb7fb","impliedFormat":1},{"version":"86956cc2eb9dd371d6fab493d326a574afedebf76eef3fa7833b8e0d9b52d6f1","affectsGlobalScope":true,"impliedFormat":1},{"version":"91c1a729db5b28b2fc32bafa7a53611d417bc3f03f649278d4fd948aa4dec898","impliedFormat":1},{"version":"e6f5a38687bebe43a4cef426b69d34373ef68be9a6b1538ec0a371e69f309354","impliedFormat":1},{"version":"a6bf63d17324010ca1fbf0389cab83f93389bb0b9a01dc8a346d092f65b3605f","impliedFormat":1},{"version":"e009777bef4b023a999b2e5b9a136ff2cde37dc3f77c744a02840f05b18be8ff","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"ee1ee365d88c4c6c0c0a5a5701d66ebc27ccd0bcfcfaa482c6e2e7fe7b98edf7","affectsGlobalScope":true,"impliedFormat":1},{"version":"88bc59b32d0d5b4e5d9632ac38edea23454057e643684c3c0b94511296f2998c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1ff5a53a58e756d2661b73ba60ffe274231a4432d21f7a2d0d9e4f6aa99f4283","impliedFormat":1},{"version":"eaf9ee1d90a35d56264f0bf39842282c58b9219e112ac7d0c1bce98c6c5da672","impliedFormat":1},{"version":"c15c4427ae7fd1dcd7f312a8a447ac93581b0d4664ddf151ecd07de4bf2bb9d7","impliedFormat":1},{"version":"5135bdd72cc05a8192bd2e92f0914d7fc43ee077d1293dc622a049b7035a0afb","impliedFormat":1},{"version":"4f80de3a11c0d2f1329a72e92c7416b2f7eab14f67e92cac63bb4e8d01c6edc8","impliedFormat":1},{"version":"6d386bc0d7f3afa1d401afc3e00ed6b09205a354a9795196caed937494a713e6","impliedFormat":1},{"version":"c72ccc191348ac1933226cab7a814cfda8b29a827d1df5dbebfe516a6fd734a8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8bea55446a296d289fbc762f61954a0e3e38ffbcacc06e47e0cba491030e3235","impliedFormat":1},{"version":"b1b6ee0d012aeebe11d776a155d8979730440082797695fc8e2a5c326285678f","impliedFormat":1},{"version":"45875bcae57270aeb3ebc73a5e3fb4c7b9d91d6b045f107c1d8513c28ece71c0","impliedFormat":1},{"version":"3eb62baae4df08c9173e6903d3ca45942ccec8c3659b0565684a75f3292cffbb","affectsGlobalScope":true,"impliedFormat":1},{"version":"42aaa94addeed66a04b61e433c14e829c43d1efd653cf2fda480c5fb3d722ed8","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"c6b4e0a02545304935ecbf7de7a8e056a31bb50939b5b321c9d50a405b5a0bba","impliedFormat":1},{"version":"fab29e6d649aa074a6b91e3bdf2bff484934a46067f6ee97a30fcd9762ae2213","impliedFormat":1},{"version":"8145e07aad6da5f23f2fcd8c8e4c5c13fb26ee986a79d03b0829b8fce152d8b2","impliedFormat":1},{"version":"e1120271ebbc9952fdc7b2dd3e145560e52e06956345e6fdf91d70ca4886464f","impliedFormat":1},{"version":"15c5e91b5f08be34a78e3d976179bf5b7a9cc28dc0ef1ffebffeb3c7812a2dca","impliedFormat":1},{"version":"d63ff33a2fa221b36a4da0dd5a3dad3156f3dd0fe1baf43a186e607d4ba5af99","impliedFormat":1},{"version":"553870e516f8c772b89f3820576152ebc70181d7994d96917bb943e37da7f8a7","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"93452d394fdd1dc551ec62f5042366f011a00d342d36d50793b3529bfc9bd633","impliedFormat":1},{"version":"745c4240220559bd340c8aeb6e3c5270a709d3565e934dc22a69c304703956bc","affectsGlobalScope":true,"impliedFormat":1},{"version":"2754d8221d77c7b382096651925eb476f1066b3348da4b73fe71ced7801edada","impliedFormat":1},{"version":"9212c6e9d80cb45441a3614e95afd7235a55a18584c2ed32d6c1aca5a0c53d93","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef91efa0baea5d0e0f0f27b574a8bc100ce62a6d7e70220a0d58af6acab5e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"282fd2a1268a25345b830497b4b7bf5037a5e04f6a9c44c840cb605e19fea841","impliedFormat":1},{"version":"5360a27d3ebca11b224d7d3e38e3e2c63f8290cb1fcf6c3610401898f8e68bc3","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"7d6ff413e198d25639f9f01f16673e7df4e4bd2875a42455afd4ecc02ef156da","affectsGlobalScope":true,"impliedFormat":1},{"version":"1f58ebc40c84046ba4c25cf7e86e1ae92c3f064fb641af6c46a5acebf0b8b20b","affectsGlobalScope":true,"impliedFormat":1},{"version":"f689c4237b70ae6be5f0e4180e8833f34ace40529d1acc0676ab8fb8f70457d7","impliedFormat":1},{"version":"ae25afbbf1ed5df63a177d67b9048bf7481067f1b8dc9c39212e59db94fc9fc6","impliedFormat":1},{"version":"ac5ed35e649cdd8143131964336ab9076937fa91802ec760b3ea63b59175c10a","impliedFormat":1},{"version":"52a8e7e8a1454b6d1b5ad428efae3870ffc56f2c02d923467f2940c454aa9aec","affectsGlobalScope":true,"impliedFormat":1},{"version":"78dc0513cc4f1642906b74dda42146bcbd9df7401717d6e89ea6d72d12ecb539","impliedFormat":1},{"version":"ad90122e1cb599b3bc06a11710eb5489101be678f2920f2322b0ac3e195af78d","impliedFormat":1},{"version":"03d0e8cd16f16b504879544f6323f0e0a9ca9a6e70277c15bf3db9eeedb435cc","impliedFormat":1},{"version":"92d4cd0e80a54da81b6dca627c6b7f3357f91227ee5a2f807fe170c5e1486c85","impliedFormat":1},{"version":"f9ee90b6077378c21926a5c4ad07f76516df15faa281e0c282fab0b628458a1f","signature":"9135f578c1159fbc1a37339a1187c3d44459ec16090e2b84ed6c761900cf8afe","impliedFormat":1},{"version":"8648346b485f088f1171680a4cea70dc100f3cf7e6311a27cf520ffc9fab8ea1","signature":"bd28c9f28c2b9008b46ac5a90e3f397f8285f23b4f7c05171971d30649ffaaa0","impliedFormat":1},{"version":"85410177f0607c4f0f49d39497280b6a3fb631ea44024d41bd6f0c8265251513","signature":"01f118ac01015be05dc2a0005706bf8fe8248aaaed36c50f23b2a64dde0517ac","impliedFormat":1},{"version":"c7b5914ff504aa3590ef5a98f6a41ead9ccd896aae5ef129cfca16945f9b1af2","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"f7368a5cb0c090073c3ed4426d884aaab84c861bfd5266cc01e52fa4911b8609","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"17c20b6076805a442682f4cb8fa35a6bbcaa6c0309fc3fd7ce2b82597a8882b3","signature":"99e19059c4bd18df586ee56283eb59b0aba861204fb89cde18e064d64f6dc0ec","impliedFormat":1},{"version":"785b9d575b49124ce01b46f5b9402157c7611e6532effa562ac6aebec0074dfc","impliedFormat":1},{"version":"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","impliedFormat":1},{"version":"a4a39b5714adfcadd3bbea6698ca2e942606d833bde62ad5fb6ec55f5e438ff8","impliedFormat":1},{"version":"bbc1d029093135d7d9bfa4b38cbf8761db505026cc458b5e9c8b74f4000e5e75","impliedFormat":1},{"version":"1f68ab0e055994eb337b67aa87d2a15e0200951e9664959b3866ee6f6b11a0fe","impliedFormat":1},{"version":"89121c1bf2990f5219bfd802a3e7fc557de447c62058d6af68d6b6348d64499a","impliedFormat":1},{"version":"79b4369233a12c6fa4a07301ecb7085802c98f3a77cf9ab97eee27e1656f82e6","impliedFormat":1},{"version":"96d14f21b7652903852eef49379d04dbda28c16ed36468f8c9fa08f7c14c9538","impliedFormat":1},{"version":"22293bd6fa12747929f8dfca3ec1684a3fe08638aa18023dd286ab337e88a592","impliedFormat":1},{"version":"cf3d384d082b933d987c4e2fe7bfb8710adfd9dc8155190056ed6695a25a559e","impliedFormat":1},{"version":"9871b7ee672bc16c78833bdab3052615834b08375cb144e4d2cba74473f4a589","impliedFormat":1},{"version":"c863198dae89420f3c552b5a03da6ed6d0acfa3807a64772b895db624b0de707","impliedFormat":1},{"version":"8b03a5e327d7db67112ebbc93b4f744133eda2c1743dbb0a990c61a8007823ef","impliedFormat":1},{"version":"86c73f2ee1752bac8eeeece234fd05dfcf0637a4fbd8032e4f5f43102faa8eec","impliedFormat":1},{"version":"42fad1f540271e35ca37cecda12c4ce2eef27f0f5cf0f8dd761d723c744d3159","impliedFormat":1},{"version":"ff3743a5de32bee10906aff63d1de726f6a7fd6ee2da4b8229054dfa69de2c34","impliedFormat":1},{"version":"83acd370f7f84f203e71ebba33ba61b7f1291ca027d7f9a662c6307d74e4ac22","impliedFormat":1},{"version":"1445cec898f90bdd18b2949b9590b3c012f5b7e1804e6e329fb0fe053946d5ec","impliedFormat":1},{"version":"0e5318ec2275d8da858b541920d9306650ae6ac8012f0e872fe66eb50321a669","impliedFormat":1},{"version":"cf530297c3fb3a92ec9591dd4fa229d58b5981e45fe6702a0bd2bea53a5e59be","impliedFormat":1},{"version":"c1f6f7d08d42148ddfe164d36d7aba91f467dbcb3caa715966ff95f55048b3a4","impliedFormat":1},{"version":"f4e9bf9103191ef3b3612d3ec0044ca4044ca5be27711fe648ada06fad4bcc85","impliedFormat":1},{"version":"0c1ee27b8f6a00097c2d6d91a21ee4d096ab52c1e28350f6362542b55380059a","impliedFormat":1},{"version":"7677d5b0db9e020d3017720f853ba18f415219fb3a9597343b1b1012cfd699f7","impliedFormat":1},{"version":"bc1c6bc119c1784b1a2be6d9c47addec0d83ef0d52c8fbe1f14a51b4dfffc675","impliedFormat":1},{"version":"52cf2ce99c2a23de70225e252e9822a22b4e0adb82643ab0b710858810e00bf1","impliedFormat":1},{"version":"770625067bb27a20b9826255a8d47b6b5b0a2d3dfcbd21f89904c731f671ba77","impliedFormat":1},{"version":"d1ed6765f4d7906a05968fb5cd6d1db8afa14dbe512a4884e8ea5c0f5e142c80","impliedFormat":1},{"version":"799c0f1b07c092626cf1efd71d459997635911bb5f7fc1196efe449bba87e965","impliedFormat":1},{"version":"2a184e4462b9914a30b1b5c41cf80c6d3428f17b20d3afb711fff3f0644001fd","impliedFormat":1},{"version":"9eabde32a3aa5d80de34af2c2206cdc3ee094c6504a8d0c2d6d20c7c179503cc","impliedFormat":1},{"version":"397c8051b6cfcb48aa22656f0faca2553c5f56187262135162ee79d2b2f6c966","impliedFormat":1},{"version":"a8ead142e0c87dcd5dc130eba1f8eeed506b08952d905c47621dc2f583b1bff9","impliedFormat":1},{"version":"a02f10ea5f73130efca046429254a4e3c06b5475baecc8f7b99a0014731be8b3","impliedFormat":1},{"version":"c2576a4083232b0e2d9bd06875dd43d371dee2e090325a9eac0133fd5650c1cb","impliedFormat":1},{"version":"4c9a0564bb317349de6a24eb4efea8bb79898fa72ad63a1809165f5bd42970dd","impliedFormat":1},{"version":"f40ac11d8859092d20f953aae14ba967282c3bb056431a37fced1866ec7a2681","impliedFormat":1},{"version":"cc11e9e79d4746cc59e0e17473a59d6f104692fd0eeea1bdb2e206eabed83b03","impliedFormat":1},{"version":"b444a410d34fb5e98aa5ee2b381362044f4884652e8bc8a11c8fe14bbd85518e","impliedFormat":1},{"version":"c35808c1f5e16d2c571aa65067e3cb95afeff843b259ecfa2fc107a9519b5392","impliedFormat":1},{"version":"14d5dc055143e941c8743c6a21fa459f961cbc3deedf1bfe47b11587ca4b3ef5","impliedFormat":1},{"version":"a3ad4e1fc542751005267d50a6298e6765928c0c3a8dce1572f2ba6ca518661c","impliedFormat":1},{"version":"f237e7c97a3a89f4591afd49ecb3bd8d14f51a1c4adc8fcae3430febedff5eb6","impliedFormat":1},{"version":"3ffdfbec93b7aed71082af62b8c3e0cc71261cc68d796665faa1e91604fbae8f","impliedFormat":1},{"version":"662201f943ed45b1ad600d03a90dffe20841e725203ced8b708c91fcd7f9379a","impliedFormat":1},{"version":"c9ef74c64ed051ea5b958621e7fb853fe3b56e8787c1587aefc6ea988b3c7e79","impliedFormat":1},{"version":"2462ccfac5f3375794b861abaa81da380f1bbd9401de59ffa43119a0b644253d","impliedFormat":1},{"version":"34baf65cfee92f110d6653322e2120c2d368ee64b3c7981dff08ed105c4f19b0","impliedFormat":1},{"version":"7d8ddf0f021c53099e34ee831a06c394d50371816caa98684812f089b4c6b3d4","impliedFormat":1}],"root":[[181,186]],"options":{"allowJs":false,"composite":true,"declaration":true,"esModuleInterop":true,"experimentalDecorators":true,"inlineSources":true,"module":100,"outDir":"./","rootDir":"..","skipLibCheck":true,"sourceMap":true,"strict":true,"target":9},"referencedMap":[[180,1],[179,2],[191,3],[190,4],[189,5],[187,6],[193,7],[188,6],[194,6],[125,8],[126,8],[127,9],[85,10],[128,11],[129,12],[130,13],[80,6],[83,14],[81,6],[82,6],[131,15],[132,16],[133,17],[134,18],[135,19],[136,20],[137,20],[139,21],[138,22],[140,23],[141,24],[142,25],[124,26],[84,6],[143,27],[144,28],[145,29],[178,30],[146,31],[147,32],[148,33],[149,34],[150,35],[151,36],[152,37],[153,38],[154,39],[155,40],[156,40],[157,41],[158,6],[159,6],[160,42],[162,43],[161,44],[163,45],[164,46],[165,47],[166,48],[167,49],[168,50],[169,51],[170,52],[171,53],[172,54],[173,55],[174,56],[175,57],[176,58],[177,59],[195,6],[220,60],[221,61],[196,62],[199,62],[218,60],[219,60],[209,60],[208,63],[206,60],[201,60],[214,60],[212,60],[216,60],[200,60],[213,60],[217,60],[202,60],[203,60],[215,60],[197,60],[204,60],[205,60],[207,60],[211,60],[222,64],[210,60],[198,60],[235,65],[234,6],[229,64],[231,66],[230,64],[223,64],[224,64],[226,64],[228,64],[232,66],[233,66],[225,66],[227,66],[192,6],[86,6],[66,67],[67,68],[75,69],[68,68],[69,68],[70,70],[78,71],[76,6],[77,6],[64,6],[71,72],[65,68],[72,72],[73,68],[74,72],[61,6],[62,6],[12,6],[10,6],[11,6],[16,6],[15,6],[2,6],[17,6],[18,6],[19,6],[20,6],[21,6],[22,6],[23,6],[24,6],[3,6],[25,6],[26,6],[4,6],[27,6],[31,6],[28,6],[29,6],[30,6],[32,6],[33,6],[34,6],[5,6],[35,6],[36,6],[37,6],[38,6],[6,6],[42,6],[39,6],[40,6],[41,6],[43,6],[7,6],[44,6],[49,6],[50,6],[45,6],[46,6],[47,6],[48,6],[8,6],[54,6],[51,6],[52,6],[53,6],[55,6],[9,6],[56,6],[63,6],[57,6],[58,6],[60,6],[59,6],[1,6],[14,6],[13,6],[102,73],[112,74],[101,73],[122,75],[93,76],[92,77],[121,2],[115,78],[120,79],[95,80],[109,81],[94,82],[118,83],[90,84],[89,2],[119,85],[91,86],[96,87],[97,6],[100,87],[87,6],[123,88],[113,89],[104,90],[105,91],[107,92],[103,93],[106,94],[116,2],[98,95],[99,96],[108,97],[88,98],[111,89],[110,87],[114,6],[117,99],[79,6],[184,100],[182,101],[185,102],[186,103],[183,104],[181,105]],"latestChangedDtsFile":"./src/index.d.ts","version":"5.9.2"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vpalmisano/throttler",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/vpalmisano/throttler.git"
|
|
@@ -57,22 +57,22 @@
|
|
|
57
57
|
"@vpalmisano/typedoc-cookie-consent": "^0.0.4",
|
|
58
58
|
"@vpalmisano/typedoc-plugin-ga": "^1.0.6",
|
|
59
59
|
"eslint": "^8.57.0",
|
|
60
|
-
"eslint-config-prettier": "^10.1.
|
|
60
|
+
"eslint-config-prettier": "^10.1.8",
|
|
61
61
|
"eslint-config-standard": "^17.1.0",
|
|
62
62
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
63
63
|
"eslint-plugin-import": "^2.32.0",
|
|
64
|
-
"eslint-plugin-jest": "^
|
|
64
|
+
"eslint-plugin-jest": "^29.0.1",
|
|
65
65
|
"eslint-plugin-node": "^11.1.0",
|
|
66
|
-
"eslint-plugin-prettier": "^5.5.
|
|
66
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
67
67
|
"eslint-plugin-promise": "^6.2.0",
|
|
68
68
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
69
|
-
"eslint-plugin-unused-imports": "^4.
|
|
69
|
+
"eslint-plugin-unused-imports": "^4.2.0",
|
|
70
70
|
"prettier": "^3.6.2",
|
|
71
71
|
"terser-webpack-plugin": "^5.3.10",
|
|
72
|
-
"ts-loader": "^9.5.
|
|
73
|
-
"typedoc": "^0.28.
|
|
74
|
-
"typescript": "^5.
|
|
75
|
-
"webpack": "^5.
|
|
72
|
+
"ts-loader": "^9.5.4",
|
|
73
|
+
"typedoc": "^0.28.12",
|
|
74
|
+
"typescript": "^5.9.2",
|
|
75
|
+
"webpack": "^5.101.3",
|
|
76
76
|
"webpack-cli": "^5.1.4",
|
|
77
77
|
"webpack-node-externals": "^3.0.0",
|
|
78
78
|
"yarn-upgrade-minor": "^1.0.13"
|
package/src/throttle.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'child_process'
|
|
2
|
+
import { EventEmitter } from 'events'
|
|
2
3
|
import fs from 'fs'
|
|
3
4
|
import JSON5 from 'json5'
|
|
4
5
|
import os from 'os'
|
|
@@ -45,6 +46,17 @@ const throttleCurrentValues = {
|
|
|
45
46
|
>(),
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
export const throttleNotifier = new EventEmitter()
|
|
50
|
+
|
|
51
|
+
async function runShellCommandIfLinux(
|
|
52
|
+
cmd: string,
|
|
53
|
+
verbose = false,
|
|
54
|
+
): Promise<void> {
|
|
55
|
+
if (os.platform() === 'linux') {
|
|
56
|
+
await runShellCommand(cmd, verbose)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
48
60
|
async function cleanup(): Promise<void> {
|
|
49
61
|
await Promise.allSettled([...captureStops.values()].map(stop => stop()))
|
|
50
62
|
captureStops.clear()
|
|
@@ -52,11 +64,12 @@ async function cleanup(): Promise<void> {
|
|
|
52
64
|
ruleTimeouts.clear()
|
|
53
65
|
throttleCurrentValues.up.clear()
|
|
54
66
|
throttleCurrentValues.down.clear()
|
|
67
|
+
throttleNotifier.emit('change')
|
|
55
68
|
let device = throttleConfig?.length ? throttleConfig[0].device : ''
|
|
56
69
|
if (!device) {
|
|
57
70
|
device = await getDefaultNetworkInterface()
|
|
58
71
|
}
|
|
59
|
-
await
|
|
72
|
+
await runShellCommandIfLinux(`\
|
|
60
73
|
sudo -n tc qdisc del dev ${device} root || true;
|
|
61
74
|
sudo -n tc class del dev ${device} || true;
|
|
62
75
|
sudo -n tc filter del dev ${device} || true;
|
|
@@ -216,7 +229,7 @@ sudo -n tc filter add dev ${device} \
|
|
|
216
229
|
flowid 1:${handle};
|
|
217
230
|
`
|
|
218
231
|
try {
|
|
219
|
-
await
|
|
232
|
+
await runShellCommandIfLinux(cmd, true)
|
|
220
233
|
} catch (err) {
|
|
221
234
|
log.error(`error running "${cmd}": ${(err as Error).stack}`)
|
|
222
235
|
throw err
|
|
@@ -268,7 +281,7 @@ sudo -n tc filter add dev ${device} \
|
|
|
268
281
|
}
|
|
269
282
|
}
|
|
270
283
|
|
|
271
|
-
log.info(`applying rules on ${device} (${mark}): ${desc}`)
|
|
284
|
+
log.info(`applying rules on ${device} (${mark}): ${desc.trim()}`)
|
|
272
285
|
const cmd = `\
|
|
273
286
|
sudo -n tc qdisc change dev ${device} \
|
|
274
287
|
parent 1:${handle} \
|
|
@@ -277,7 +290,7 @@ sudo -n tc qdisc change dev ${device} \
|
|
|
277
290
|
try {
|
|
278
291
|
ruleTimeouts.delete(timeoutId)
|
|
279
292
|
|
|
280
|
-
await
|
|
293
|
+
await runShellCommandIfLinux(cmd)
|
|
281
294
|
|
|
282
295
|
throttleCurrentValues[direction].set(index, {
|
|
283
296
|
rate: rate ? 1000 * rate : undefined,
|
|
@@ -285,6 +298,7 @@ sudo -n tc qdisc change dev ${device} \
|
|
|
285
298
|
loss: loss || undefined,
|
|
286
299
|
queue: limit || undefined,
|
|
287
300
|
})
|
|
301
|
+
throttleNotifier.emit('change')
|
|
288
302
|
} catch (err) {
|
|
289
303
|
log.error(`error running "${cmd}": ${(err as Error).stack}`)
|
|
290
304
|
}
|
|
@@ -312,7 +326,7 @@ async function start(): Promise<void> {
|
|
|
312
326
|
device = await getDefaultNetworkInterface()
|
|
313
327
|
}
|
|
314
328
|
|
|
315
|
-
await
|
|
329
|
+
await runShellCommandIfLinux(
|
|
316
330
|
`\
|
|
317
331
|
set -e;
|
|
318
332
|
|
|
@@ -362,7 +376,7 @@ sudo -n tc filter add dev ${device} \
|
|
|
362
376
|
config.match,
|
|
363
377
|
)
|
|
364
378
|
}
|
|
365
|
-
if (config.capture) {
|
|
379
|
+
if (config.capture && os.platform() === 'linux') {
|
|
366
380
|
captureStops.set(
|
|
367
381
|
index,
|
|
368
382
|
capturePackets(index, config.capture, config.protocol),
|
|
@@ -377,9 +391,6 @@ sudo -n tc filter add dev ${device} \
|
|
|
377
391
|
* @param config A JSON5 configuration parsed as {@link ThrottleConfig}.
|
|
378
392
|
*/
|
|
379
393
|
export async function startThrottle(config: string): Promise<void> {
|
|
380
|
-
if (os.platform() !== 'linux') {
|
|
381
|
-
throw new Error('Throttle option is only supported on Linux')
|
|
382
|
-
}
|
|
383
394
|
try {
|
|
384
395
|
throttleConfig = JSON5.parse(config) as ThrottleConfig[]
|
|
385
396
|
log.debug('Starting throttle with config:', throttleConfig)
|
|
@@ -396,9 +407,6 @@ export async function startThrottle(config: string): Promise<void> {
|
|
|
396
407
|
* Stops the network throttle.
|
|
397
408
|
*/
|
|
398
409
|
export async function stopThrottle(): Promise<void> {
|
|
399
|
-
if (os.platform() !== 'linux') {
|
|
400
|
-
throw new Error('Throttle option is only supported on Linux')
|
|
401
|
-
}
|
|
402
410
|
try {
|
|
403
411
|
log.debug('Stopping throttle')
|
|
404
412
|
await cleanup()
|
|
@@ -505,7 +513,7 @@ async function cleanupRules(): Promise<void> {
|
|
|
505
513
|
if (!throttleConfig?.length) return
|
|
506
514
|
log.debug(`cleanupRules (${throttleConfig.length})`)
|
|
507
515
|
try {
|
|
508
|
-
await
|
|
516
|
+
await runShellCommandIfLinux(`\
|
|
509
517
|
for i in $(seq 0 ${throttleConfig.length}); do
|
|
510
518
|
rule=$(sudo -n iptables -t mangle -L OUTPUT --line-numbers | grep "owner GID match throttler\${i}" | awk '{print $1}');
|
|
511
519
|
if [ -n "$rule" ]; then
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'child_process'
|
|
2
2
|
import fs from 'fs'
|
|
3
|
+
import os from 'os'
|
|
3
4
|
import path from 'path'
|
|
4
5
|
|
|
5
6
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
@@ -87,6 +88,7 @@ export function toPrecision(value: number, precision = 3): string {
|
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
export async function getDefaultNetworkInterface(): Promise<string> {
|
|
91
|
+
if (os.platform() !== 'linux') return 'lo'
|
|
90
92
|
const { stdout } = await runShellCommand(
|
|
91
93
|
`ip route | awk '/default/ {print $5; exit}' | tr -d ''`,
|
|
92
94
|
)
|
package/throttler.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
(()=>{"use strict";var e={28:function(e,t,r){var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(n=function(e){return n=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[t.length]=r);return t},n(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r=n(e),s=0;s<r.length;s++)"default"!==r[s]&&o(t,e,r[s]);return i(t,e),t});Object.defineProperty(t,"__esModule",{value:!0}),t.getConfigDocs=function(){return g({},null,f.getSchema())},t.loadConfig=function(e,t){e&&(0,c.existsSync)(e)?(d.debug(`Loading config from ${e}`),f.loadFile(e)):t?(d.debug("Loading config from values."),f.load(t)):(d.debug("Using default values."),f.load({}));f.validate({allowed:"strict"});const r=f.getProperties();return d.debug("Using config:",r),r};const a=s(r(950)),l=r(618),c=r(896),d=(0,r(185).logger)("throttler:config"),u={name:"float",coerce:e=>parseFloat(e),validate:e=>{if(!Number.isFinite(e))throw new Error(`Invalid float: ${e}`)}},p={name:"index",coerce:e=>e,validate:e=>{if("string"==typeof e){if("true"===e||"false"===e||""===e)return;if(-1!==e.indexOf("-"))return void e.split("-").forEach((e=>{if(isNaN(parseInt(e))||!isFinite(parseInt(e)))throw new Error(`Invalid index: ${e}`)}));if(-1!==e.indexOf(","))return void e.split(",").forEach((e=>{if(isNaN(parseInt(e))||!isFinite(parseInt(e)))throw new Error(`Invalid index: ${e}`)}));if(isNaN(parseInt(e))||!isFinite(parseInt(e)))throw new Error(`Invalid index: ${e}`)}else if("number"==typeof e||"boolean"==typeof e)return;throw new Error(`Invalid index: ${e}`)}};(0,a.addFormats)({ipaddress:l.ipaddress,url:l.url,float:u,index:p});const f=(0,a.default)({runDuration:{doc:"If greater than 0, the test will stop after the provided number of seconds.",format:"nat",default:0,env:"RUN_DURATION",arg:"run-duration"},throttleConfig:{doc:"A JSON5 string with a valid network throttling configuration. Example: \n ```javascript\n [{\n sessions: '0-1',\n device: 'eth0',\n protocol: 'udp',\n capture: 'capture.pcap',\n up: {\n rate: 1000,\n delay: 50,\n loss: 5,\n queue: 10,\n },\n down: [\n { rate: 2000, delay: 50, loss: 2, queue: 20 },\n { rate: 1000, delay: 50, loss: 2, queue: 20, at: 60 },\n ]\n }]\n ```\nThe sessions field represents the sessions IDs range that will be affected by the rule, e.g.: \"0-10\", \"2,4\" or simply \"2\". The device, protocol, up, down fields are optional. When device is not set, the default route device will be used. If protocol is specified ('udp' or 'tcp'), only the packets with the specified protocol will be affected by the shaping rules. ",format:String,nullable:!0,default:"",env:"THROTTLE_CONFIG",arg:"throttle-config"},commandConfig:{doc:'The commands configuration.Example: \n ```javascript\n [{\n session: 0,\n command: "firefox https://www.speedtest.net",\n }]\n ```\n',format:String,nullable:!0,default:"",env:"COMMAND_CONFIG",arg:"command-config"}});function g(e,t,r){return r._cvtProperties?(Object.entries(r._cvtProperties).forEach((([r,n])=>{g(e,`${t?`${t}.`:""}${r}`,n)})),e):(t&&(e[t]={doc:r.doc,format:JSON.stringify(r.format,null,2),default:JSON.stringify(r.default,null,2)}),e)}f.getProperties()},185:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.LoggerInterface=t.Log=void 0,t.logger=s,t.resolvePackagePath=function(e){if("__nexe"in process)return e;return i.default.join(i.default.dirname(__filename),e)},t.toPrecision=function(e,t=3){return(Math.round(e*10**t)/10**t).toFixed(t)},t.getDefaultNetworkInterface=async function(){const{stdout:e}=await l("ip route | awk '/default/ {print $5; exit}' | tr -d ''");return e.trim()},t.checkNetworkInterface=async function(e){if("lo"===e)return;await l(`ip route | grep -q "dev ${e}"`)},t.runShellCommand=l,t.registerExitHandler=function(e){c.add(e)},t.unregisterExitHandler=function(e){c.delete(e)},t.runExitHandlersNow=p,t.getProcessChildren=async function e(t){a.debug(`getProcessChildren pid=${t}`);const r=[];try{const n=await l(`pgrep -P ${t}`);for(const t of n.stdout.trim().split("\n").map(Number)){r.push(t);try{const n=await e(t);for(const e of n)r.push(e)}catch(e){a.debug(`Error getting process ${t} children: ${e.message}`)}}}catch(e){a.debug(`Error getting process ${t} children: ${e.message}`)}return r};const o=r(200),i=(n(r(896)),n(r(928)));function s(e,r={}){return new t.Log(e,{splitLine:!1,...r})}t.Log=r(940).Log;t.LoggerInterface=class{name;logInit(e){this.name&&e.unshift(`[${this.name}]`)}debug(...e){this.logInit(e),a.debug(...e)}info(...e){this.logInit(e),a.info(...e)}warn(...e){this.logInit(e),a.warn(...e)}error(...e){this.logInit(e),a.error(...e)}log(...e){this.logInit(e),a.log(...e)}};const a=s("webrtcperf:utils");async function l(e,t=!1){return t&&a.debug(`runShellCommand cmd: ${e}`),new Promise(((r,n)=>{const i=(0,o.spawn)(e,{shell:!0,stdio:["ignore","pipe","pipe"],detached:!0});let s="",l="";i.stdout.on("data",(e=>{s.length>524288&&(s=s.slice(e.length)),s+=e})),i.stderr.on("data",(e=>{l.length>524288&&(l=l.slice(e.length)),l+=e})),i.once("error",(e=>n(e))),i.once("close",(o=>{0!==o?n(new Error(`runShellCommand cmd: ${e} failed with code ${o}: ${l}`)):(t&&a.debug(`runShellCommand cmd: ${e} done`,{stdout:s,stderr:l}),r({stdout:s,stderr:l}))}))}))}const c=new Set;const d=async e=>{let t=0;for(const r of c.values()){const n=`${t+1}/${c.size}`;a.debug(`running exitHandler ${n}`);try{await r(e),a.debug(` exitHandler ${n} done`)}catch(e){a.error(`exitHandler ${n} error: ${e}`)}t++}c.clear()};let u=null;async function p(e){u||(u=d(e)),await u}const f=["beforeExit","uncaughtException","unhandledRejection","SIGHUP","SIGINT","SIGQUIT","SIGILL","SIGTRAP","SIGABRT","SIGBUS","SIGFPE","SIGUSR1","SIGSEGV","SIGUSR2","SIGTERM"];process.setMaxListeners(process.getMaxListeners()+f.length),f.forEach((e=>process.once(e,(async e=>{e instanceof Error?a.error(`Exit on error: ${e.stack||e.message}`):a.debug(`Exit on signal: ${e}`),await p(e),process.exit(0)}))))},200:e=>{e.exports=require("child_process")},251:e=>{e.exports=require("word-wrap")},423:e=>{e.exports=require("change-case")},618:e=>{e.exports=require("convict-format-with-validator")},670:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.startThrottle=async function(e){if("linux"!==a.default.platform())throw new Error("Throttle option is only supported on Linux");try{d=s.default.parse(e),c.debug("Starting throttle with config:",d),await g(),await async function(){if(!d||!d.length)return;let e=d[0].device;if(e)try{await(0,l.checkNetworkInterface)(e)}catch(t){c.warn(`Network interface ${e} not found, using default.`),e=""}e||(e=await(0,l.getDefaultNetworkInterface)());await(0,l.runShellCommand)(`set -e;\n\nsudo -n modprobe ifb || true;\nsudo -n ip link add ifb0 type ifb || true;\nsudo -n ip link set dev ifb0 up;\n\nsudo -n tc qdisc add dev ${e} root handle 1: htb default 1;\nsudo -n tc class add dev ${e} parent 1: classid 1:1 htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ifb0 root handle 1: htb default 1;\nsudo -n tc class add dev ifb0 parent 1: classid 1:1 htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ${e} ingress handle ffff: || true;\nsudo -n tc filter add dev ${e} parent ffff: protocol ip u32 match u32 0 0 action connmark action mirred egress redirect dev ifb0 flowid 1:1;\n`,!0);let t=0;for(const r of d)r.up&&await $(r,"up",e,t,r.protocol,r.match),r.down&&await $(r,"down","ifb0",t,r.protocol,r.match),r.capture&&p.set(t,w(t,r.capture,r.protocol)),t++}()}catch(t){throw c.error(`startThrottle "${e}" error: ${t.stack}`),await m(),t}},t.stopThrottle=m,t.getSessionThrottleIndex=function(e){if(!d)return-1;for(const[t,r]of d.entries())if(void 0!==r.sessions&&""!==r.sessions)try{if(r.sessions.includes("-")){const[n,o]=r.sessions.split("-").map(Number);if(e>=n&&e<=o)return t}else if(r.sessions.includes(",")){if(r.sessions.split(",").map(Number).includes(e))return t}else if(e===Number(r.sessions))return t}catch(t){c.error(`getSessionThrottleId sessionId=${e} error: ${t.stack}`)}return-1},t.getSessionThrottleValues=function(e,t){if(e<0)return{};return f[t].get(e)||{}},t.throttleLauncher=async function(e,t){if(c.debug(`throttleLauncher executablePath=${e} index=${t}`),!d||t<0)return e;const r=d[t],n=t+1,o=`/tmp/throttler-launcher-${t}`,s=`throttler${t}`,a=`${r.protocol?`-p ${r.protocol}`:""}${r.skipSourcePorts?` -m multiport ! --sports ${r.skipSourcePorts}`:""}${r.skipDestinationPorts?` -m multiport ! --dports ${r.skipDestinationPorts}`:""}${r.filter?` ${r.filter}`:""}`;return await i.default.promises.writeFile(o,`#!/bin/bash\ngetent group ${s} >/dev/null || sudo -n addgroup --system ${s}\nsudo -n adduser $USER ${s} --quiet\n\nrule=$(sudo -n iptables -t mangle -L OUTPUT --line-numbers | grep "owner GID match ${s}" | awk '{print $1}')\nif [ -n "$rule" ]; then\n sudo -n iptables -t mangle -R OUTPUT \${rule} ${a} -m owner --gid-owner ${s} -j MARK --set-mark ${n} \nelse\n sudo -n iptables -t mangle -I OUTPUT 1 ${a} -m owner --gid-owner ${s} -j MARK --set-mark ${n}\nfi\n\nsudo -n iptables -t mangle -L PREROUTING | grep -q "CONNMARK restore" || sudo -n iptables -t mangle -I PREROUTING 1 -j CONNMARK --restore-mark\nsudo -n iptables -t mangle -L POSTROUTING | grep -q "CONNMARK save" || sudo -n iptables -t mangle -I POSTROUTING 1 -j CONNMARK --save-mark\n\nfunction stop() {\n echo "Stopping throttler"\n}\ntrap stop SIGINT SIGTERM\n\necho "running: ${e} $@"\nexec newgrp ${s} <<EOF\n${e} $@\nEOF`),await i.default.promises.chmod(o,493),o};const o=r(200),i=n(r(896)),s=n(r(865)),a=n(r(857)),l=r(185),c=(0,l.logger)("throttler:throttle");let d=null;const u=new Set,p=new Map,f={up:new Map,down:new Map};async function g(){await Promise.allSettled([...p.values()].map((e=>e()))),p.clear(),u.forEach((e=>clearTimeout(e))),u.clear(),f.up.clear(),f.down.clear();let e=d?.length?d[0].device:"";e||(e=await(0,l.getDefaultNetworkInterface)()),await(0,l.runShellCommand)(`sudo -n tc qdisc del dev ${e} root || true;\nsudo -n tc class del dev ${e} || true;\nsudo -n tc filter del dev ${e} || true;\nsudo -n tc qdisc del dev ${e} ingress || true;\n\nsudo -n tc qdisc del dev ifb0 root || true;\nsudo -n tc class del dev ifb0 root || true;\nsudo -n tc filter del dev ifb0 root || true;\n`),await async function(){if(!d?.length)return;c.debug(`cleanupRules (${d.length})`);try{await(0,l.runShellCommand)(`for i in $(seq 0 ${d.length}); do\n rule=$(sudo -n iptables -t mangle -L OUTPUT --line-numbers | grep "owner GID match throttler\${i}" | awk '{print $1}');\n if [ -n "$rule" ]; then\n sudo -n iptables -t mangle -D OUTPUT \${rule};\n fi;\ndone;`)}catch(e){c.error(`cleanupRules error: ${e.stack}`)}}()}function h(e,t,r=1500){return Math.ceil(1.5*e*1e3/8*(t/1e3)/r)}async function $(e,t,r,n,o,i){let s=e[t];if(s){c.info(`applyRules device=${r} index=${n} protocol=${o} match=${i} ${JSON.stringify(s)}`),Array.isArray(s)||(s=[s]),s.sort(((e,t)=>(e.at||0)-(t.at||0)));for(const[e,a]of s.entries()){const{rate:s,delay:d,delayJitter:p,delayJitterCorrelation:g,delayDistribution:$,reorder:m,reorderCorrelation:w,reorderGap:b,loss:v,lossBurst:I,queue:y,at:x}=a,S=y??h(s||0,d||0),k=n+1,P=n+2;if(0===e){const e=[`'meta(nf_mark eq ${k})'`];"udp"===o?e.push("'cmp(u8 at 9 layer network eq 0x11)'"):"tcp"===o&&e.push("'cmp(u8 at 9 layer network eq 0x6)'"),i&&e.push(i);const t=`set -e;\n\nsudo -n tc class add dev ${r} parent 1: classid 1:${P} htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ${r} parent 1:${P} handle ${P}: netem; \nsudo -n tc filter add dev ${r} parent 1: protocol ip basic match ${e.join(" and ")} flowid 1:${P};\n`;try{await(0,l.runShellCommand)(t,!0)}catch(e){throw c.error(`error running "${t}": ${e.stack}`),e}}const T=setTimeout((async()=>{let e="";if(s&&s>0&&(e+=` rate ${s}kbit`),S&&S>0&&(e+=` limit ${S}`),d&&d>0&&(e+=` delay ${d}ms`,p&&p>0&&(e+=` ${p}ms`,g&&g>0&&(e+=` ${g}`)),$&&(e+=` distribution ${$}`)),v&&v>0)if(I&&I>0){const t=100*v/(I*(100-v)),r=100/I;e+=` loss gemodel ${(0,l.toPrecision)(t,2)} ${(0,l.toPrecision)(r,2)}`}else e+=` loss ${(0,l.toPrecision)(v,2)}%`;m&&m>0&&(e+=` reorder ${(0,l.toPrecision)(m,2)}%`,w&&w>0&&(e+=` ${(0,l.toPrecision)(w,2)}`),b&&b>0&&(e+=` gap ${b}`)),c.info(`applying rules on ${r} (${k}): ${e}`);const o=`sudo -n tc qdisc change dev ${r} parent 1:${P} handle ${P}: netem ${e}`;try{u.delete(T),await(0,l.runShellCommand)(o),f[t].set(n,{rate:s?1e3*s:void 0,delay:d||void 0,loss:v||void 0,queue:S||void 0})}catch(e){c.error(`error running "${o}": ${e.stack}`)}}),1e3*(x||0));u.add(T)}}}async function m(){if("linux"!==a.default.platform())throw new Error("Throttle option is only supported on Linux");try{c.debug("Stopping throttle"),await g(),c.debug("Stopping throttle done"),d=null}catch(e){c.error(`Stop throttle error: ${e.stack}`)}}function w(e,t,r){const n=e+1;c.info(`Starting capture ${t}`);const i=`#!/bin/bash\nsudo -n iptables -L INPUT | grep -q "nflog-group ${n}" || sudo -n iptables -I INPUT 1 ${r?`-p ${r}`:""} -m connmark --mark ${n} -j NFLOG --nflog-group ${n}\nsudo -n iptables -L OUTPUT | grep -q "nflog-group ${n}" || sudo -n iptables -I OUTPUT 1 ${r?`-p ${r}`:""} -m connmark --mark ${n} -j NFLOG --nflog-group ${n}\nexec dumpcap -q -i nflog:${n} -w ${t}\n`,s=(0,o.spawn)(i,{shell:!0,stdio:["ignore","ignore","pipe"],detached:!0});let a="";s.stderr.on("data",(e=>{a+=e})),s.on("error",(e=>{c.error(`Error running command capturePackets ${e}: ${a}`)})),s.once("exit",(e=>{e?c.error(`capturePackets exited with code ${e}: ${a}`):c.info("capturePackets exited")}));return async()=>{c.info(`Stopping capture ${t}`),s.kill("SIGINT"),await(0,l.runShellCommand)(`#!/bin/bash\nsudo -n iptables -D INPUT ${r?`-p ${r}`:""} -m connmark --mark ${n} -j NFLOG --nflog-group ${n}\nsudo -n iptables -D OUTPUT ${r?`-p ${r}`:""} -m connmark --mark ${n} -j NFLOG --nflog-group ${n}\n`)}}},857:e=>{e.exports=require("os")},859:function(e,t,r){e=r.nmd(e);var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=r(423),i=r(200),s=n(r(896)),a=n(r(865)),l=n(r(251)),c=r(28),d=r(670),u=r(185),p=(0,u.logger)("throttler");r.c[r.s]===e&&async function(){!function(){if(-1!==process.argv.findIndex((e=>0===e.localeCompare("--help")))){const e=(0,c.getConfigDocs)();let t="Params:\n --version\n It shows the package version.\n";Object.entries(e).forEach((([e,r])=>{t+=` --${(0,o.paramCase)(e)}\n${(0,l.default)(r.doc,{width:72,indent:" "})}\n Default: ${r.default}\n`})),console.log(t),process.exit(0)}else if(-1!==process.argv.findIndex((e=>0===e.localeCompare("--version")))){const e=a.default.parse(s.default.readFileSync((0,u.resolvePackagePath)("package.json")).toString()).version;console.log(e),process.exit(0)}}();const e=(0,c.loadConfig)(process.argv[2]),t=new Set;await(0,d.startThrottle)(e.throttleConfig);const r=async()=>{p.info("Stopping...");for(const e of t){const t=await(0,u.getProcessChildren)(e);p.debug(`Killing process ${e} and children: ${t}`);try{process.kill(e,"SIGKILL")}catch(t){p.debug(`Error killing process ${e}: ${t.stack}`)}for(const e of t)try{process.kill(e,"SIGKILL")}catch(t){p.debug(`Error killing child process ${e}: ${t.stack}`)}}await(0,d.stopThrottle)(),process.exit(0)};(0,u.registerExitHandler)((()=>r()));const n=e.commandConfig?a.default.parse(e.commandConfig):[];for(const e of n){const{session:r,command:n}=e,o=n.split(" ")[0],s=(0,d.getSessionThrottleIndex)(r||0),a=await(0,d.throttleLauncher)(n,s);try{const e=(0,i.spawn)(a,{shell:!1,stdio:["ignore","pipe","pipe"],detached:!1});e.pid&&t.add(e.pid),e.stdout.on("data",(e=>{p.info(`[${o}][stdout]`,e.toString().trim())})),e.stderr.on("data",(e=>{p.info(`[${o}][stderr]`,e.toString().trim())})),e.on("error",(e=>{e.message.startsWith("The operation was aborted")||p.error(`Error running command "${n}": ${e.stack}`)})),e.once("exit",(r=>{p.info(`Command "${n}" exited with code: ${r||0}`),e.pid&&t.delete(e.pid)}))}catch(e){p.error(`Error running command "${n}": ${e.stack}`)}}e.runDuration>0&&setTimeout(r,1e3*e.runDuration),console.log("Press [q] to stop the throttler"),process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("data",(async e=>{if(p.debug("[stdin]",e[0]),e[0]==="q".charCodeAt(0))try{await r()}catch(e){p.error(`stop error: ${e.stack}`),process.exit(1)}else console.log("Press [q] to stop the throttler")}))}().catch((e=>{console.error(e),process.exit(-1)}))},865:e=>{e.exports=require("json5")},896:e=>{e.exports=require("fs")},928:e=>{e.exports=require("path")},940:e=>{e.exports=require("debug-level")},950:e=>{e.exports=require("convict")}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={id:n,loaded:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.loaded=!0,i.exports}r.c=t,r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e);r(r.s=859)})();
|
|
2
|
+
(()=>{"use strict";var e={28:function(e,t,r){var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(n=function(e){return n=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[t.length]=r);return t},n(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r=n(e),s=0;s<r.length;s++)"default"!==r[s]&&o(t,e,r[s]);return i(t,e),t});Object.defineProperty(t,"__esModule",{value:!0}),t.getConfigDocs=function(){return g({},null,p.getSchema())},t.loadConfig=function(e,t){e&&(0,c.existsSync)(e)?(d.debug(`Loading config from ${e}`),p.loadFile(e)):t?(d.debug("Loading config from values."),p.load(t)):(d.debug("Using default values."),p.load({}));p.validate({allowed:"strict"});const r=p.getProperties();return d.debug("Using config:",r),r};const a=s(r(950)),l=r(618),c=r(896),d=(0,r(185).logger)("throttler:config"),u={name:"float",coerce:e=>parseFloat(e),validate:e=>{if(!Number.isFinite(e))throw new Error(`Invalid float: ${e}`)}},f={name:"index",coerce:e=>e,validate:e=>{if("string"==typeof e){if("true"===e||"false"===e||""===e)return;if(-1!==e.indexOf("-"))return void e.split("-").forEach((e=>{if(isNaN(parseInt(e))||!isFinite(parseInt(e)))throw new Error(`Invalid index: ${e}`)}));if(-1!==e.indexOf(","))return void e.split(",").forEach((e=>{if(isNaN(parseInt(e))||!isFinite(parseInt(e)))throw new Error(`Invalid index: ${e}`)}));if(isNaN(parseInt(e))||!isFinite(parseInt(e)))throw new Error(`Invalid index: ${e}`)}else if("number"==typeof e||"boolean"==typeof e)return;throw new Error(`Invalid index: ${e}`)}};(0,a.addFormats)({ipaddress:l.ipaddress,url:l.url,float:u,index:f});const p=(0,a.default)({runDuration:{doc:"If greater than 0, the test will stop after the provided number of seconds.",format:"nat",default:0,env:"RUN_DURATION",arg:"run-duration"},throttleConfig:{doc:"A JSON5 string with a valid network throttling configuration. Example: \n ```javascript\n [{\n sessions: '0-1',\n device: 'eth0',\n protocol: 'udp',\n capture: 'capture.pcap',\n up: {\n rate: 1000,\n delay: 50,\n loss: 5,\n queue: 10,\n },\n down: [\n { rate: 2000, delay: 50, loss: 2, queue: 20 },\n { rate: 1000, delay: 50, loss: 2, queue: 20, at: 60 },\n ]\n }]\n ```\nThe sessions field represents the sessions IDs range that will be affected by the rule, e.g.: \"0-10\", \"2,4\" or simply \"2\". The device, protocol, up, down fields are optional. When device is not set, the default route device will be used. If protocol is specified ('udp' or 'tcp'), only the packets with the specified protocol will be affected by the shaping rules. ",format:String,nullable:!0,default:"",env:"THROTTLE_CONFIG",arg:"throttle-config"},commandConfig:{doc:'The commands configuration.Example: \n ```javascript\n [{\n session: 0,\n command: "firefox https://www.speedtest.net",\n }]\n ```\n',format:String,nullable:!0,default:"",env:"COMMAND_CONFIG",arg:"command-config"}});function g(e,t,r){return r._cvtProperties?(Object.entries(r._cvtProperties).forEach((([r,n])=>{g(e,`${t?`${t}.`:""}${r}`,n)})),e):(t&&(e[t]={doc:r.doc,format:JSON.stringify(r.format,null,2),default:JSON.stringify(r.default,null,2)}),e)}p.getProperties()},185:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.LoggerInterface=t.Log=void 0,t.logger=a,t.resolvePackagePath=function(e){if("__nexe"in process)return e;return s.default.join(s.default.dirname(__filename),e)},t.toPrecision=function(e,t=3){return(Math.round(e*10**t)/10**t).toFixed(t)},t.getDefaultNetworkInterface=async function(){if("linux"!==i.default.platform())return"lo";const{stdout:e}=await c("ip route | awk '/default/ {print $5; exit}' | tr -d ''");return e.trim()},t.checkNetworkInterface=async function(e){if("lo"===e)return;await c(`ip route | grep -q "dev ${e}"`)},t.runShellCommand=c,t.registerExitHandler=function(e){d.add(e)},t.unregisterExitHandler=function(e){d.delete(e)},t.runExitHandlersNow=p,t.getProcessChildren=async function e(t){l.debug(`getProcessChildren pid=${t}`);const r=[];try{const n=await c(`pgrep -P ${t}`);for(const t of n.stdout.trim().split("\n").map(Number)){r.push(t);try{const n=await e(t);for(const e of n)r.push(e)}catch(e){l.debug(`Error getting process ${t} children: ${e.message}`)}}}catch(e){l.debug(`Error getting process ${t} children: ${e.message}`)}return r};const o=r(200),i=(n(r(896)),n(r(857))),s=n(r(928));function a(e,r={}){return new t.Log(e,{splitLine:!1,...r})}t.Log=r(940).Log;t.LoggerInterface=class{name;logInit(e){this.name&&e.unshift(`[${this.name}]`)}debug(...e){this.logInit(e),l.debug(...e)}info(...e){this.logInit(e),l.info(...e)}warn(...e){this.logInit(e),l.warn(...e)}error(...e){this.logInit(e),l.error(...e)}log(...e){this.logInit(e),l.log(...e)}};const l=a("webrtcperf:utils");async function c(e,t=!1){return t&&l.debug(`runShellCommand cmd: ${e}`),new Promise(((r,n)=>{const i=(0,o.spawn)(e,{shell:!0,stdio:["ignore","pipe","pipe"],detached:!0});let s="",a="";i.stdout.on("data",(e=>{s.length>524288&&(s=s.slice(e.length)),s+=e})),i.stderr.on("data",(e=>{a.length>524288&&(a=a.slice(e.length)),a+=e})),i.once("error",(e=>n(e))),i.once("close",(o=>{0!==o?n(new Error(`runShellCommand cmd: ${e} failed with code ${o}: ${a}`)):(t&&l.debug(`runShellCommand cmd: ${e} done`,{stdout:s,stderr:a}),r({stdout:s,stderr:a}))}))}))}const d=new Set;const u=async e=>{let t=0;for(const r of d.values()){const n=`${t+1}/${d.size}`;l.debug(`running exitHandler ${n}`);try{await r(e),l.debug(` exitHandler ${n} done`)}catch(e){l.error(`exitHandler ${n} error: ${e}`)}t++}d.clear()};let f=null;async function p(e){f||(f=u(e)),await f}const g=["beforeExit","uncaughtException","unhandledRejection","SIGHUP","SIGINT","SIGQUIT","SIGILL","SIGTRAP","SIGABRT","SIGBUS","SIGFPE","SIGUSR1","SIGSEGV","SIGUSR2","SIGTERM"];process.setMaxListeners(process.getMaxListeners()+g.length),g.forEach((e=>process.once(e,(async e=>{e instanceof Error?l.error(`Exit on error: ${e.stack||e.message}`):l.debug(`Exit on signal: ${e}`),await p(e),process.exit(0)}))))},200:e=>{e.exports=require("child_process")},251:e=>{e.exports=require("word-wrap")},261:e=>{e.exports=require("events")},423:e=>{e.exports=require("change-case")},618:e=>{e.exports=require("convict-format-with-validator")},670:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.throttleNotifier=void 0,t.startThrottle=async function(e){try{u=a.default.parse(e),d.debug("Starting throttle with config:",u),await $(),await async function(){if(!u||!u.length)return;let e=u[0].device;if(e)try{await(0,c.checkNetworkInterface)(e)}catch(t){d.warn(`Network interface ${e} not found, using default.`),e=""}e||(e=await(0,c.getDefaultNetworkInterface)());await h(`set -e;\n\nsudo -n modprobe ifb || true;\nsudo -n ip link add ifb0 type ifb || true;\nsudo -n ip link set dev ifb0 up;\n\nsudo -n tc qdisc add dev ${e} root handle 1: htb default 1;\nsudo -n tc class add dev ${e} parent 1: classid 1:1 htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ifb0 root handle 1: htb default 1;\nsudo -n tc class add dev ifb0 parent 1: classid 1:1 htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ${e} ingress handle ffff: || true;\nsudo -n tc filter add dev ${e} parent ffff: protocol ip u32 match u32 0 0 action connmark action mirred egress redirect dev ifb0 flowid 1:1;\n`,!0);let t=0;for(const r of u)r.up&&await w(r,"up",e,t,r.protocol,r.match),r.down&&await w(r,"down","ifb0",t,r.protocol,r.match),r.capture&&"linux"===l.default.platform()&&p.set(t,v(t,r.capture,r.protocol)),t++}()}catch(t){throw d.error(`startThrottle "${e}" error: ${t.stack}`),await b(),t}},t.stopThrottle=b,t.getSessionThrottleIndex=function(e){if(!u)return-1;for(const[t,r]of u.entries())if(void 0!==r.sessions&&""!==r.sessions)try{if(r.sessions.includes("-")){const[n,o]=r.sessions.split("-").map(Number);if(e>=n&&e<=o)return t}else if(r.sessions.includes(",")){if(r.sessions.split(",").map(Number).includes(e))return t}else if(e===Number(r.sessions))return t}catch(t){d.error(`getSessionThrottleId sessionId=${e} error: ${t.stack}`)}return-1},t.getSessionThrottleValues=function(e,t){if(e<0)return{};return g[t].get(e)||{}},t.throttleLauncher=async function(e,t){if(d.debug(`throttleLauncher executablePath=${e} index=${t}`),!u||t<0)return e;const r=u[t],n=t+1,o=`/tmp/throttler-launcher-${t}`,i=`throttler${t}`,a=`${r.protocol?`-p ${r.protocol}`:""}${r.skipSourcePorts?` -m multiport ! --sports ${r.skipSourcePorts}`:""}${r.skipDestinationPorts?` -m multiport ! --dports ${r.skipDestinationPorts}`:""}${r.filter?` ${r.filter}`:""}`;return await s.default.promises.writeFile(o,`#!/bin/bash\ngetent group ${i} >/dev/null || sudo -n addgroup --system ${i}\nsudo -n adduser $USER ${i} --quiet\n\nrule=$(sudo -n iptables -t mangle -L OUTPUT --line-numbers | grep "owner GID match ${i}" | awk '{print $1}')\nif [ -n "$rule" ]; then\n sudo -n iptables -t mangle -R OUTPUT \${rule} ${a} -m owner --gid-owner ${i} -j MARK --set-mark ${n} \nelse\n sudo -n iptables -t mangle -I OUTPUT 1 ${a} -m owner --gid-owner ${i} -j MARK --set-mark ${n}\nfi\n\nsudo -n iptables -t mangle -L PREROUTING | grep -q "CONNMARK restore" || sudo -n iptables -t mangle -I PREROUTING 1 -j CONNMARK --restore-mark\nsudo -n iptables -t mangle -L POSTROUTING | grep -q "CONNMARK save" || sudo -n iptables -t mangle -I POSTROUTING 1 -j CONNMARK --save-mark\n\nfunction stop() {\n echo "Stopping throttler"\n}\ntrap stop SIGINT SIGTERM\n\necho "running: ${e} $@"\nexec newgrp ${i} <<EOF\n${e} $@\nEOF`),await s.default.promises.chmod(o,493),o};const o=r(200),i=r(261),s=n(r(896)),a=n(r(865)),l=n(r(857)),c=r(185),d=(0,c.logger)("throttler:throttle");let u=null;const f=new Set,p=new Map,g={up:new Map,down:new Map};async function h(e,t=!1){"linux"===l.default.platform()&&await(0,c.runShellCommand)(e,t)}async function $(){await Promise.allSettled([...p.values()].map((e=>e()))),p.clear(),f.forEach((e=>clearTimeout(e))),f.clear(),g.up.clear(),g.down.clear(),t.throttleNotifier.emit("change");let e=u?.length?u[0].device:"";e||(e=await(0,c.getDefaultNetworkInterface)()),await h(`sudo -n tc qdisc del dev ${e} root || true;\nsudo -n tc class del dev ${e} || true;\nsudo -n tc filter del dev ${e} || true;\nsudo -n tc qdisc del dev ${e} ingress || true;\n\nsudo -n tc qdisc del dev ifb0 root || true;\nsudo -n tc class del dev ifb0 root || true;\nsudo -n tc filter del dev ifb0 root || true;\n`),await async function(){if(!u?.length)return;d.debug(`cleanupRules (${u.length})`);try{await h(`for i in $(seq 0 ${u.length}); do\n rule=$(sudo -n iptables -t mangle -L OUTPUT --line-numbers | grep "owner GID match throttler\${i}" | awk '{print $1}');\n if [ -n "$rule" ]; then\n sudo -n iptables -t mangle -D OUTPUT \${rule};\n fi;\ndone;`)}catch(e){d.error(`cleanupRules error: ${e.stack}`)}}()}function m(e,t,r=1500){return Math.ceil(1.5*e*1e3/8*(t/1e3)/r)}async function w(e,r,n,o,i,s){let a=e[r];if(a){d.info(`applyRules device=${n} index=${o} protocol=${i} match=${s} ${JSON.stringify(a)}`),Array.isArray(a)||(a=[a]),a.sort(((e,t)=>(e.at||0)-(t.at||0)));for(const[e,l]of a.entries()){const{rate:a,delay:u,delayJitter:p,delayJitterCorrelation:$,delayDistribution:w,reorder:b,reorderCorrelation:v,reorderGap:I,loss:y,lossBurst:x,queue:S,at:k}=l,P=S??m(a||0,u||0),N=o+1,T=o+2;if(0===e){const e=[`'meta(nf_mark eq ${N})'`];"udp"===i?e.push("'cmp(u8 at 9 layer network eq 0x11)'"):"tcp"===i&&e.push("'cmp(u8 at 9 layer network eq 0x6)'"),s&&e.push(s);const t=`set -e;\n\nsudo -n tc class add dev ${n} parent 1: classid 1:${T} htb rate 1Gbit ceil 1Gbit;\n\nsudo -n tc qdisc add dev ${n} parent 1:${T} handle ${T}: netem; \nsudo -n tc filter add dev ${n} parent 1: protocol ip basic match ${e.join(" and ")} flowid 1:${T};\n`;try{await h(t,!0)}catch(e){throw d.error(`error running "${t}": ${e.stack}`),e}}const O=setTimeout((async()=>{let e="";if(a&&a>0&&(e+=` rate ${a}kbit`),P&&P>0&&(e+=` limit ${P}`),u&&u>0&&(e+=` delay ${u}ms`,p&&p>0&&(e+=` ${p}ms`,$&&$>0&&(e+=` ${$}`)),w&&(e+=` distribution ${w}`)),y&&y>0)if(x&&x>0){const t=100*y/(x*(100-y)),r=100/x;e+=` loss gemodel ${(0,c.toPrecision)(t,2)} ${(0,c.toPrecision)(r,2)}`}else e+=` loss ${(0,c.toPrecision)(y,2)}%`;b&&b>0&&(e+=` reorder ${(0,c.toPrecision)(b,2)}%`,v&&v>0&&(e+=` ${(0,c.toPrecision)(v,2)}`),I&&I>0&&(e+=` gap ${I}`)),d.info(`applying rules on ${n} (${N}): ${e.trim()}`);const i=`sudo -n tc qdisc change dev ${n} parent 1:${T} handle ${T}: netem ${e}`;try{f.delete(O),await h(i),g[r].set(o,{rate:a?1e3*a:void 0,delay:u||void 0,loss:y||void 0,queue:P||void 0}),t.throttleNotifier.emit("change")}catch(e){d.error(`error running "${i}": ${e.stack}`)}}),1e3*(k||0));f.add(O)}}}async function b(){try{d.debug("Stopping throttle"),await $(),d.debug("Stopping throttle done"),u=null}catch(e){d.error(`Stop throttle error: ${e.stack}`)}}function v(e,t,r){const n=e+1;d.info(`Starting capture ${t}`);const i=`#!/bin/bash\nsudo -n iptables -L INPUT | grep -q "nflog-group ${n}" || sudo -n iptables -I INPUT 1 ${r?`-p ${r}`:""} -m connmark --mark ${n} -j NFLOG --nflog-group ${n}\nsudo -n iptables -L OUTPUT | grep -q "nflog-group ${n}" || sudo -n iptables -I OUTPUT 1 ${r?`-p ${r}`:""} -m connmark --mark ${n} -j NFLOG --nflog-group ${n}\nexec dumpcap -q -i nflog:${n} -w ${t}\n`,s=(0,o.spawn)(i,{shell:!0,stdio:["ignore","ignore","pipe"],detached:!0});let a="";s.stderr.on("data",(e=>{a+=e})),s.on("error",(e=>{d.error(`Error running command capturePackets ${e}: ${a}`)})),s.once("exit",(e=>{e?d.error(`capturePackets exited with code ${e}: ${a}`):d.info("capturePackets exited")}));return async()=>{d.info(`Stopping capture ${t}`),s.kill("SIGINT"),await(0,c.runShellCommand)(`#!/bin/bash\nsudo -n iptables -D INPUT ${r?`-p ${r}`:""} -m connmark --mark ${n} -j NFLOG --nflog-group ${n}\nsudo -n iptables -D OUTPUT ${r?`-p ${r}`:""} -m connmark --mark ${n} -j NFLOG --nflog-group ${n}\n`)}}t.throttleNotifier=new i.EventEmitter},857:e=>{e.exports=require("os")},859:function(e,t,r){e=r.nmd(e);var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=r(423),i=r(200),s=n(r(896)),a=n(r(865)),l=n(r(251)),c=r(28),d=r(670),u=r(185),f=(0,u.logger)("throttler");r.c[r.s]===e&&async function(){!function(){if(-1!==process.argv.findIndex((e=>0===e.localeCompare("--help")))){const e=(0,c.getConfigDocs)();let t="Params:\n --version\n It shows the package version.\n";Object.entries(e).forEach((([e,r])=>{t+=` --${(0,o.paramCase)(e)}\n${(0,l.default)(r.doc,{width:72,indent:" "})}\n Default: ${r.default}\n`})),console.log(t),process.exit(0)}else if(-1!==process.argv.findIndex((e=>0===e.localeCompare("--version")))){const e=a.default.parse(s.default.readFileSync((0,u.resolvePackagePath)("package.json")).toString()).version;console.log(e),process.exit(0)}}();const e=(0,c.loadConfig)(process.argv[2]),t=new Set;await(0,d.startThrottle)(e.throttleConfig);const r=async()=>{f.info("Stopping...");for(const e of t){const t=await(0,u.getProcessChildren)(e);f.debug(`Killing process ${e} and children: ${t}`);try{process.kill(e,"SIGKILL")}catch(t){f.debug(`Error killing process ${e}: ${t.stack}`)}for(const e of t)try{process.kill(e,"SIGKILL")}catch(t){f.debug(`Error killing child process ${e}: ${t.stack}`)}}await(0,d.stopThrottle)(),process.exit(0)};(0,u.registerExitHandler)((()=>r()));const n=e.commandConfig?a.default.parse(e.commandConfig):[];for(const e of n){const{session:r,command:n}=e,o=n.split(" ")[0],s=(0,d.getSessionThrottleIndex)(r||0),a=await(0,d.throttleLauncher)(n,s);try{const e=(0,i.spawn)(a,{shell:!1,stdio:["ignore","pipe","pipe"],detached:!1});e.pid&&t.add(e.pid),e.stdout.on("data",(e=>{f.info(`[${o}][stdout]`,e.toString().trim())})),e.stderr.on("data",(e=>{f.info(`[${o}][stderr]`,e.toString().trim())})),e.on("error",(e=>{e.message.startsWith("The operation was aborted")||f.error(`Error running command "${n}": ${e.stack}`)})),e.once("exit",(r=>{f.info(`Command "${n}" exited with code: ${r||0}`),e.pid&&t.delete(e.pid)}))}catch(e){f.error(`Error running command "${n}": ${e.stack}`)}}e.runDuration>0&&setTimeout(r,1e3*e.runDuration),console.log("Press [q] to stop the throttler"),process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("data",(async e=>{if(f.debug("[stdin]",e[0]),e[0]==="q".charCodeAt(0))try{await r()}catch(e){f.error(`stop error: ${e.stack}`),process.exit(1)}else console.log("Press [q] to stop the throttler")}))}().catch((e=>{console.error(e),process.exit(-1)}))},865:e=>{e.exports=require("json5")},896:e=>{e.exports=require("fs")},928:e=>{e.exports=require("path")},940:e=>{e.exports=require("debug-level")},950:e=>{e.exports=require("convict")}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={id:n,loaded:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.loaded=!0,i.exports}r.c=t,r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e);r(r.s=859)})();
|