@rstest/browser 0.10.2 → 0.10.4
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/{323.js → 626.js} +2 -3
- package/dist/browser-container/container-static/js/{188.480c3c49b5.js → 3.d3d6c6e4cf.js} +2908 -2915
- package/dist/browser-container/container-static/js/3.d3d6c6e4cf.js.LICENSE.txt +1 -0
- package/dist/browser-container/container-static/js/{index.29fc60be33.js → index.8fb1588e4a.js} +431 -455
- package/dist/browser-container/container-static/js/{lib-react.5ae9b90ee5.js → lib-react.62b27a21db.js} +21 -21
- package/dist/browser-container/container-static/js/lib-react.62b27a21db.js.LICENSE.txt +1 -0
- package/dist/browser-container/index.html +1 -1
- package/dist/browser.js +5 -5
- package/dist/client/dispatchTransport.d.ts +19 -0
- package/dist/client/public.d.ts +3 -3
- package/dist/client/sourceMapSupport.d.ts +1 -1
- package/dist/concurrency.d.ts +3 -3
- package/dist/configValidation.d.ts +2 -2
- package/dist/dispatchCapabilities.d.ts +1 -1
- package/dist/hostController.d.ts +3 -3
- package/dist/index.d.ts +5 -5
- package/dist/index.js +209 -221
- package/dist/protocol.d.ts +45 -18
- package/dist/providers/index.d.ts +11 -1
- package/dist/rpcProtocol.d.ts +32 -18
- package/dist/rslib-runtime.js +9 -5
- package/dist/viewportPresets.d.ts +5 -0
- package/package.json +8 -8
- package/src/AGENTS.md +7 -1
- package/src/client/dispatchTransport.ts +63 -1
- package/src/client/entry.ts +25 -58
- package/src/client/public.ts +3 -3
- package/src/client/snapshot.ts +24 -22
- package/src/client/sourceMapSupport.ts +1 -1
- package/src/concurrency.ts +6 -20
- package/src/configValidation.ts +2 -2
- package/src/dispatchCapabilities.ts +102 -83
- package/src/env.d.ts +6 -2
- package/src/hostController.ts +76 -42
- package/src/index.ts +22 -11
- package/src/protocol.ts +66 -22
- package/src/providers/index.ts +11 -1
- package/src/providers/playwright/runtime.ts +104 -4
- package/src/rpcProtocol.ts +34 -21
- package/src/viewportPresets.ts +5 -0
- package/src/watchCliShortcuts.ts +2 -4
- package/dist/browser-container/container-static/js/188.480c3c49b5.js.LICENSE.txt +0 -1
- package/dist/browser-container/container-static/js/lib-react.5ae9b90ee5.js.LICENSE.txt +0 -1
package/src/protocol.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BrowserViewport } from '@rstest/core/internal/browser';
|
|
2
2
|
import type {
|
|
3
3
|
RuntimeConfig,
|
|
4
4
|
TestFileResult,
|
|
5
5
|
TestInfo,
|
|
6
6
|
TestResult,
|
|
7
|
-
} from '@rstest/core/browser-runtime';
|
|
7
|
+
} from '@rstest/core/internal/browser-runtime';
|
|
8
8
|
import type { SnapshotUpdateState } from '@vitest/snapshot';
|
|
9
9
|
|
|
10
10
|
export type {
|
|
11
11
|
BrowserLocatorIR,
|
|
12
12
|
BrowserRpcRequest,
|
|
13
|
+
SnapshotRpcCall,
|
|
14
|
+
SnapshotRpcMethod,
|
|
15
|
+
SnapshotRpcMethodArgs,
|
|
13
16
|
SnapshotRpcRequest,
|
|
14
17
|
} from './rpcProtocol';
|
|
15
18
|
export { validateBrowserRpcRequest } from './rpcProtocol';
|
|
@@ -27,12 +30,10 @@ export const DISPATCH_METHOD_RPC = 'rpc';
|
|
|
27
30
|
|
|
28
31
|
export type SerializedRuntimeConfig = RuntimeConfig;
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
| DevicePreset;
|
|
33
|
+
// `BrowserViewport` is a core config type (`@rstest/core` owns the canonical
|
|
34
|
+
// definition used by `NormalizedBrowserModeConfig`). Re-export it so the host
|
|
35
|
+
// assigns the SAME type across the seam instead of a hand-copied duplicate.
|
|
36
|
+
export type { BrowserViewport };
|
|
36
37
|
|
|
37
38
|
export type BrowserProjectRuntime = {
|
|
38
39
|
name: string;
|
|
@@ -58,6 +59,25 @@ export type TestFileInfo = {
|
|
|
58
59
|
*/
|
|
59
60
|
export type BrowserExecutionMode = 'run' | 'collect';
|
|
60
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Wire shape of a `log` client message payload. The host receives this and maps
|
|
64
|
+
* it onto core's {@link UserConsoleLog} (notably `level` → `name`); that mapper
|
|
65
|
+
* (`hostController.ts` `handleLog`) annotates its result as `UserConsoleLog`, so
|
|
66
|
+
* the map→core direction is compiler-checked. Owning the wire shape here as one
|
|
67
|
+
* named type keeps the host's input type from drifting away from the producer.
|
|
68
|
+
*/
|
|
69
|
+
export type BrowserLogPayload = {
|
|
70
|
+
level: 'log' | 'warn' | 'error' | 'info' | 'debug';
|
|
71
|
+
content: string;
|
|
72
|
+
taskId?: string;
|
|
73
|
+
taskName?: string;
|
|
74
|
+
taskParentNames?: string[];
|
|
75
|
+
taskType?: 'file' | 'suite' | 'case';
|
|
76
|
+
testPath: string;
|
|
77
|
+
type: 'stdout' | 'stderr';
|
|
78
|
+
trace?: string;
|
|
79
|
+
};
|
|
80
|
+
|
|
61
81
|
export type BrowserHostConfig = {
|
|
62
82
|
rootPath: string;
|
|
63
83
|
projects: BrowserProjectRuntime[];
|
|
@@ -101,20 +121,7 @@ export type BrowserClientMessage =
|
|
|
101
121
|
}
|
|
102
122
|
| { type: 'case-result'; payload: TestResult }
|
|
103
123
|
| { type: 'file-complete'; payload: TestFileResult }
|
|
104
|
-
| {
|
|
105
|
-
type: 'log';
|
|
106
|
-
payload: {
|
|
107
|
-
level: 'log' | 'warn' | 'error' | 'info' | 'debug';
|
|
108
|
-
content: string;
|
|
109
|
-
taskId?: string;
|
|
110
|
-
taskName?: string;
|
|
111
|
-
taskParentNames?: string[];
|
|
112
|
-
taskType?: 'file' | 'suite' | 'case';
|
|
113
|
-
testPath: string;
|
|
114
|
-
type: 'stdout' | 'stderr';
|
|
115
|
-
trace?: string;
|
|
116
|
-
};
|
|
117
|
-
}
|
|
124
|
+
| { type: 'log'; payload: BrowserLogPayload }
|
|
118
125
|
| {
|
|
119
126
|
type: 'fatal';
|
|
120
127
|
payload: { message: string; stack?: string };
|
|
@@ -134,6 +141,38 @@ export type BrowserClientMessage =
|
|
|
134
141
|
payload: BrowserDispatchRequest;
|
|
135
142
|
};
|
|
136
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Lifecycle methods the runner emits via `dispatchRunnerLifecycle()` as
|
|
146
|
+
* dispatch-rpc-requests on the `runner` namespace (as opposed to the
|
|
147
|
+
* {@link BrowserClientMessage} types it `send()`s). The runner client imports
|
|
148
|
+
* this instead of redeclaring the list, so the emit site cannot drift from the
|
|
149
|
+
* host router.
|
|
150
|
+
*/
|
|
151
|
+
export type RunnerLifecycleMethod =
|
|
152
|
+
| 'file-ready'
|
|
153
|
+
| 'suite-start'
|
|
154
|
+
| 'suite-result'
|
|
155
|
+
| 'case-start';
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* {@link BrowserClientMessage} types that are forwarded to the `runner`
|
|
159
|
+
* namespace (by message `type`) rather than handled at the transport layer.
|
|
160
|
+
* `Extract` keeps this a checked subset of the message union — renaming a
|
|
161
|
+
* message type drops it here, surfacing as a missing handler downstream.
|
|
162
|
+
*/
|
|
163
|
+
type RunnerMessageMethod = Extract<
|
|
164
|
+
BrowserClientMessage['type'],
|
|
165
|
+
'file-start' | 'case-result' | 'file-complete' | 'log' | 'fatal'
|
|
166
|
+
>;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Single source of truth for every method handled by the `runner` dispatch
|
|
170
|
+
* namespace. The host handler table is keyed by this union (a missing key is a
|
|
171
|
+
* compile error), so adding a runner method here forces a matching handler and
|
|
172
|
+
* cannot silently no-op at runtime.
|
|
173
|
+
*/
|
|
174
|
+
export type RunnerDispatchMethod = RunnerLifecycleMethod | RunnerMessageMethod;
|
|
175
|
+
|
|
137
176
|
/**
|
|
138
177
|
* Transport-agnostic envelope used by host routing.
|
|
139
178
|
* `namespace + method + args + target` describes an operation independent of
|
|
@@ -147,6 +186,11 @@ export type BrowserDispatchRequest = {
|
|
|
147
186
|
namespace: string;
|
|
148
187
|
method: string;
|
|
149
188
|
args?: unknown;
|
|
189
|
+
// Routing reads `namespace`, `method`, `runToken`, and `target.sessionId`
|
|
190
|
+
// (see dispatchRouter.ts / dispatchBrowserRpcRequest). `target.testFile` and
|
|
191
|
+
// `target.projectName` are carried for diagnostics / forward-compatibility and
|
|
192
|
+
// are NOT consulted for routing today — adding a routing-relevant field here
|
|
193
|
+
// means wiring a reader on the host side, which structural typing won't force.
|
|
150
194
|
target?: {
|
|
151
195
|
testFile?: string;
|
|
152
196
|
sessionId?: string;
|
package/src/providers/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BrowserProvider } from '@rstest/core/internal/browser';
|
|
1
2
|
import type { BrowserRpcRequest } from '../rpcProtocol';
|
|
2
3
|
import { playwrightProviderImplementation } from './playwright';
|
|
3
4
|
|
|
@@ -14,8 +15,14 @@ import { playwrightProviderImplementation } from './playwright';
|
|
|
14
15
|
* - do not reference optional peer provider types from public declarations
|
|
15
16
|
* - keep provider-specific behavior and config decoding inside provider implementations
|
|
16
17
|
* - prefer direct passthrough to provider APIs over provider-specific translation
|
|
18
|
+
*
|
|
19
|
+
* The provider-name union is owned by `@rstest/core` (see `BROWSER_PROVIDERS`)
|
|
20
|
+
* because core's CLI `init` templates need it but cannot import this package
|
|
21
|
+
* (peer-dependency direction). `providerImplementations` below is keyed by the
|
|
22
|
+
* re-exported union, so a provider added in core without an implementation here
|
|
23
|
+
* is a compile error.
|
|
17
24
|
*/
|
|
18
|
-
export type BrowserProvider
|
|
25
|
+
export type { BrowserProvider };
|
|
19
26
|
|
|
20
27
|
/** Minimal console shape needed by host logging bridge. */
|
|
21
28
|
export type BrowserConsoleMessage = {
|
|
@@ -44,6 +51,7 @@ export type BrowserProviderPage = {
|
|
|
44
51
|
): void;
|
|
45
52
|
};
|
|
46
53
|
close: () => Promise<void>;
|
|
54
|
+
[Symbol.asyncDispose]: () => Promise<void>;
|
|
47
55
|
};
|
|
48
56
|
|
|
49
57
|
/** Minimal browser context API surface required by hostController. */
|
|
@@ -51,11 +59,13 @@ export type BrowserProviderContext = {
|
|
|
51
59
|
newPage: () => Promise<BrowserProviderPage>;
|
|
52
60
|
on: (event: 'page', listener: (page: BrowserProviderPage) => void) => void;
|
|
53
61
|
close: () => Promise<void>;
|
|
62
|
+
[Symbol.asyncDispose]: () => Promise<void>;
|
|
54
63
|
};
|
|
55
64
|
|
|
56
65
|
/** Minimal browser API surface required by hostController. */
|
|
57
66
|
export type BrowserProviderBrowser = {
|
|
58
67
|
close: () => Promise<void>;
|
|
68
|
+
[Symbol.asyncDispose]: () => Promise<void>;
|
|
59
69
|
newContext: (options: {
|
|
60
70
|
viewport: { width: number; height: number } | null;
|
|
61
71
|
providerOptions?: Record<string, unknown>;
|
|
@@ -1,4 +1,104 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
BrowserConsoleMessage,
|
|
3
|
+
BrowserProviderContext,
|
|
4
|
+
BrowserProviderPage,
|
|
5
|
+
BrowserProviderRuntime,
|
|
6
|
+
} from '../index';
|
|
7
|
+
|
|
8
|
+
type PlaywrightPageLike = Omit<
|
|
9
|
+
BrowserProviderPage,
|
|
10
|
+
'on' | typeof Symbol.asyncDispose
|
|
11
|
+
> & {
|
|
12
|
+
on: {
|
|
13
|
+
(event: 'popup', listener: (page: PlaywrightPageLike) => void): void;
|
|
14
|
+
(
|
|
15
|
+
event: 'console',
|
|
16
|
+
listener: (message: BrowserConsoleMessage) => void,
|
|
17
|
+
): void;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
type PlaywrightContextLike = Omit<
|
|
21
|
+
BrowserProviderContext,
|
|
22
|
+
'newPage' | typeof Symbol.asyncDispose
|
|
23
|
+
> & {
|
|
24
|
+
newPage: () => Promise<PlaywrightPageLike>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type AsyncDisposableResource<T> = T & {
|
|
28
|
+
[Symbol.asyncDispose]: () => Promise<void>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type PlaywrightBrowserLike = Omit<
|
|
32
|
+
BrowserProviderRuntime['browser'],
|
|
33
|
+
typeof Symbol.asyncDispose
|
|
34
|
+
>;
|
|
35
|
+
|
|
36
|
+
const patchedPages = new WeakSet<PlaywrightPageLike>();
|
|
37
|
+
const patchedContexts = new WeakSet<PlaywrightContextLike>();
|
|
38
|
+
|
|
39
|
+
const withAsyncDispose = <T extends { close: () => Promise<void> }>(
|
|
40
|
+
resource: T,
|
|
41
|
+
): AsyncDisposableResource<T> => {
|
|
42
|
+
if (typeof Symbol.asyncDispose === 'symbol') {
|
|
43
|
+
const existing = Object.getOwnPropertyDescriptor(
|
|
44
|
+
resource,
|
|
45
|
+
Symbol.asyncDispose,
|
|
46
|
+
);
|
|
47
|
+
if (!existing) {
|
|
48
|
+
Object.defineProperty(resource, Symbol.asyncDispose, {
|
|
49
|
+
configurable: true,
|
|
50
|
+
value: () => resource.close(),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return resource as AsyncDisposableResource<T>;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const wrapPage = (page: PlaywrightPageLike): BrowserProviderPage => {
|
|
59
|
+
if (patchedPages.has(page)) {
|
|
60
|
+
return withAsyncDispose(page) as BrowserProviderPage;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
patchedPages.add(page);
|
|
64
|
+
const originalOn = page.on.bind(page);
|
|
65
|
+
page.on = ((
|
|
66
|
+
event: 'popup' | 'console',
|
|
67
|
+
listener:
|
|
68
|
+
| ((page: BrowserProviderPage) => void)
|
|
69
|
+
| ((message: BrowserConsoleMessage) => void),
|
|
70
|
+
) => {
|
|
71
|
+
if (event === 'popup') {
|
|
72
|
+
originalOn(event, (popup) => {
|
|
73
|
+
(listener as (page: BrowserProviderPage) => void)(wrapPage(popup));
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
originalOn(event, listener as (message: BrowserConsoleMessage) => void);
|
|
79
|
+
}) as PlaywrightPageLike['on'];
|
|
80
|
+
|
|
81
|
+
return withAsyncDispose(page) as BrowserProviderPage;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const wrapContext = (
|
|
85
|
+
context: PlaywrightContextLike,
|
|
86
|
+
): BrowserProviderContext => {
|
|
87
|
+
if (patchedContexts.has(context)) {
|
|
88
|
+
return withAsyncDispose(context) as BrowserProviderContext;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
patchedContexts.add(context);
|
|
92
|
+
const originalNewPage = context.newPage.bind(context);
|
|
93
|
+
context.newPage = async () => wrapPage(await originalNewPage());
|
|
94
|
+
|
|
95
|
+
const originalOn = context.on.bind(context);
|
|
96
|
+
context.on = (event, listener) => {
|
|
97
|
+
originalOn(event, (page) => listener(wrapPage(page)));
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return withAsyncDispose(context) as BrowserProviderContext;
|
|
101
|
+
};
|
|
2
102
|
|
|
3
103
|
export async function launchPlaywrightBrowser({
|
|
4
104
|
browserName,
|
|
@@ -30,7 +130,7 @@ export async function launchPlaywrightBrowser({
|
|
|
30
130
|
args: launchArgs,
|
|
31
131
|
});
|
|
32
132
|
|
|
33
|
-
const wrappedBrowser
|
|
133
|
+
const wrappedBrowser = withAsyncDispose({
|
|
34
134
|
close: async () => browser.close(),
|
|
35
135
|
newContext: async ({
|
|
36
136
|
providerOptions: contextProviderOptions,
|
|
@@ -44,9 +144,9 @@ export async function launchPlaywrightBrowser({
|
|
|
44
144
|
viewport,
|
|
45
145
|
});
|
|
46
146
|
|
|
47
|
-
return context as unknown as
|
|
147
|
+
return wrapContext(context as unknown as PlaywrightContextLike);
|
|
48
148
|
},
|
|
49
|
-
};
|
|
149
|
+
} satisfies PlaywrightBrowserLike) as BrowserProviderRuntime['browser'];
|
|
50
150
|
|
|
51
151
|
return {
|
|
52
152
|
browser: wrappedBrowser,
|
package/src/rpcProtocol.ts
CHANGED
|
@@ -178,28 +178,41 @@ export const validateBrowserRpcRequest = (
|
|
|
178
178
|
return request;
|
|
179
179
|
};
|
|
180
180
|
|
|
181
|
+
/**
|
|
182
|
+
* Single source of truth for snapshot RPC methods and their argument shapes.
|
|
183
|
+
* The request union, the client sender, both host-side mappers, and every
|
|
184
|
+
* exhaustiveness check derive from this map — adding or renaming a method here
|
|
185
|
+
* forces a compile error at every site that has not been updated.
|
|
186
|
+
*/
|
|
187
|
+
export type SnapshotRpcMethodArgs = {
|
|
188
|
+
resolveSnapshotPath: { testPath: string };
|
|
189
|
+
readSnapshotFile: { filepath: string };
|
|
190
|
+
saveSnapshotFile: { filepath: string; content: string };
|
|
191
|
+
removeSnapshotFile: { filepath: string };
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export type SnapshotRpcMethod = keyof SnapshotRpcMethodArgs;
|
|
195
|
+
|
|
181
196
|
/**
|
|
182
197
|
* Snapshot RPC request from runner iframe.
|
|
183
198
|
* The container will forward these to the host via WebSocket RPC.
|
|
184
199
|
*/
|
|
185
|
-
export type SnapshotRpcRequest =
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
args: { filepath: string };
|
|
205
|
-
};
|
|
200
|
+
export type SnapshotRpcRequest = {
|
|
201
|
+
[M in SnapshotRpcMethod]: {
|
|
202
|
+
id: string;
|
|
203
|
+
method: M;
|
|
204
|
+
args: SnapshotRpcMethodArgs[M];
|
|
205
|
+
};
|
|
206
|
+
}[SnapshotRpcMethod];
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Client-side snapshot RPC call (request without the transport `id`).
|
|
210
|
+
* Distributive over {@link SnapshotRpcMethod} so `method` and `args` stay paired
|
|
211
|
+
* at the call site — a mismatched pair fails to compile.
|
|
212
|
+
*/
|
|
213
|
+
export type SnapshotRpcCall = {
|
|
214
|
+
[M in SnapshotRpcMethod]: {
|
|
215
|
+
method: M;
|
|
216
|
+
args: SnapshotRpcMethodArgs[M];
|
|
217
|
+
};
|
|
218
|
+
}[SnapshotRpcMethod];
|
package/src/viewportPresets.ts
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
* IMPORTANT: Keep this list/map in sync with `DevicePreset` typing in
|
|
5
5
|
* `@rstest/core` (`packages/core/src/types/config.ts`) so `defineConfig`
|
|
6
6
|
* autocomplete and runtime validation stay consistent.
|
|
7
|
+
*
|
|
8
|
+
* Upstream source of truth for ids/dimensions is the Chrome DevTools emulated
|
|
9
|
+
* device list — mirror each device's `screen.vertical` `{ width, height }`:
|
|
10
|
+
* https://github.com/ChromeDevTools/devtools-frontend/blob/main/front_end/models/emulation/EmulatedDevices.ts
|
|
11
|
+
* Last verified in sync (all 17): 2026-04-22, devtools-frontend commit abaac05e.
|
|
7
12
|
*/
|
|
8
13
|
export const BROWSER_VIEWPORT_PRESET_IDS = [
|
|
9
14
|
'iPhoneSE',
|
package/src/watchCliShortcuts.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { color, logger } from '@rstest/core/browser';
|
|
1
|
+
import { color, isTTY, logger } from '@rstest/core/internal/browser';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
export const isBrowserWatchCliShortcutsEnabled = (): boolean => isTTY();
|
|
3
|
+
export const isBrowserWatchCliShortcutsEnabled = (): boolean => isTTY('stdin');
|
|
6
4
|
|
|
7
5
|
export const getBrowserWatchCliShortcutsHintMessage = (): string => {
|
|
8
6
|
return ` ${color.dim('press')} ${color.bold('q')} ${color.dim('to quit')}\n`;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! LICENSE: 188.480c3c49b5.js.LICENSE.txt */
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! LICENSE: lib-react.5ae9b90ee5.js.LICENSE.txt */
|