@monoes/monobrowse 1.0.25 → 1.0.27

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.
Files changed (67) hide show
  1. package/dist/src/__tests__/browser-launch.test.d.ts +3 -2
  2. package/dist/src/__tests__/browser-launch.test.d.ts.map +1 -1
  3. package/dist/src/__tests__/browser-launch.test.js +71 -6
  4. package/dist/src/__tests__/browser-launch.test.js.map +1 -1
  5. package/dist/src/__tests__/launch-close-settle.test.d.ts +6 -0
  6. package/dist/src/__tests__/launch-close-settle.test.d.ts.map +1 -1
  7. package/dist/src/__tests__/launch-close-settle.test.js +29 -8
  8. package/dist/src/__tests__/launch-close-settle.test.js.map +1 -1
  9. package/dist/src/browser/actions-eval.d.ts +8 -0
  10. package/dist/src/browser/actions-eval.d.ts.map +1 -0
  11. package/dist/src/browser/actions-eval.js +72 -0
  12. package/dist/src/browser/actions-eval.js.map +1 -0
  13. package/dist/src/browser/actions-form.d.ts +10 -0
  14. package/dist/src/browser/actions-form.d.ts.map +1 -0
  15. package/dist/src/browser/actions-form.js +133 -0
  16. package/dist/src/browser/actions-form.js.map +1 -0
  17. package/dist/src/browser/actions-keyboard.d.ts +7 -0
  18. package/dist/src/browser/actions-keyboard.d.ts.map +1 -0
  19. package/dist/src/browser/actions-keyboard.js +131 -0
  20. package/dist/src/browser/actions-keyboard.js.map +1 -0
  21. package/dist/src/browser/actions-mouse.d.ts +11 -0
  22. package/dist/src/browser/actions-mouse.d.ts.map +1 -0
  23. package/dist/src/browser/actions-mouse.js +105 -0
  24. package/dist/src/browser/actions-mouse.js.map +1 -0
  25. package/dist/src/browser/actions.d.ts +12 -28
  26. package/dist/src/browser/actions.d.ts.map +1 -1
  27. package/dist/src/browser/actions.js +12 -434
  28. package/dist/src/browser/actions.js.map +1 -1
  29. package/dist/src/browser/browser-discovery.d.ts +26 -0
  30. package/dist/src/browser/browser-discovery.d.ts.map +1 -0
  31. package/dist/src/browser/browser-discovery.js +113 -0
  32. package/dist/src/browser/browser-discovery.js.map +1 -0
  33. package/dist/src/browser/browser-launch.d.ts +3 -0
  34. package/dist/src/browser/browser-launch.d.ts.map +1 -0
  35. package/dist/src/browser/browser-launch.js +324 -0
  36. package/dist/src/browser/browser-launch.js.map +1 -0
  37. package/dist/src/browser/browser-lifecycle.d.ts +52 -0
  38. package/dist/src/browser/browser-lifecycle.d.ts.map +1 -0
  39. package/dist/src/browser/browser-lifecycle.js +233 -0
  40. package/dist/src/browser/browser-lifecycle.js.map +1 -0
  41. package/dist/src/browser/browser-page.d.ts +13 -0
  42. package/dist/src/browser/browser-page.d.ts.map +1 -0
  43. package/dist/src/browser/browser-page.js +179 -0
  44. package/dist/src/browser/browser-page.js.map +1 -0
  45. package/dist/src/browser/browser-state.d.ts +7 -0
  46. package/dist/src/browser/browser-state.d.ts.map +1 -0
  47. package/dist/src/browser/browser-state.js +19 -0
  48. package/dist/src/browser/browser-state.js.map +1 -0
  49. package/dist/src/browser/browser.d.ts +5 -68
  50. package/dist/src/browser/browser.d.ts.map +1 -1
  51. package/dist/src/browser/browser.js +9 -794
  52. package/dist/src/browser/browser.js.map +1 -1
  53. package/dist/tsconfig.tsbuildinfo +1 -1
  54. package/package.json +1 -1
  55. package/src/__tests__/browser-launch.test.ts +78 -6
  56. package/src/__tests__/launch-close-settle.test.ts +32 -10
  57. package/src/browser/actions-eval.ts +118 -0
  58. package/src/browser/actions-form.ts +218 -0
  59. package/src/browser/actions-keyboard.ts +171 -0
  60. package/src/browser/actions-mouse.ts +212 -0
  61. package/src/browser/actions.ts +37 -712
  62. package/src/browser/browser-discovery.ts +116 -0
  63. package/src/browser/browser-launch.ts +358 -0
  64. package/src/browser/browser-lifecycle.ts +238 -0
  65. package/src/browser/browser-page.ts +213 -0
  66. package/src/browser/browser-state.ts +21 -0
  67. package/src/browser/browser.ts +17 -859
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-page.d.ts","sourceRoot":"","sources":["../../../src/browser/browser-page.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAgC,MAAM,UAAU,CAAC;AAGnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,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,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"}
@@ -0,0 +1,179 @@
1
+ // Split out of browser.ts (file-size sweep). Pure move: no behaviour change.
2
+ import { CdpClient, fetchNewTarget, fetchTargets } from './cdp.js';
3
+ import { enableConsoleCapture, setupConsoleCapture } from './console-log.js';
4
+ import { setupDialogAutoHandling } from './dialog.js';
5
+ export async function enableSessionDomains(client, sessionId) {
6
+ await Promise.all([
7
+ client.send('Page.enable', {}, sessionId),
8
+ client.send('Runtime.enable', {}, sessionId),
9
+ client.send('Network.enable', {}, sessionId),
10
+ client.send('DOM.enable', {}, sessionId),
11
+ client.send('Accessibility.enable', {}, sessionId),
12
+ ]);
13
+ setupConsoleCapture(client, sessionId);
14
+ await enableConsoleCapture(client, sessionId);
15
+ setupDialogAutoHandling(client, sessionId);
16
+ }
17
+ export async function connectToTarget(port, targetId) {
18
+ const targets = await fetchTargets(port);
19
+ const pageTargets = targets.filter((t) => t.type === 'page');
20
+ let target;
21
+ if (targetId) {
22
+ const found = pageTargets.find((t) => t.id === targetId);
23
+ if (!found)
24
+ throw new Error(`Target ${targetId} not found`);
25
+ target = found;
26
+ }
27
+ else if (pageTargets.length > 0) {
28
+ target = pageTargets[0];
29
+ }
30
+ else {
31
+ target = await fetchNewTarget(port, 'about:blank');
32
+ }
33
+ const wsUrl = target.webSocketDebuggerUrl ?? `ws://127.0.0.1:${port}/devtools/page/${target.id}`;
34
+ const client = new CdpClient();
35
+ await client.connect(wsUrl);
36
+ const { sessionId } = await client.send('Target.attachToTarget', {
37
+ targetId: target.id,
38
+ flatten: true,
39
+ });
40
+ await enableSessionDomains(client, sessionId);
41
+ return { client, target, sessionId };
42
+ }
43
+ export async function openUrl(client, sessionId, url) {
44
+ // Cap to 2 MB to prevent OOM in CDP message serializer (e.g. data: URI attacks)
45
+ if (url.length > 2_097_152)
46
+ throw new Error('URL exceeds 2 MB limit');
47
+ // Page.navigate reports a protocol-level failure (e.g. a refused connection)
48
+ // via errorText in its own response, before Chrome ever settles on the
49
+ // chrome-error://chromewebdata/ page — without this check a refused
50
+ // connection previously reported success against that error page.
51
+ const nav = await client.send('Page.navigate', { url }, sessionId);
52
+ if (nav.errorText)
53
+ throw new Error(`Navigation to ${url} failed: ${nav.errorText}`);
54
+ await waitForNetworkIdle(client, sessionId, 500, 30_000);
55
+ }
56
+ export async function waitForLoad(client, sessionId, condition = 'load', timeout = 30_000) {
57
+ if (condition === 'load' || condition === 'domcontentloaded') {
58
+ // Guard against race where the page loads before the listener is registered
59
+ const readyExpr = condition === 'load'
60
+ ? 'document.readyState === "complete"'
61
+ : 'document.readyState !== "loading"';
62
+ const readyCheck = await client
63
+ .send('Runtime.evaluate', {
64
+ expression: readyExpr,
65
+ returnByValue: true,
66
+ }, sessionId)
67
+ .catch(() => ({ result: { value: false } }));
68
+ if (readyCheck.result?.value)
69
+ return;
70
+ const event = condition === 'load' ? 'Page.loadEventFired' : 'Page.domContentEventFired';
71
+ const [eventPromise, cancelOnce] = client.onceWithOff(event, sessionId);
72
+ let timedOut = false;
73
+ let timeoutHandle;
74
+ const timeoutPromise = new Promise((resolve) => {
75
+ timeoutHandle = setTimeout(() => {
76
+ timedOut = true;
77
+ resolve();
78
+ }, timeout);
79
+ });
80
+ try {
81
+ await Promise.race([eventPromise, timeoutPromise]);
82
+ if (timedOut)
83
+ throw new Error(`Timeout waiting for ${condition}`);
84
+ }
85
+ finally {
86
+ cancelOnce();
87
+ clearTimeout(timeoutHandle);
88
+ }
89
+ return;
90
+ }
91
+ // networkidle: no network requests for 500ms
92
+ await waitForNetworkIdle(client, sessionId, 500, timeout);
93
+ }
94
+ async function waitForNetworkIdle(client, sessionId, idleMs, timeout) {
95
+ return new Promise((resolve, reject) => {
96
+ let pending = 0;
97
+ const inflight = new Set();
98
+ let idleTimer = null;
99
+ const killTimer = setTimeout(() => {
100
+ cleanup();
101
+ reject(new Error('Timeout waiting for networkidle'));
102
+ }, timeout);
103
+ const cleanup = () => {
104
+ if (idleTimer) {
105
+ clearTimeout(idleTimer);
106
+ idleTimer = null;
107
+ }
108
+ clearTimeout(killTimer);
109
+ offReq();
110
+ offResp();
111
+ offFail();
112
+ offCache();
113
+ offResp2();
114
+ };
115
+ const settle = () => {
116
+ cleanup();
117
+ resolve();
118
+ };
119
+ const check = () => {
120
+ if (pending === 0) {
121
+ if (idleTimer)
122
+ clearTimeout(idleTimer);
123
+ idleTimer = setTimeout(settle, idleMs);
124
+ }
125
+ else {
126
+ if (idleTimer) {
127
+ clearTimeout(idleTimer);
128
+ idleTimer = null;
129
+ }
130
+ }
131
+ };
132
+ const offReq = client.on('Network.requestWillBeSent', (params, sid) => {
133
+ if (sid !== sessionId)
134
+ return;
135
+ const id = params.requestId;
136
+ if (!inflight.has(id)) {
137
+ inflight.add(id);
138
+ pending++;
139
+ check();
140
+ }
141
+ });
142
+ const decrement = (params, sid) => {
143
+ if (sid !== sessionId)
144
+ return;
145
+ const id = params.requestId;
146
+ if (inflight.delete(id)) {
147
+ pending = Math.max(0, pending - 1);
148
+ check();
149
+ }
150
+ };
151
+ const offResp = client.on('Network.loadingFinished', decrement);
152
+ const offFail = client.on('Network.loadingFailed', decrement);
153
+ const offCache = client.on('Network.requestServedFromCache', decrement);
154
+ // Guard against requests that never fire loadingFinished/loadingFailed (e.g. data: URLs)
155
+ // Skip 3xx redirect responses — the request continues under the same requestId
156
+ const offResp2 = client.on('Network.responseReceived', (params, sid) => {
157
+ const p = params;
158
+ if (p.response.status >= 300 && p.response.status < 400)
159
+ return;
160
+ decrement(params, sid);
161
+ });
162
+ check();
163
+ });
164
+ }
165
+ export async function getCurrentUrl(client, sessionId) {
166
+ const result = await client.send('Runtime.evaluate', {
167
+ expression: 'location.href',
168
+ returnByValue: true,
169
+ }, sessionId);
170
+ return result.result?.value ?? '';
171
+ }
172
+ export async function getCurrentTitle(client, sessionId) {
173
+ const result = await client.send('Runtime.evaluate', {
174
+ expression: 'document.title',
175
+ returnByValue: true,
176
+ }, sessionId);
177
+ return result.result?.value ?? '';
178
+ }
179
+ //# sourceMappingURL=browser-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-page.js","sourceRoot":"","sources":["../../../src/browser/browser-page.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const launchedPids: Map<number, number>;
2
+ export declare const launchedUserDataDirs: Map<number, string>;
3
+ /** PID of the Chrome instance *this process* launched on `port`, if any. */
4
+ export declare function getLaunchedPid(port: number): number | undefined;
5
+ /** userDataDir of the Chrome instance *this process* launched on `port`, if any. */
6
+ export declare function getLaunchedUserDataDir(port: number): string | undefined;
7
+ //# sourceMappingURL=browser-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-state.d.ts","sourceRoot":"","sources":["../../../src/browser/browser-state.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,YAAY,qBAA4B,CAAC;AAGtD,eAAO,MAAM,oBAAoB,qBAA4B,CAAC;AAE9D,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"}
@@ -0,0 +1,19 @@
1
+ // Split out of browser.ts (file-size sweep). Pure move: no behaviour change.
2
+ // Tracks the PID of Chrome instances *we* spawned, keyed by CDP port, so
3
+ // closeBrowser() has a kill fallback when the graceful `Browser.close` CDP
4
+ // command fails or times out (e.g. a hung renderer). Ports we merely attached
5
+ // to (already-running browser) are never recorded here — we only ever kill
6
+ // processes we launched ourselves.
7
+ export const launchedPids = new Map();
8
+ // userDataDir per launched port — informational, persisted alongside the pid
9
+ // so a later process could clean up the temp profile dir too if ever needed.
10
+ export const launchedUserDataDirs = new Map();
11
+ /** PID of the Chrome instance *this process* launched on `port`, if any. */
12
+ export function getLaunchedPid(port) {
13
+ return launchedPids.get(port);
14
+ }
15
+ /** userDataDir of the Chrome instance *this process* launched on `port`, if any. */
16
+ export function getLaunchedUserDataDir(port) {
17
+ return launchedUserDataDirs.get(port);
18
+ }
19
+ //# sourceMappingURL=browser-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-state.js","sourceRoot":"","sources":["../../../src/browser/browser-state.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,yEAAyE;AACzE,2EAA2E;AAC3E,8EAA8E;AAC9E,2EAA2E;AAC3E,mCAAmC;AACnC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;AACtD,6EAA6E;AAC7E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE9D,4EAA4E;AAC5E,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC"}
@@ -1,69 +1,6 @@
1
- import { CdpClient } from './cdp.js';
2
- import type { BrowserConfig, CdpTarget } from './types.js';
3
- /** PID of the Chrome instance *this process* launched on `port`, if any. */
4
- export declare function getLaunchedPid(port: number): number | undefined;
5
- /** userDataDir of the Chrome instance *this process* launched on `port`, if any. */
6
- export declare function getLaunchedUserDataDir(port: number): string | undefined;
7
- export declare function isPortOpen(port: number): Promise<boolean>;
8
- export declare function launchBrowser(config?: BrowserConfig): Promise<number>;
9
- export declare function enableSessionDomains(client: CdpClient, sessionId: string): Promise<void>;
10
- export declare function connectToTarget(port: number, targetId?: string): Promise<{
11
- client: CdpClient;
12
- target: CdpTarget;
13
- sessionId: string;
14
- }>;
15
- /**
16
- * Cleanly terminate a Chrome/Chromium instance we launched on `port`.
17
- * Sends the `Browser.close` CDP command (the correct graceful shutdown —
18
- * closes all tabs and exits the process cleanly) over `client`'s connection.
19
- * If that command fails, times out, or the connection is already gone,
20
- * falls back to killing the tracked PID directly so a headed/interactive
21
- * browser window (e.g. one spawned for a login/CAPTCHA flow) never lingers
22
- * as a visible, authenticated, still-debuggable orphan process.
23
- *
24
- * On the graceful path this resolves only once the process is actually gone,
25
- * or after force-killing it when it outlasts PROCESS_EXIT_TIMEOUT_MS. Chrome
26
- * acknowledges `Browser.close` well before it exits, and this used to return
27
- * on the ack with an unref'd 1s timer as the only force-kill — so it resolved
28
- * while Chrome was still running and holding its port and its profile's
29
- * singleton lock, and if the caller's process exited first the kill never
30
- * happened at all. Callers reasonably read a resolved close() as "that
31
- * browser is gone"; on the graceful path it now means that.
32
- */
33
- export declare function closeBrowser(client: CdpClient, port: number): Promise<void>;
34
- /**
35
- * Give back the CDP port of a browser we launched that nothing is using any
36
- * more. A launched Chrome is deliberately detached and unref'd so it outlives
37
- * the command that spawned it and later commands can reattach — but nothing
38
- * reaped it afterwards, so an abandoned session kept listening on its port
39
- * (9222 by convention, which other local tools want) indefinitely. A foreign
40
- * CDP server *answers* there rather than refusing the connection, so those
41
- * tools retry the wrong port and report misleading errors instead of moving on.
42
- *
43
- * Nothing long-lived exists to run this on a timer — every CLI command is its
44
- * own short-lived process — so it runs at the next launch/attach instead
45
- * (see launchBrowser). A browser is reaped only when ALL of these hold:
46
- * - the persisted session says WE launched it — `connect` records
47
- * launched:false for a browser that belongs to the user, never touched;
48
- * - that session is older than IDLE_REAP_AFTER_MS;
49
- * - the CDP endpoint still answers and reports ZERO targets. An open tab,
50
- * or a client attached to one (Chrome drops webSocketDebuggerUrl from an
51
- * attached target but still lists it), means the session is live and
52
- * reattach-across-commands must keep working.
53
- *
54
- * Shutdown goes through closeBrowser() on the browser-level websocket — the
55
- * only connection left once every target is gone — so a recycled PID can
56
- * never be signaled by mistake: graceful `Browser.close` reaches whatever is
57
- * actually listening on that port, at any age, and the persisted PID is only
58
- * ever used for closeBrowser's own age-bounded force-kill.
59
- *
60
- * Never throws: a failed reap must not stop a launch. Returns the reaped
61
- * port, or null when there was nothing to reap. Sessions are per-port
62
- * (#318), so every recorded one is considered, not just the newest.
63
- */
64
- export declare function reapIdleLaunchedBrowser(): Promise<number | null>;
65
- export declare function openUrl(client: CdpClient, sessionId: string, url: string): Promise<void>;
66
- export declare function waitForLoad(client: CdpClient, sessionId: string, condition?: 'load' | 'networkidle' | 'domcontentloaded', timeout?: number): Promise<void>;
67
- export declare function getCurrentUrl(client: CdpClient, sessionId: string): Promise<string>;
68
- export declare function getCurrentTitle(client: CdpClient, sessionId: string): Promise<string>;
1
+ export { isPortOpen } from './browser-discovery.js';
2
+ export { launchBrowser } from './browser-launch.js';
3
+ export { closeBrowser, reapIdleLaunchedBrowser } from './browser-lifecycle.js';
4
+ export { connectToTarget, enableSessionDomains, getCurrentTitle, getCurrentUrl, openUrl, waitForLoad, } from './browser-page.js';
5
+ export { getLaunchedPid, getLaunchedUserDataDir } from './browser-state.js';
69
6
  //# sourceMappingURL=browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/browser/browser.ts"],"names":[],"mappings":"AAKA,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;AAgMD,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"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/browser/browser.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,OAAO,EACP,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC"}