@gnuechtel/shared-e2e 1.0.2 → 1.1.0-13211763982
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gnuechtel/shared-e2e",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0-13211763982",
|
|
4
4
|
"description": "Shared end-to-end test functions for gnuechtel projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"tslib": "^2.3.0",
|
|
13
|
-
"@gnuechtel/shared-coverage": "1.0
|
|
14
|
-
"@gnuechtel/shared-util": "1.0
|
|
13
|
+
"@gnuechtel/shared-coverage": "1.1.0-13211763982",
|
|
14
|
+
"@gnuechtel/shared-util": "1.1.0-13211763982"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
17
|
"@playwright/test": "^1.38.0",
|
|
18
|
-
"nx": "
|
|
18
|
+
"nx": ">=19 <23",
|
|
19
19
|
"debug": "^4.3.4"
|
|
20
20
|
},
|
|
21
21
|
"type": "commonjs",
|
|
@@ -4,6 +4,9 @@ exports.startLocalRegistry = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const child_process_1 = require("child_process");
|
|
6
6
|
const shared_util_1 = require("@gnuechtel/shared-util");
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const http_1 = require("http");
|
|
9
|
+
const path_1 = require("path");
|
|
7
10
|
// Some duplicated code from here: https://github.com/nrwl/nx/blob/d36194ad17d36e8e12f517f30f5171f4af99d556/packages/js/src/plugins/jest/start-local-registry.ts
|
|
8
11
|
//
|
|
9
12
|
// With some changes:
|
|
@@ -18,34 +21,72 @@ function startLocalRegistry(localRegistryTarget, storage) {
|
|
|
18
21
|
throw new Error(`localRegistryTarget is required`);
|
|
19
22
|
}
|
|
20
23
|
const name = 'Local registry';
|
|
21
|
-
const readyWhen = 'http://
|
|
24
|
+
const readyWhen = 'http://';
|
|
25
|
+
let registryHost = 'localhost';
|
|
22
26
|
let port;
|
|
27
|
+
const envBeforeRegistry = {
|
|
28
|
+
npm_config_registry: process.env['npm_config_registry'],
|
|
29
|
+
NPM_CONFIG_USERCONFIG: process.env['NPM_CONFIG_USERCONFIG'],
|
|
30
|
+
npm_config_userconfig: process.env['npm_config_userconfig'],
|
|
31
|
+
NPM_CONFIG_CACHE: process.env['NPM_CONFIG_CACHE'],
|
|
32
|
+
npm_config_cache: process.env['npm_config_cache'],
|
|
33
|
+
YARN_REGISTRY: process.env['YARN_REGISTRY'],
|
|
34
|
+
YARN_NPM_REGISTRY_SERVER: process.env['YARN_NPM_REGISTRY_SERVER'],
|
|
35
|
+
YARN_UNSAFE_HTTP_WHITELIST: process.env['YARN_UNSAFE_HTTP_WHITELIST'],
|
|
36
|
+
};
|
|
37
|
+
const npmConfigDir = (0, path_1.join)(process.cwd(), 'tmp', 'local-registry');
|
|
38
|
+
const npmUserConfig = (0, path_1.join)(npmConfigDir, '.npmrc');
|
|
39
|
+
const npmCacheDir = (0, path_1.join)(process.cwd(), 'tmp', 'npm-cache');
|
|
40
|
+
if (!(0, fs_1.existsSync)(npmConfigDir))
|
|
41
|
+
(0, fs_1.mkdirSync)(npmConfigDir, { recursive: true });
|
|
42
|
+
if (!(0, fs_1.existsSync)(npmCacheDir))
|
|
43
|
+
(0, fs_1.mkdirSync)(npmCacheDir, { recursive: true });
|
|
44
|
+
const npmEnvironment = Object.assign(Object.assign({}, process.env), { NPM_CONFIG_USERCONFIG: npmUserConfig, npm_config_userconfig: npmUserConfig, NPM_CONFIG_CACHE: npmCacheDir, npm_config_cache: npmCacheDir });
|
|
23
45
|
// We configure npm and yarn for local publishing after the local registry was started
|
|
24
46
|
const onReady = (readyMessage) => {
|
|
25
|
-
var _a
|
|
47
|
+
var _a;
|
|
26
48
|
if (!readyMessage)
|
|
27
49
|
throw new Error(`${name} is not ready!`);
|
|
28
|
-
// Detect port from server output
|
|
29
|
-
const
|
|
50
|
+
// Detect host and port from server output to keep npm/yarn target and auth host in sync.
|
|
51
|
+
const hostPortMatch = (_a = readyMessage.match(/https?:\/\/(?<host>[^/:]+):(?<port>\d+)/)) === null || _a === void 0 ? void 0 : _a.groups;
|
|
52
|
+
const portString = hostPortMatch === null || hostPortMatch === void 0 ? void 0 : hostPortMatch['port'];
|
|
53
|
+
const hostString = hostPortMatch === null || hostPortMatch === void 0 ? void 0 : hostPortMatch['host'];
|
|
30
54
|
if (!portString)
|
|
31
55
|
throw new Error('Could not detect port');
|
|
56
|
+
if (!hostString)
|
|
57
|
+
throw new Error('Could not detect host');
|
|
58
|
+
registryHost = hostString;
|
|
32
59
|
port = parseInt(portString);
|
|
33
60
|
console.log(`${name} started on port ${port}`);
|
|
34
61
|
// Configure npm
|
|
35
|
-
const registry = `http
|
|
62
|
+
const registry = `http://${registryHost}:${port}`;
|
|
36
63
|
process.env['npm_config_registry'] = registry;
|
|
37
|
-
|
|
64
|
+
process.env['NPM_CONFIG_USERCONFIG'] = npmUserConfig;
|
|
65
|
+
process.env['npm_config_userconfig'] = npmUserConfig;
|
|
66
|
+
process.env['NPM_CONFIG_CACHE'] = npmCacheDir;
|
|
67
|
+
process.env['npm_config_cache'] = npmCacheDir;
|
|
68
|
+
(0, child_process_1.execSync)(`npm config set //${registryHost}:${port}/:_authToken "secretVerdaccioToken"`, { env: npmEnvironment });
|
|
38
69
|
// Configure yarn 1 and yarn 2
|
|
39
70
|
process.env['YARN_REGISTRY'] = registry;
|
|
40
71
|
process.env['YARN_NPM_REGISTRY_SERVER'] = registry;
|
|
41
|
-
process.env['YARN_UNSAFE_HTTP_WHITELIST'] = 'localhost';
|
|
72
|
+
process.env['YARN_UNSAFE_HTTP_WHITELIST'] = Array.from(new Set([registryHost, 'localhost', '127.0.0.1'])).join(',');
|
|
42
73
|
console.log(`Set npm and yarn config registry to ${registry}`);
|
|
43
74
|
};
|
|
44
75
|
// We delete the local npm configuration before the local registry will be stopped
|
|
45
|
-
const onStopping = () =>
|
|
76
|
+
const onStopping = () => {
|
|
77
|
+
if (port) {
|
|
78
|
+
try {
|
|
79
|
+
(0, child_process_1.execSync)(`npm config delete //${registryHost}:${port}/:_authToken`, { env: npmEnvironment });
|
|
80
|
+
}
|
|
81
|
+
catch (_a) {
|
|
82
|
+
// ignore cleanup errors
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
restoreEnvironmentVariables(envBeforeRegistry);
|
|
86
|
+
};
|
|
46
87
|
// We write a log message after the local registry was stopped
|
|
47
88
|
const onStopped = () => console.log(`${name} stopped successfully`);
|
|
48
|
-
|
|
89
|
+
const localRegistryProcess = yield (0, shared_util_1.createProcess)(require.resolve('nx/bin/nx'), [
|
|
49
90
|
...`run ${localRegistryTarget} --location none --clear true`.split(' '),
|
|
50
91
|
...(storage ? [`--storage`, storage] : []),
|
|
51
92
|
], {
|
|
@@ -57,7 +98,67 @@ function startLocalRegistry(localRegistryTarget, storage) {
|
|
|
57
98
|
background: false,
|
|
58
99
|
useFork: true,
|
|
59
100
|
});
|
|
101
|
+
yield ensureLocalRegistryAvailable(registryHost, port, localRegistryProcess);
|
|
102
|
+
return localRegistryProcess;
|
|
60
103
|
});
|
|
61
104
|
}
|
|
62
105
|
exports.startLocalRegistry = startLocalRegistry;
|
|
106
|
+
function ensureLocalRegistryAvailable(host, port, localRegistryProcess) {
|
|
107
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
if (!port) {
|
|
109
|
+
localRegistryProcess.stop();
|
|
110
|
+
throw new Error('Local registry did not provide a valid port');
|
|
111
|
+
}
|
|
112
|
+
const timeoutMs = 10000;
|
|
113
|
+
const pollIntervalMs = 250;
|
|
114
|
+
const started = Date.now();
|
|
115
|
+
const url = `http://${host}:${port}/-/ping`;
|
|
116
|
+
while (Date.now() - started < timeoutMs) {
|
|
117
|
+
try {
|
|
118
|
+
yield pingRegistry(host, port);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
catch (_a) {
|
|
122
|
+
yield delay(pollIntervalMs);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
localRegistryProcess.stop();
|
|
126
|
+
throw new Error(`Local registry is not reachable at ${url}`);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function pingRegistry(host, port) {
|
|
130
|
+
return new Promise((resolve, reject) => {
|
|
131
|
+
const req = (0, http_1.request)({
|
|
132
|
+
host,
|
|
133
|
+
port,
|
|
134
|
+
path: '/-/ping',
|
|
135
|
+
method: 'GET',
|
|
136
|
+
timeout: 2000,
|
|
137
|
+
}, (res) => {
|
|
138
|
+
res.resume();
|
|
139
|
+
if ((res.statusCode || 500) < 500) {
|
|
140
|
+
resolve();
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
reject(new Error(`Unexpected status code ${res.statusCode}`));
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
req.on('timeout', () => req.destroy(new Error('Ping timed out')));
|
|
147
|
+
req.on('error', reject);
|
|
148
|
+
req.end();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function delay(milliseconds) {
|
|
152
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
153
|
+
}
|
|
154
|
+
function restoreEnvironmentVariables(environmentVariables) {
|
|
155
|
+
for (const [key, value] of Object.entries(environmentVariables)) {
|
|
156
|
+
if (value === undefined) {
|
|
157
|
+
delete process.env[key];
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
process.env[key] = value;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
63
164
|
//# sourceMappingURL=local-registry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-registry.js","sourceRoot":"","sources":["../../../../../libs/shared-e2e/src/lib/local-registry.ts"],"names":[],"mappings":";;;;AAAA,iDAAyC;AACzC,wDAAuD;
|
|
1
|
+
{"version":3,"file":"local-registry.js","sourceRoot":"","sources":["../../../../../libs/shared-e2e/src/lib/local-registry.ts"],"names":[],"mappings":";;;;AAAA,iDAAyC;AACzC,wDAAuD;AACvD,2BAA2C;AAC3C,+BAA+B;AAC/B,+BAA4B;AAE5B,gKAAgK;AAChK,EAAE;AACF,qBAAqB;AACrB,EAAE;AACF,iCAAiC;AACjC,mBAAmB;AACnB,6CAA6C;AAC7C,EAAE;AACF,SAAsB,kBAAkB,CAAC,mBAA2B,EAAE,OAAe;;QACnF,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,IAAI,GAAG,gBAAgB,CAAC;QAC9B,MAAM,SAAS,GAAG,SAAS,CAAC;QAC5B,IAAI,YAAY,GAAG,WAAW,CAAC;QAC/B,IAAI,IAAwB,CAAC;QAC7B,MAAM,iBAAiB,GAAG;YACxB,mBAAmB,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;YACvD,qBAAqB,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;YAC3D,qBAAqB,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;YAC3D,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACjD,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACjD,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;YAC3C,wBAAwB,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;YACjE,0BAA0B,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;SACtE,CAAC;QAEF,MAAM,YAAY,GAAG,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;QAClE,MAAM,aAAa,GAAG,IAAA,WAAI,EAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAA,eAAU,EAAC,YAAY,CAAC;YAAE,IAAA,cAAS,EAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,IAAI,CAAC,IAAA,eAAU,EAAC,WAAW,CAAC;YAAE,IAAA,cAAS,EAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E,MAAM,cAAc,mCACf,OAAO,CAAC,GAAG,KACd,qBAAqB,EAAE,aAAa,EACpC,qBAAqB,EAAE,aAAa,EACpC,gBAAgB,EAAE,WAAW,EAC7B,gBAAgB,EAAE,WAAW,GAC9B,CAAC;QAEF,sFAAsF;QACtF,MAAM,OAAO,GAAG,CAAC,YAAoB,EAAE,EAAE;;YACvC,IAAI,CAAC,YAAY;gBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,gBAAgB,CAAC,CAAC;YAE5D,yFAAyF;YACzF,MAAM,aAAa,GAAG,MAAA,YAAY,CAAC,KAAK,CAAC,yCAAyC,CAAC,0CAAE,MAAM,CAAC;YAC5F,MAAM,UAAU,GAAG,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,MAAM,CAAC,CAAC;YAC3C,MAAM,UAAU,GAAG,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,MAAM,CAAC,CAAC;YAC3C,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YAC1D,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YAC1D,YAAY,GAAG,UAAU,CAAC;YAC1B,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,oBAAoB,IAAI,EAAE,CAAC,CAAC;YAE/C,gBAAgB;YAChB,MAAM,QAAQ,GAAG,UAAU,YAAY,IAAI,IAAI,EAAE,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,GAAG,QAAQ,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,GAAG,aAAa,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,GAAG,aAAa,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,WAAW,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,WAAW,CAAC;YAC9C,IAAA,wBAAQ,EAAC,oBAAoB,YAAY,IAAI,IAAI,qCAAqC,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC,CAAC;YAEjH,8BAA8B;YAC9B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,GAAG,QAAQ,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEpH,OAAO,CAAC,GAAG,CAAC,uCAAuC,QAAQ,EAAE,CAAC,CAAC;QACjE,CAAC,CAAC;QAEF,kFAAkF;QAClF,MAAM,UAAU,GAAG,GAAG,EAAE;YACtB,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC;oBACH,IAAA,wBAAQ,EAAC,uBAAuB,YAAY,IAAI,IAAI,cAAc,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC,CAAC;gBAC/F,CAAC;gBAAC,WAAM,CAAC;oBACP,wBAAwB;gBAC1B,CAAC;YACH,CAAC;YACD,2BAA2B,CAAC,iBAAiB,CAAC,CAAC;QACjD,CAAC,CAAC;QAEF,8DAA8D;QAC9D,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,uBAAuB,CAAC,CAAC;QAEpE,MAAM,oBAAoB,GAAG,MAAM,IAAA,2BAAa,EAC9C,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAC5B;YACE,GAAG,OAAO,mBAAmB,+BAA+B,CAAC,KAAK,CAAC,GAAG,CAAC;YACvE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3C,EACD;YACE,IAAI;YACJ,SAAS;YACT,OAAO;YACP,UAAU;YACV,SAAS;YACT,UAAU,EAAE,KAAK;YACjB,OAAO,EAAE,IAAI;SACd,CACF,CAAC;QAEF,MAAM,4BAA4B,CAAC,YAAY,EAAE,IAAI,EAAE,oBAAoB,CAAC,CAAC;QAC7E,OAAO,oBAAoB,CAAC;IAC9B,CAAC;CAAA;AAlGD,gDAkGC;AAED,SAAe,4BAA4B,CACzC,IAAY,EACZ,IAAwB,EACxB,oBAA0C;;QAE1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,oBAAoB,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,SAAS,GAAG,KAAM,CAAC;QACzB,MAAM,cAAc,GAAG,GAAG,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,UAAU,IAAI,IAAI,IAAI,SAAS,CAAC;QAE5C,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC;gBACH,MAAM,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC/B,OAAO;YACT,CAAC;YAAC,WAAM,CAAC;gBACP,MAAM,KAAK,CAAC,cAAc,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,oBAAoB,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,EAAE,CAAC,CAAC;IAC/D,CAAC;CAAA;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,IAAY;IAC9C,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,GAAG,GAAG,IAAA,cAAO,EACjB;YACE,IAAI;YACJ,IAAI;YACJ,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAK;SACf,EACD,CAAC,GAAG,EAAE,EAAE;YACN,GAAG,CAAC,MAAM,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;gBAClC,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAChE,CAAC;QACH,CAAC,CACF,CAAC;QAEF,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAClE,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,KAAK,CAAC,YAAoB;IACjC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,2BAA2B,CAAC,oBAAwD;IAC3F,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAChE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC"}
|