@monoes/monobrowse 1.0.24 → 1.0.26
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/dist/src/__tests__/browser-launch.test.d.ts +3 -2
- package/dist/src/__tests__/browser-launch.test.d.ts.map +1 -1
- package/dist/src/__tests__/browser-launch.test.js +208 -13
- package/dist/src/__tests__/browser-launch.test.js.map +1 -1
- package/dist/src/__tests__/launch-close-settle.test.d.ts +6 -0
- package/dist/src/__tests__/launch-close-settle.test.d.ts.map +1 -1
- package/dist/src/__tests__/launch-close-settle.test.js +29 -8
- package/dist/src/__tests__/launch-close-settle.test.js.map +1 -1
- package/dist/src/browser/browser.d.ts.map +1 -1
- package/dist/src/browser/browser.js +120 -44
- package/dist/src/browser/browser.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/__tests__/browser-launch.test.ts +220 -13
- package/src/__tests__/launch-close-settle.test.ts +32 -10
- package/src/browser/browser.ts +126 -47
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* launchBrowser would ever exec a browser binary, so these run fast and
|
|
6
6
|
* don't depend on Chrome being installed in CI.
|
|
7
7
|
*
|
|
8
|
-
* Fixed port range (
|
|
9
|
-
* services
|
|
8
|
+
* Fixed port range (23460-23489) chosen to avoid colliding with real
|
|
9
|
+
* services and with reap-idle-browser.test.ts's 23490-23499, which runs in a
|
|
10
|
+
* parallel worker; each test binds/tears down its own listeners.
|
|
10
11
|
*/
|
|
11
12
|
export {};
|
|
12
13
|
//# sourceMappingURL=browser-launch.test.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-launch.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browser-launch.test.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"browser-launch.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browser-launch.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -5,15 +5,17 @@
|
|
|
5
5
|
* launchBrowser would ever exec a browser binary, so these run fast and
|
|
6
6
|
* don't depend on Chrome being installed in CI.
|
|
7
7
|
*
|
|
8
|
-
* Fixed port range (
|
|
9
|
-
* services
|
|
8
|
+
* Fixed port range (23460-23489) chosen to avoid colliding with real
|
|
9
|
+
* services and with reap-idle-browser.test.ts's 23490-23499, which runs in a
|
|
10
|
+
* parallel worker; each test binds/tears down its own listeners.
|
|
10
11
|
*/
|
|
11
|
-
import {
|
|
12
|
+
import { execFileSync } from 'node:child_process';
|
|
13
|
+
import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
12
14
|
import { createServer as createHttpServer } from 'node:http';
|
|
13
15
|
import { createServer as createTcpServer } from 'node:net';
|
|
14
16
|
import { tmpdir } from 'node:os';
|
|
15
17
|
import { join } from 'node:path';
|
|
16
|
-
import { afterEach, describe, expect, it } from 'vitest';
|
|
18
|
+
import { afterAll, afterEach, describe, expect, it } from 'vitest';
|
|
17
19
|
import { getLaunchedPid, getLaunchedUserDataDir, launchBrowser } from '../browser/browser.js';
|
|
18
20
|
const BASE = 23470;
|
|
19
21
|
let servers = [];
|
|
@@ -28,6 +30,69 @@ afterEach(async () => {
|
|
|
28
30
|
await Promise.all(servers.map((s) => new Promise((resolve) => s.close(() => resolve()))));
|
|
29
31
|
servers = [];
|
|
30
32
|
}, 5000);
|
|
33
|
+
// Every fake-chrome.cjs below is spawned by launchBrowser (detached, so a
|
|
34
|
+
// test cannot reach it through a ChildProcess). Its temp dir is on its
|
|
35
|
+
// command line, so each dir is recorded here and afterAll kills whatever is
|
|
36
|
+
// still running out of one — a fixture must never outlive this file (one
|
|
37
|
+
// that did kept 127.0.0.1:23480 bound and failed later runs with
|
|
38
|
+
// EADDRINUSE).
|
|
39
|
+
const fixtureDirs = [];
|
|
40
|
+
function fixtureDir(prefix) {
|
|
41
|
+
const dir = mkdtempSync(join(tmpdir(), prefix));
|
|
42
|
+
fixtureDirs.push(dir);
|
|
43
|
+
return dir;
|
|
44
|
+
}
|
|
45
|
+
/** Pids of processes whose command line mentions `dir`. */
|
|
46
|
+
function processesIn(dir) {
|
|
47
|
+
try {
|
|
48
|
+
return execFileSync('pgrep', ['-f', dir], { encoding: 'utf8' })
|
|
49
|
+
.trim()
|
|
50
|
+
.split('\n')
|
|
51
|
+
.filter(Boolean);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return []; // pgrep exits 1 when nothing matches
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
afterAll(async () => {
|
|
58
|
+
const leaked = [];
|
|
59
|
+
for (const dir of fixtureDirs.splice(0)) {
|
|
60
|
+
// A fixture a test just SIGKILLed can take a moment to disappear.
|
|
61
|
+
let pids = processesIn(dir);
|
|
62
|
+
for (let i = 0; i < 20 && pids.length > 0; i++) {
|
|
63
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
64
|
+
pids = processesIn(dir);
|
|
65
|
+
}
|
|
66
|
+
leaked.push(...pids);
|
|
67
|
+
for (const pid of pids) {
|
|
68
|
+
try {
|
|
69
|
+
process.kill(Number(pid), 'SIGKILL');
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
/* already gone */
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
rmSync(dir, { recursive: true, force: true });
|
|
76
|
+
}
|
|
77
|
+
// Swept above either way; failing here names a test whose own cleanup
|
|
78
|
+
// missed a fixture.
|
|
79
|
+
expect(leaked, 'fake-chrome fixtures outlived their test').toEqual([]);
|
|
80
|
+
});
|
|
81
|
+
// Prepended to every fake-chrome script: exit once the process that launched
|
|
82
|
+
// it is gone (launchBrowser spawns detached, so a vitest worker that dies or
|
|
83
|
+
// is killed mid-test would otherwise leave the fixture — and its port —
|
|
84
|
+
// behind, reparented to init), and never live longer than a minute anyway.
|
|
85
|
+
const FIXTURE_WATCHDOG = `const parent = process.ppid;
|
|
86
|
+
setInterval(() => {
|
|
87
|
+
try {
|
|
88
|
+
if (process.ppid !== parent) process.exit(0);
|
|
89
|
+
process.kill(parent, 0);
|
|
90
|
+
} catch {
|
|
91
|
+
process.exit(0);
|
|
92
|
+
}
|
|
93
|
+
}, 1000).unref();
|
|
94
|
+
setTimeout(() => process.exit(0), 60000).unref();
|
|
95
|
+
`;
|
|
31
96
|
/** Bind a bare TCP listener — accepts connections but speaks no HTTP/CDP. */
|
|
32
97
|
function occupyNonChrome(port) {
|
|
33
98
|
return new Promise((resolve, reject) => {
|
|
@@ -105,7 +170,7 @@ describe('launchBrowser — port scan/attach decisions', () => {
|
|
|
105
170
|
// --remote-debugging-port=0, it binds a kernel-assigned port and only then
|
|
106
171
|
// writes that port to <user-data-dir>/DevToolsActivePort.
|
|
107
172
|
const FAKE_CHROME = `#!/usr/bin/env node
|
|
108
|
-
const { createServer } = require('node:http');
|
|
173
|
+
${FIXTURE_WATCHDOG}const { createServer } = require('node:http');
|
|
109
174
|
const { writeFileSync } = require('node:fs');
|
|
110
175
|
const { join } = require('node:path');
|
|
111
176
|
const dir = process.argv.find((a) => a.startsWith('--user-data-dir=')).slice('--user-data-dir='.length);
|
|
@@ -118,9 +183,29 @@ setTimeout(() => server.listen(0, '127.0.0.1', () => {
|
|
|
118
183
|
writeFileSync(join(dir, 'DevToolsActivePort'), server.address().port + '\\n/devtools/browser/fake');
|
|
119
184
|
}), 600);
|
|
120
185
|
`;
|
|
186
|
+
// Like FAKE_CHROME, but its first /json/version answer takes longer than
|
|
187
|
+
// launchBrowser's 1 s identity timeout, while /json/list answers at once.
|
|
188
|
+
const FAKE_CHROME_SLOW_IDENTITY = `#!/usr/bin/env node
|
|
189
|
+
${FIXTURE_WATCHDOG}const { createServer } = require('node:http');
|
|
190
|
+
const { writeFileSync } = require('node:fs');
|
|
191
|
+
const { join } = require('node:path');
|
|
192
|
+
const dir = process.argv.find((a) => a.startsWith('--user-data-dir=')).slice('--user-data-dir='.length);
|
|
193
|
+
let versionCalls = 0;
|
|
194
|
+
const server = createServer((req, res) => {
|
|
195
|
+
const send = () => {
|
|
196
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
197
|
+
res.end(req.url === '/json/version' ? JSON.stringify({ Browser: 'Chrome/999.0.0.0' }) : '[]');
|
|
198
|
+
};
|
|
199
|
+
if (req.url === '/json/version' && versionCalls++ === 0) setTimeout(send, 1500);
|
|
200
|
+
else send();
|
|
201
|
+
});
|
|
202
|
+
server.listen(0, '127.0.0.1', () => {
|
|
203
|
+
writeFileSync(join(dir, 'DevToolsActivePort'), server.address().port + '\\n/devtools/browser/fake');
|
|
204
|
+
});
|
|
205
|
+
`;
|
|
121
206
|
describe.skipIf(process.platform === 'win32')('launchBrowser — port 0 (Chrome picks the port)', () => {
|
|
122
207
|
it('returns the port its own Chrome reported, never another CDP endpoint', async () => {
|
|
123
|
-
const dir =
|
|
208
|
+
const dir = fixtureDir('monobrowse-port0-');
|
|
124
209
|
const exe = join(dir, 'fake-chrome.cjs');
|
|
125
210
|
writeFileSync(exe, FAKE_CHROME);
|
|
126
211
|
chmodSync(exe, 0o755);
|
|
@@ -151,6 +236,45 @@ describe.skipIf(process.platform === 'win32')('launchBrowser — port 0 (Chrome
|
|
|
151
236
|
rmSync(dir, { recursive: true, force: true });
|
|
152
237
|
}
|
|
153
238
|
});
|
|
239
|
+
it('does not reject its own Chrome when /json/version answers slowly (loaded machine)', async () => {
|
|
240
|
+
// On a busy CI runner Chrome's DevTools server can take longer than the
|
|
241
|
+
// identity check's timeout to answer /json/version right after it
|
|
242
|
+
// starts listening, while /json/list (no timeout) got through. That
|
|
243
|
+
// timeout used to be read as "not Chrome" and failed the launch with
|
|
244
|
+
// "occupied by a CDP-speaking process that does not identify as
|
|
245
|
+
// Chrome/Chromium" — for the very Chrome it had just started.
|
|
246
|
+
const dir = fixtureDir('monobrowse-slowid-');
|
|
247
|
+
const exe = join(dir, 'fake-chrome.cjs');
|
|
248
|
+
writeFileSync(exe, FAKE_CHROME_SLOW_IDENTITY);
|
|
249
|
+
chmodSync(exe, 0o755);
|
|
250
|
+
const profile = join(dir, 'profile');
|
|
251
|
+
mkdirSync(profile);
|
|
252
|
+
let port;
|
|
253
|
+
try {
|
|
254
|
+
port = await launchBrowser({ port: 0, userDataDir: profile, executablePath: exe });
|
|
255
|
+
expect(port).toBeGreaterThan(0);
|
|
256
|
+
expect(getLaunchedPid(port)).toBeTypeOf('number');
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
const pid = port === undefined ? undefined : getLaunchedPid(port);
|
|
260
|
+
if (pid)
|
|
261
|
+
process.kill(pid, 'SIGKILL');
|
|
262
|
+
}
|
|
263
|
+
}, 15000);
|
|
264
|
+
it('still refuses a CDP endpoint that answers as a non-Chrome browser', async () => {
|
|
265
|
+
const dir = fixtureDir('monobrowse-notchrome-');
|
|
266
|
+
const exe = join(dir, 'fake-chrome.cjs');
|
|
267
|
+
writeFileSync(exe, FAKE_CHROME.replace('Chrome/999.0.0.0', 'Firefox/1.0'));
|
|
268
|
+
chmodSync(exe, 0o755);
|
|
269
|
+
const profile = join(dir, 'profile');
|
|
270
|
+
mkdirSync(profile);
|
|
271
|
+
await expect(launchBrowser({ port: 0, userDataDir: profile, executablePath: exe })).rejects.toThrow(/does not identify as Chrome/);
|
|
272
|
+
// Refused, so never tracked — launchBrowser must stop it itself.
|
|
273
|
+
for (let i = 0; i < 20 && processesIn(dir).length > 0; i++) {
|
|
274
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
275
|
+
}
|
|
276
|
+
expect(processesIn(dir)).toEqual([]);
|
|
277
|
+
}, 15000);
|
|
154
278
|
it('refuses port 0 without a dedicated userDataDir', async () => {
|
|
155
279
|
await expect(launchBrowser({ port: 0 })).rejects.toThrow(/requires a dedicated userDataDir/);
|
|
156
280
|
});
|
|
@@ -161,30 +285,38 @@ describe.skipIf(process.platform === 'win32')('launchBrowser — port 0 (Chrome
|
|
|
161
285
|
// port too — see cli/commands.ts's `port` option default). If the bind
|
|
162
286
|
// fails (another process already has it), it exits the way real Chrome does
|
|
163
287
|
// when a concurrent launch wins the same "free-looking" port: before its
|
|
164
|
-
// CDP endpoint ever opens.
|
|
288
|
+
// CDP endpoint ever opens. Like real Chrome on a fixed port, it writes no
|
|
289
|
+
// DevToolsActivePort; it announces its browser websocket on stderr, with an
|
|
290
|
+
// id unique to this process that /json/version reports too.
|
|
165
291
|
const FAKE_CHROME_FIXED_PORT = `#!/usr/bin/env node
|
|
166
|
-
const { createServer } = require('node:http');
|
|
292
|
+
${FIXTURE_WATCHDOG}const { createServer } = require('node:http');
|
|
293
|
+
const { randomUUID } = require('node:crypto');
|
|
167
294
|
const { writeFileSync, mkdirSync } = require('node:fs');
|
|
168
295
|
const { join } = require('node:path');
|
|
169
296
|
const port = Number(
|
|
170
297
|
process.argv.find((a) => a.startsWith('--remote-debugging-port=')).slice('--remote-debugging-port='.length),
|
|
171
298
|
);
|
|
172
299
|
const dir = process.argv.find((a) => a.startsWith('--user-data-dir=')).slice('--user-data-dir='.length);
|
|
300
|
+
const ws = 'ws://127.0.0.1:' + port + '/devtools/browser/' + randomUUID();
|
|
173
301
|
const server = createServer((req, res) => {
|
|
174
302
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
175
|
-
res.end(
|
|
303
|
+
res.end(
|
|
304
|
+
req.url === '/json/version'
|
|
305
|
+
? JSON.stringify({ Browser: 'Chrome/999.0.0.0', webSocketDebuggerUrl: ws })
|
|
306
|
+
: '[]',
|
|
307
|
+
);
|
|
176
308
|
});
|
|
177
309
|
server.on('error', () => {
|
|
178
310
|
process.exit(21);
|
|
179
311
|
});
|
|
180
312
|
server.listen(port, '127.0.0.1', () => {
|
|
181
313
|
mkdirSync(dir, { recursive: true });
|
|
182
|
-
|
|
314
|
+
process.stderr.write('\\nDevTools listening on ' + ws + '\\n');
|
|
183
315
|
});
|
|
184
316
|
`;
|
|
185
317
|
describe.skipIf(process.platform === 'win32')('launchBrowser — concurrent launches with no explicit --port (TOCTOU race)', () => {
|
|
186
318
|
it('two concurrent launches racing for the same default port both succeed, on different ports and profiles', async () => {
|
|
187
|
-
const dir =
|
|
319
|
+
const dir = fixtureDir('monobrowse-concurrent-');
|
|
188
320
|
const exe = join(dir, 'fake-chrome.cjs');
|
|
189
321
|
writeFileSync(exe, FAKE_CHROME_FIXED_PORT);
|
|
190
322
|
chmodSync(exe, 0o755);
|
|
@@ -193,12 +325,17 @@ describe.skipIf(process.platform === 'win32')('launchBrowser — concurrent laun
|
|
|
193
325
|
// do, since the CLI's `port` option always defaults to the same value
|
|
194
326
|
// whether or not the user passed it (cli/commands.ts:288).
|
|
195
327
|
const port = BASE + 10;
|
|
328
|
+
// allSettled, not all: when one launch rejects, the other's fixture is
|
|
329
|
+
// still running and must be killed too — Promise.all dropped its port
|
|
330
|
+
// and leaked it.
|
|
331
|
+
let results = [];
|
|
196
332
|
let ports = [];
|
|
197
333
|
try {
|
|
198
|
-
|
|
334
|
+
results = await Promise.allSettled([
|
|
199
335
|
launchBrowser({ port, executablePath: exe, launchTimeoutMs: 5000 }),
|
|
200
336
|
launchBrowser({ port, executablePath: exe, launchTimeoutMs: 5000 }),
|
|
201
337
|
]);
|
|
338
|
+
ports = results.flatMap((r) => (r.status === 'fulfilled' ? [r.value] : []));
|
|
202
339
|
}
|
|
203
340
|
finally {
|
|
204
341
|
for (const p of ports) {
|
|
@@ -212,8 +349,10 @@ describe.skipIf(process.platform === 'win32')('launchBrowser — concurrent laun
|
|
|
212
349
|
}
|
|
213
350
|
}
|
|
214
351
|
}
|
|
215
|
-
rmSync(dir, { recursive: true, force: true });
|
|
216
352
|
}
|
|
353
|
+
for (const r of results)
|
|
354
|
+
if (r.status === 'rejected')
|
|
355
|
+
throw r.reason;
|
|
217
356
|
expect(ports).toHaveLength(2);
|
|
218
357
|
// The old probe-then-launch race let both calls observe the same
|
|
219
358
|
// candidate as free and spawn Chrome on it — one bind wins, the
|
|
@@ -228,5 +367,61 @@ describe.skipIf(process.platform === 'win32')('launchBrowser — concurrent laun
|
|
|
228
367
|
expect(dirs[0]).toBeTruthy();
|
|
229
368
|
expect(dirs[1]).toBeTruthy();
|
|
230
369
|
}, 15000);
|
|
370
|
+
it('a launch whose Chrome is still booting does not adopt a concurrent launch that took the port', async () => {
|
|
371
|
+
// The loaded-machine shape of the race above, made deterministic: both
|
|
372
|
+
// launches probe the port as free, the "fast" Chrome binds it first,
|
|
373
|
+
// and the "slow" one is still starting when its poll finds a Chrome
|
|
374
|
+
// answering there. That Chrome is not the slow launch's own, so it
|
|
375
|
+
// must not be returned — nor may the slow launch record its own pid
|
|
376
|
+
// (about to exit on the lost bind) under the fast launch's port.
|
|
377
|
+
const dir = fixtureDir('monobrowse-adopt-');
|
|
378
|
+
const fast = join(dir, 'fast-chrome.cjs');
|
|
379
|
+
const slow = join(dir, 'slow-chrome.cjs');
|
|
380
|
+
writeFileSync(fast, fixedPortChrome(500));
|
|
381
|
+
writeFileSync(slow, fixedPortChrome(2500));
|
|
382
|
+
chmodSync(fast, 0o755);
|
|
383
|
+
chmodSync(slow, 0o755);
|
|
384
|
+
// Below BASE: this file's fixed ports, clear of the kernel's
|
|
385
|
+
// ephemeral range, where another test's listen(0) server can land on
|
|
386
|
+
// the candidate the slow launch scans on to.
|
|
387
|
+
const port = BASE - 10;
|
|
388
|
+
let results = [];
|
|
389
|
+
try {
|
|
390
|
+
results = await Promise.allSettled([
|
|
391
|
+
launchBrowser({ port, executablePath: fast, launchTimeoutMs: 10_000 }),
|
|
392
|
+
launchBrowser({ port, executablePath: slow, launchTimeoutMs: 10_000 }),
|
|
393
|
+
]);
|
|
394
|
+
}
|
|
395
|
+
finally {
|
|
396
|
+
for (const r of results) {
|
|
397
|
+
const pid = r.status === 'fulfilled' ? getLaunchedPid(r.value) : undefined;
|
|
398
|
+
if (pid) {
|
|
399
|
+
try {
|
|
400
|
+
process.kill(pid, 'SIGKILL');
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
/* already gone */
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
const [fastResult, slowResult] = results;
|
|
409
|
+
expect(fastResult).toEqual({ status: 'fulfilled', value: port });
|
|
410
|
+
if (slowResult.status === 'rejected')
|
|
411
|
+
throw slowResult.reason;
|
|
412
|
+
expect(slowResult.value).not.toBe(port);
|
|
413
|
+
// The pid tracked for the port is the Chrome that actually serves it.
|
|
414
|
+
const fastDir = getLaunchedUserDataDir(port);
|
|
415
|
+
expect(fastDir).toBeTruthy();
|
|
416
|
+
expect(getLaunchedPid(port)).toBe(Number(readFileSync(join(fastDir, 'pid'), 'utf8')));
|
|
417
|
+
}, 20_000);
|
|
231
418
|
});
|
|
419
|
+
/** FAKE_CHROME_FIXED_PORT that waits `delayMs` before binding, and records
|
|
420
|
+
* its own pid in its profile dir. */
|
|
421
|
+
function fixedPortChrome(delayMs) {
|
|
422
|
+
return FAKE_CHROME_FIXED_PORT.replace('mkdirSync(dir, { recursive: true });', `mkdirSync(dir, { recursive: true });
|
|
423
|
+
writeFileSync(join(dir, 'pid'), String(process.pid));`)
|
|
424
|
+
.replace("server.listen(port, '127.0.0.1', () => {", "setTimeout(() => server.listen(port, '127.0.0.1', () => {")
|
|
425
|
+
.replace(/\}\);\n$/, `}), ${delayMs});\n`);
|
|
426
|
+
}
|
|
232
427
|
//# sourceMappingURL=browser-launch.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-launch.test.js","sourceRoot":"","sources":["../../../src/__tests__/browser-launch.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"browser-launch.test.js","sourceRoot":"","sources":["../../../src/__tests__/browser-launch.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjG,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAA6B,MAAM,WAAW,CAAC;AACxF,OAAO,EAAE,YAAY,IAAI,eAAe,EAAyC,MAAM,UAAU,CAAC;AAClG,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE9F,MAAM,IAAI,GAAG,KAAK,CAAC;AAEnB,IAAI,OAAO,GAAkC,EAAE,CAAC;AAChD,IAAI,OAAO,GAAa,EAAE,CAAC;AAE3B,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,qEAAqE;IACrE,0EAA0E;IAC1E,yEAAyE;IACzE,KAAK,MAAM,IAAI,IAAI,OAAO;QAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IAC3C,OAAO,GAAG,EAAE,CAAC;IACb,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChG,OAAO,GAAG,EAAE,CAAC;AACf,CAAC,EAAE,IAAI,CAAC,CAAC;AAET,0EAA0E;AAC1E,uEAAuE;AACvE,4EAA4E;AAC5E,yEAAyE;AACzE,iEAAiE;AACjE,eAAe;AACf,MAAM,WAAW,GAAa,EAAE,CAAC;AAEjC,SAAS,UAAU,CAAC,MAAc;IAChC,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,2DAA2D;AAC3D,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;aAC5D,IAAI,EAAE;aACN,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC,CAAC,qCAAqC;IAClD,CAAC;AACH,CAAC;AAED,QAAQ,CAAC,KAAK,IAAI,EAAE;IAClB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,kEAAkE;QAClE,IAAI,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YACzD,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACrB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC;gBACP,kBAAkB;YACpB,CAAC;QACH,CAAC;QACD,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,sEAAsE;IACtE,oBAAoB;IACpB,MAAM,CAAC,MAAM,EAAE,0CAA0C,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC;AAEH,6EAA6E;AAC7E,6EAA6E;AAC7E,wEAAwE;AACxE,2EAA2E;AAC3E,MAAM,gBAAgB,GAAG;;;;;;;;;;CAUxB,CAAC;AAEF,6EAA6E;AAC7E,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,EAAE,EAAE;YACjC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,6CAA6C;QACnE,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;YAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,+EAA+E;AAC/E,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,GAAG,gBAAgB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACtC,IAAI,GAAG,CAAC,GAAG,KAAK,eAAe,EAAE,CAAC;gBAChC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACjD,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;YAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;QACtB,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sFAAsF,EAAE,KAAK,IAAI,EAAE;QACpG,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;QACtB,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,YAAY,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,2DAA2D;QACzF,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACrE,6BAA6B,CAC9B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qFAAqF,EAAE,KAAK,IAAI,EAAE;QACnG,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;QACtB,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,KAAK,IAAI,EAAE;QAC3F,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;QACtB,iEAAiE;QACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;YAAE,MAAM,eAAe,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QAC7D,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACnD,IAAI,MAAM,CAAC,SAAS,IAAI,IAAI,IAAI,GAAG,CAAC,mBAAmB,CAAC,CACzD,CAAC;IACJ,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,mEAAmE;IAE9E,EAAE,CAAC,gGAAgG,EAAE,KAAK,IAAI,EAAE;QAC9G,wEAAwE;QACxE,yEAAyE;QACzE,uEAAuE;QACvE,uEAAuE;QACvE,uEAAuE;QACvE,8CAA8C;QAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;QACtB,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,uCAAuC;QACpE,MAAM,YAAY,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,+DAA+D;QAC7F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;YAAE,MAAM,eAAe,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,iCAAiC;QAC/F,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACnD,IAAI,MAAM,CAAC,SAAS,IAAI,IAAI,IAAI,GAAG,CAAC,mBAAmB,CAAC,CACzD,CAAC;IACJ,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,mEAAmE;AAChF,CAAC,CAAC,CAAC;AAEH,2DAA2D;AAC3D,2EAA2E;AAC3E,0DAA0D;AAC1D,MAAM,WAAW,GAAG;EAClB,gBAAgB;;;;;;;;;;;;CAYjB,CAAC;AAEF,yEAAyE;AACzE,0EAA0E;AAC1E,MAAM,yBAAyB,GAAG;EAChC,gBAAgB;;;;;;;;;;;;;;;;CAgBjB,CAAC;AAEF,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAC3C,gDAAgD,EAChD,GAAG,EAAE;IACH,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,GAAG,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QACzC,aAAa,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAChC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACrC,+DAA+D;QAC/D,gEAAgE;QAChE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,gBAAgB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACtC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACjD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,SAAS,CAAC,OAAO,CAAC,CAAC;QACnB,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,EAAE,GAAG,OAAO,2BAA2B,CAAC,CAAC;QAE1F,IAAI,IAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC;YACnF,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACpD,CAAC;gBAAS,CAAC;YACT,MAAM,GAAG,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAClE,IAAI,GAAG;gBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YACtC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;QACjG,wEAAwE;QACxE,kEAAkE;QAClE,oEAAoE;QACpE,qEAAqE;QACrE,gEAAgE;QAChE,8DAA8D;QAC9D,MAAM,GAAG,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QACzC,aAAa,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAC;QAC9C,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACrC,SAAS,CAAC,OAAO,CAAC,CAAC;QAEnB,IAAI,IAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC;YACnF,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACpD,CAAC;gBAAS,CAAC;YACT,MAAM,GAAG,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAClE,IAAI,GAAG;gBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,EAAE,KAAK,CAAC,CAAC;IAEV,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,GAAG,GAAG,UAAU,CAAC,uBAAuB,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QACzC,aAAa,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC,CAAC;QAC3E,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACrC,SAAS,CAAC,OAAO,CAAC,CAAC;QACnB,MAAM,MAAM,CACV,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,CACtE,CAAC,OAAO,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;QACjD,iEAAiE;QACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3D,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEV,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;AACL,CAAC,CACF,CAAC;AAEF,4EAA4E;AAC5E,6EAA6E;AAC7E,4EAA4E;AAC5E,uEAAuE;AACvE,4EAA4E;AAC5E,yEAAyE;AACzE,0EAA0E;AAC1E,4EAA4E;AAC5E,4DAA4D;AAC5D,MAAM,sBAAsB,GAAG;EAC7B,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;CAwBjB,CAAC;AAEF,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAC3C,2EAA2E,EAC3E,GAAG,EAAE;IACH,EAAE,CAAC,wGAAwG,EAAE,KAAK,IAAI,EAAE;QACtH,MAAM,GAAG,GAAG,UAAU,CAAC,wBAAwB,CAAC,CAAC;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QACzC,aAAa,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;QAC3C,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtB,sEAAsE;QACtE,uEAAuE;QACvE,sEAAsE;QACtE,2DAA2D;QAC3D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QAEvB,uEAAuE;QACvE,sEAAsE;QACtE,iBAAiB;QACjB,IAAI,OAAO,GAAmC,EAAE,CAAC;QACjD,IAAI,KAAK,GAAa,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;gBACjC,aAAa,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;gBACnE,aAAa,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;aACpE,CAAC,CAAC;YACH,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9E,CAAC;gBAAS,CAAC;YACT,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBAC9B,IAAI,GAAG,EAAE,CAAC;oBACR,IAAI,CAAC;wBACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;oBAC/B,CAAC;oBAAC,MAAM,CAAC;wBACP,kBAAkB;oBACpB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU;gBAAE,MAAM,CAAC,CAAC,MAAM,CAAC;QACrE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,iEAAiE;QACjE,gEAAgE;QAChE,mEAAmE;QACnE,6DAA6D;QAC7D,gEAAgE;QAChE,kEAAkE;QAClE,iCAAiC;QACjC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;IAC/B,CAAC,EAAE,KAAK,CAAC,CAAC;IAEV,EAAE,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;QAC5G,uEAAuE;QACvE,qEAAqE;QACrE,oEAAoE;QACpE,mEAAmE;QACnE,oEAAoE;QACpE,iEAAiE;QACjE,MAAM,GAAG,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QAC1C,aAAa,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1C,aAAa,CAAC,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvB,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvB,6DAA6D;QAC7D,qEAAqE;QACrE,6CAA6C;QAC7C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QAEvB,IAAI,OAAO,GAAmC,EAAE,CAAC;QACjD,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;gBACjC,aAAa,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC;gBACtE,aAAa,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC;aACvE,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC3E,IAAI,GAAG,EAAE,CAAC;oBACR,IAAI,CAAC;wBACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;oBAC/B,CAAC;oBAAC,MAAM,CAAC;wBACP,kBAAkB;oBACpB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC;QACzC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,IAAI,UAAU,CAAC,MAAM,KAAK,UAAU;YAAE,MAAM,UAAU,CAAC,MAAM,CAAC;QAC9D,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,sEAAsE;QACtE,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAE,CAAC;QAC9C,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC;QAC7B,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACxF,CAAC,EAAE,MAAM,CAAC,CAAC;AACb,CAAC,CACF,CAAC;AAEF;sCACsC;AACtC,SAAS,eAAe,CAAC,OAAe;IACtC,OAAO,sBAAsB,CAAC,OAAO,CACnC,sCAAsC,EACtC;wDACoD,CACrD;SACE,OAAO,CACN,0CAA0C,EAC1C,2DAA2D,CAC5D;SACA,OAAO,CAAC,UAAU,EAAE,OAAO,OAAO,MAAM,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -27,6 +27,12 @@
|
|
|
27
27
|
* manual repro. vi.useFakeTimers() (used throughout close-browser.test.ts)
|
|
28
28
|
* cannot catch this class of bug, because fake timers do not model real
|
|
29
29
|
* event-loop-drain semantics — hence a dedicated, real-timer test here.
|
|
30
|
+
*
|
|
31
|
+
* Ports come from the OS (listen on 0), never a fixed number (#351): these
|
|
32
|
+
* tests used 23495-23497, inside reap-idle-browser.test.ts's 23490-23499
|
|
33
|
+
* range, whose fake Chrome endpoints run in a parallel worker. A spawn that
|
|
34
|
+
* failed on 23495 while that file had 23495 bound looked like a lost launch
|
|
35
|
+
* race to launchBrowser, which moved on and reported port 23496 instead.
|
|
30
36
|
*/
|
|
31
37
|
export {};
|
|
32
38
|
//# sourceMappingURL=launch-close-settle.test.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launch-close-settle.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/launch-close-settle.test.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"launch-close-settle.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/launch-close-settle.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG"}
|
|
@@ -27,10 +27,17 @@
|
|
|
27
27
|
* manual repro. vi.useFakeTimers() (used throughout close-browser.test.ts)
|
|
28
28
|
* cannot catch this class of bug, because fake timers do not model real
|
|
29
29
|
* event-loop-drain semantics — hence a dedicated, real-timer test here.
|
|
30
|
+
*
|
|
31
|
+
* Ports come from the OS (listen on 0), never a fixed number (#351): these
|
|
32
|
+
* tests used 23495-23497, inside reap-idle-browser.test.ts's 23490-23499
|
|
33
|
+
* range, whose fake Chrome endpoints run in a parallel worker. A spawn that
|
|
34
|
+
* failed on 23495 while that file had 23495 bound looked like a lost launch
|
|
35
|
+
* race to launchBrowser, which moved on and reported port 23496 instead.
|
|
30
36
|
*/
|
|
31
37
|
import { spawn } from 'node:child_process';
|
|
32
38
|
import { chmodSync, writeFileSync } from 'node:fs';
|
|
33
39
|
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
40
|
+
import { createServer } from 'node:net';
|
|
34
41
|
import { tmpdir } from 'node:os';
|
|
35
42
|
import { join } from 'node:path';
|
|
36
43
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
@@ -85,6 +92,18 @@ afterEach(async () => {
|
|
|
85
92
|
}
|
|
86
93
|
await rm(tempDir, { recursive: true, force: true });
|
|
87
94
|
});
|
|
95
|
+
/** A port nothing is listening on, picked by the kernel from its ephemeral
|
|
96
|
+
* range — which the fixed-port fixtures of other test files stay below. */
|
|
97
|
+
function freePort() {
|
|
98
|
+
return new Promise((resolve, reject) => {
|
|
99
|
+
const server = createServer();
|
|
100
|
+
server.once('error', reject);
|
|
101
|
+
server.listen(0, '127.0.0.1', () => {
|
|
102
|
+
const { port } = server.address();
|
|
103
|
+
server.close(() => resolve(port));
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}
|
|
88
107
|
async function writePersistedPort(port, pid, savedAt) {
|
|
89
108
|
const dir = join(tempDir, '.monomind', 'monobrowse');
|
|
90
109
|
await mkdir(dir, { recursive: true });
|
|
@@ -109,32 +128,34 @@ describe('#314: launchBrowser settles instead of hanging when Chrome fails to st
|
|
|
109
128
|
// "file not found" that launchBrowser would reject before ever exec'ing.
|
|
110
129
|
writeFileSync(fake, 'not an executable\n');
|
|
111
130
|
chmodSync(fake, 0o644);
|
|
131
|
+
const port = await freePort();
|
|
112
132
|
const start = Date.now();
|
|
113
|
-
await expect(launchBrowser({ executablePath: fake, port
|
|
133
|
+
await expect(launchBrowser({ executablePath: fake, port, launchTimeoutMs: 10_000 })).rejects.toThrow(`Chrome failed to start on port ${port}: `);
|
|
114
134
|
// Without a child 'error' listener, this used to depend entirely on
|
|
115
135
|
// whether something outside this function happened to intercept the
|
|
116
136
|
// resulting uncaught exception (a bare node:test process has nothing
|
|
117
137
|
// that does — see the module doc comment); where it happened not to
|
|
118
138
|
// crash the process outright, the promise still only ever settled by
|
|
119
139
|
// burning the full launchTimeoutMs. The fix rejects as soon as the
|
|
120
|
-
// spawn error fires, so this must land
|
|
121
|
-
// ride
|
|
122
|
-
expect(Date.now() - start).toBeLessThan(
|
|
123
|
-
},
|
|
140
|
+
// spawn error fires, so this must land well inside the 10s timeout
|
|
141
|
+
// rather than ride it out — with room for a loaded machine.
|
|
142
|
+
expect(Date.now() - start).toBeLessThan(5000);
|
|
143
|
+
}, 20_000);
|
|
124
144
|
it('rejects with a clear message when Chrome exits immediately instead of opening its CDP port', async () => {
|
|
125
145
|
vi.resetModules();
|
|
126
146
|
const { launchBrowser } = await import('../browser/browser.js');
|
|
127
147
|
const fake = join(tempDir, 'chrome.sh');
|
|
128
148
|
writeFileSync(fake, '#!/bin/sh\nexit 1\n');
|
|
129
149
|
chmodSync(fake, 0o755);
|
|
130
|
-
|
|
131
|
-
|
|
150
|
+
const port = await freePort();
|
|
151
|
+
await expect(launchBrowser({ executablePath: fake, port, launchTimeoutMs: 10_000 })).rejects.toThrow(`Chrome exited before the CDP endpoint opened on port ${port} `);
|
|
152
|
+
}, 20_000);
|
|
132
153
|
});
|
|
133
154
|
describe('#314: closeBrowser settles under the real event loop, not fake timers', () => {
|
|
134
155
|
it('resolves promptly when nothing else is pinning the event loop', async () => {
|
|
135
156
|
vi.resetModules();
|
|
136
157
|
const { closeBrowser } = await import('../browser/browser.js');
|
|
137
|
-
const port =
|
|
158
|
+
const port = await freePort();
|
|
138
159
|
// A real, short-lived child — not Chrome, just something with a genuine,
|
|
139
160
|
// observable exit so process.kill(pid, 0) behaves for real and there is
|
|
140
161
|
// no other handle (socket, ref'd timer) left to accidentally keep the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launch-close-settle.test.js","sourceRoot":"","sources":["../../../src/__tests__/launch-close-settle.test.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"launch-close-settle.test.js","sourceRoot":"","sources":["../../../src/__tests__/launch-close-settle.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/browser/browser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/browser/browser.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAgC,MAAM,UAAU,CAAC;AASnE,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA8B3D,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/D;AAED,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvE;AA0BD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAyDD,wBAAsB,aAAa,CAAC,MAAM,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyF/E;AAyPD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW9F;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CA0BtE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8EjF;AAgCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOtE;AA6DD,wBAAsB,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9F;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAM,GAAG,aAAa,GAAG,kBAA2B,EAC/D,OAAO,SAAS,GACf,OAAO,CAAC,IAAI,CAAC,CAyCf;AAiFD,wBAAsB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUzF;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAU3F"}
|