@multiplatform.one/vite-plugin-vscode 6.4.3 → 6.6.0
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/lib/index.cjs +37 -2
- package/lib/index.mjs +37 -3
- package/package.json +2 -2
- package/src/index.ts +53 -2
- package/types/index.d.ts +19 -1
- package/types/index.d.ts.map +1 -1
package/lib/index.cjs
CHANGED
|
@@ -66,9 +66,11 @@ async function createVscodeConfig(options) {
|
|
|
66
66
|
const workspaceRoot = options.workspaceRoot ?? (0, _multiplatform_one_utils_dev.lookupProjectRoot)();
|
|
67
67
|
const isDev = options.isDev ?? process.env.NODE_ENV !== "production";
|
|
68
68
|
const { tamaguiPlugin } = await import("@tamagui/vite-plugin");
|
|
69
|
+
const outputCSS = node_path.default.join(options.targetDir, "tamagui.css");
|
|
70
|
+
if (!node_fs.default.existsSync(outputCSS)) node_fs.default.writeFileSync(outputCSS, "/* generated by @tamagui/vite-plugin during build */\n");
|
|
69
71
|
return {
|
|
70
72
|
root: options.targetDir,
|
|
71
|
-
base:
|
|
73
|
+
base: "/",
|
|
72
74
|
build: {
|
|
73
75
|
outDir: options.outDir,
|
|
74
76
|
emptyOutDir: true,
|
|
@@ -177,10 +179,41 @@ async function createVscodeConfig(options) {
|
|
|
177
179
|
}
|
|
178
180
|
};
|
|
179
181
|
}
|
|
182
|
+
/** Correct the webview dist path baked into the extension-host bundle.
|
|
183
|
+
*
|
|
184
|
+
* @tomjs/vite-plugin-vscode computes `VITE_WEBVIEW_DIST` (the segment its
|
|
185
|
+
* runtime joins onto `context.extensionUri` to form the webview base URI)
|
|
186
|
+
* by stripping `process.cwd()` off the resolved outDir. That model assumes
|
|
187
|
+
* the extension is packaged from the vite project root; with an
|
|
188
|
+
* out-of-tree staging dir (ours: apps/<name>/dist-vscode + generated
|
|
189
|
+
* manifest) the strip misses and the BUILD MACHINE'S ABSOLUTE PATH gets
|
|
190
|
+
* baked into the bundle — at runtime the webview base URI doubles into
|
|
191
|
+
* `…/dist-vscode/Users/…/dist-vscode/webview` and every asset 404s.
|
|
192
|
+
*
|
|
193
|
+
* In the staging layout the correct value is always the literal
|
|
194
|
+
* `"webview"` (the assets dir next to the generated package.json), so the
|
|
195
|
+
* staging step rewrites the joinPath call site — anchored on the
|
|
196
|
+
* `.extensionUri` property read, which survives minification. */
|
|
197
|
+
async function fixWebviewDistPath(stagingDir) {
|
|
198
|
+
const bundles = ["extension/index.js", "extension/index.cjs"].map((file) => node_path.default.join(stagingDir, file));
|
|
199
|
+
let fixed = false;
|
|
200
|
+
for (const bundle of bundles) {
|
|
201
|
+
if (!node_fs.default.existsSync(bundle)) continue;
|
|
202
|
+
const source = await node_fs.default.promises.readFile(bundle, "utf-8");
|
|
203
|
+
const rewritten = source.replace(/joinPath\(([A-Za-z_$][\w$]*\.extensionUri),\s*("[^"\n]*"|'[^'\n]*'|`[^`\n]*`)\)/g, "joinPath($1, \"webview\")");
|
|
204
|
+
if (rewritten !== source) {
|
|
205
|
+
await node_fs.default.promises.writeFile(bundle, rewritten, "utf-8");
|
|
206
|
+
fixed = true;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return fixed;
|
|
210
|
+
}
|
|
180
211
|
/** Write the extension-manifest package.json into the staging dir. A VS
|
|
181
212
|
* Code extension's package.json IS its manifest — the product app's own
|
|
182
213
|
* package.json (an Expo/One app manifest) can't double as it, so `vsce
|
|
183
|
-
* package` runs against the staging dir instead.
|
|
214
|
+
* package` runs against the staging dir instead. Also applies
|
|
215
|
+
* `fixWebviewDistPath` — staging is the earliest race-free point after
|
|
216
|
+
* the plugin's detached extension-host build has finished. */
|
|
184
217
|
async function writeVsceManifest(stagingDir, manifest) {
|
|
185
218
|
const { engines, main, ...rest } = manifest;
|
|
186
219
|
const packageJson = {
|
|
@@ -193,10 +226,12 @@ async function writeVsceManifest(stagingDir, manifest) {
|
|
|
193
226
|
};
|
|
194
227
|
await node_fs.default.promises.mkdir(stagingDir, { recursive: true });
|
|
195
228
|
await node_fs.default.promises.writeFile(node_path.default.join(stagingDir, "package.json"), `${JSON.stringify(packageJson, null, 2)}\n`, "utf-8");
|
|
229
|
+
await fixWebviewDistPath(stagingDir);
|
|
196
230
|
}
|
|
197
231
|
|
|
198
232
|
//#endregion
|
|
199
233
|
exports.DEFAULT_WEBVIEW_CSP = DEFAULT_WEBVIEW_CSP;
|
|
200
234
|
exports.createVscodeConfig = createVscodeConfig;
|
|
235
|
+
exports.fixWebviewDistPath = fixWebviewDistPath;
|
|
201
236
|
exports.resolveSeamOneAdapter = resolveSeamOneAdapter;
|
|
202
237
|
exports.writeVsceManifest = writeVsceManifest;
|
package/lib/index.mjs
CHANGED
|
@@ -34,9 +34,11 @@ async function createVscodeConfig(options) {
|
|
|
34
34
|
const workspaceRoot = options.workspaceRoot ?? lookupProjectRoot();
|
|
35
35
|
const isDev = options.isDev ?? process.env.NODE_ENV !== "production";
|
|
36
36
|
const { tamaguiPlugin } = await import("@tamagui/vite-plugin");
|
|
37
|
+
const outputCSS = path.join(options.targetDir, "tamagui.css");
|
|
38
|
+
if (!fs.existsSync(outputCSS)) fs.writeFileSync(outputCSS, "/* generated by @tamagui/vite-plugin during build */\n");
|
|
37
39
|
return {
|
|
38
40
|
root: options.targetDir,
|
|
39
|
-
base:
|
|
41
|
+
base: "/",
|
|
40
42
|
build: {
|
|
41
43
|
outDir: options.outDir,
|
|
42
44
|
emptyOutDir: true,
|
|
@@ -145,10 +147,41 @@ async function createVscodeConfig(options) {
|
|
|
145
147
|
}
|
|
146
148
|
};
|
|
147
149
|
}
|
|
150
|
+
/** Correct the webview dist path baked into the extension-host bundle.
|
|
151
|
+
*
|
|
152
|
+
* @tomjs/vite-plugin-vscode computes `VITE_WEBVIEW_DIST` (the segment its
|
|
153
|
+
* runtime joins onto `context.extensionUri` to form the webview base URI)
|
|
154
|
+
* by stripping `process.cwd()` off the resolved outDir. That model assumes
|
|
155
|
+
* the extension is packaged from the vite project root; with an
|
|
156
|
+
* out-of-tree staging dir (ours: apps/<name>/dist-vscode + generated
|
|
157
|
+
* manifest) the strip misses and the BUILD MACHINE'S ABSOLUTE PATH gets
|
|
158
|
+
* baked into the bundle — at runtime the webview base URI doubles into
|
|
159
|
+
* `…/dist-vscode/Users/…/dist-vscode/webview` and every asset 404s.
|
|
160
|
+
*
|
|
161
|
+
* In the staging layout the correct value is always the literal
|
|
162
|
+
* `"webview"` (the assets dir next to the generated package.json), so the
|
|
163
|
+
* staging step rewrites the joinPath call site — anchored on the
|
|
164
|
+
* `.extensionUri` property read, which survives minification. */
|
|
165
|
+
async function fixWebviewDistPath(stagingDir) {
|
|
166
|
+
const bundles = ["extension/index.js", "extension/index.cjs"].map((file) => path.join(stagingDir, file));
|
|
167
|
+
let fixed = false;
|
|
168
|
+
for (const bundle of bundles) {
|
|
169
|
+
if (!fs.existsSync(bundle)) continue;
|
|
170
|
+
const source = await fs.promises.readFile(bundle, "utf-8");
|
|
171
|
+
const rewritten = source.replace(/joinPath\(([A-Za-z_$][\w$]*\.extensionUri),\s*("[^"\n]*"|'[^'\n]*'|`[^`\n]*`)\)/g, "joinPath($1, \"webview\")");
|
|
172
|
+
if (rewritten !== source) {
|
|
173
|
+
await fs.promises.writeFile(bundle, rewritten, "utf-8");
|
|
174
|
+
fixed = true;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return fixed;
|
|
178
|
+
}
|
|
148
179
|
/** Write the extension-manifest package.json into the staging dir. A VS
|
|
149
180
|
* Code extension's package.json IS its manifest — the product app's own
|
|
150
181
|
* package.json (an Expo/One app manifest) can't double as it, so `vsce
|
|
151
|
-
* package` runs against the staging dir instead.
|
|
182
|
+
* package` runs against the staging dir instead. Also applies
|
|
183
|
+
* `fixWebviewDistPath` — staging is the earliest race-free point after
|
|
184
|
+
* the plugin's detached extension-host build has finished. */
|
|
152
185
|
async function writeVsceManifest(stagingDir, manifest) {
|
|
153
186
|
const { engines, main, ...rest } = manifest;
|
|
154
187
|
const packageJson = {
|
|
@@ -161,7 +194,8 @@ async function writeVsceManifest(stagingDir, manifest) {
|
|
|
161
194
|
};
|
|
162
195
|
await fs.promises.mkdir(stagingDir, { recursive: true });
|
|
163
196
|
await fs.promises.writeFile(path.join(stagingDir, "package.json"), `${JSON.stringify(packageJson, null, 2)}\n`, "utf-8");
|
|
197
|
+
await fixWebviewDistPath(stagingDir);
|
|
164
198
|
}
|
|
165
199
|
|
|
166
200
|
//#endregion
|
|
167
|
-
export { DEFAULT_WEBVIEW_CSP, createVscodeConfig, resolveSeamOneAdapter, writeVsceManifest };
|
|
201
|
+
export { DEFAULT_WEBVIEW_CSP, createVscodeConfig, fixWebviewDistPath, resolveSeamOneAdapter, writeVsceManifest };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplatform.one/vite-plugin-vscode",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.6.0",
|
|
4
4
|
"description": "Vite config factory for building a VS Code extension (extension host + Tamagui webview) as a target of a multiplatform.one One app — wraps @tomjs/vite-plugin-vscode with the workspace source aliases, the one-router seam alias, React dedupe against one's vendored copy, and a vsce staging-manifest writer.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"multiplatform.one",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@multiplatform.one/utils": "6.
|
|
49
|
+
"@multiplatform.one/utils": "6.6.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@tamagui/vite-plugin": "2.0.0-rc.41",
|
package/src/index.ts
CHANGED
|
@@ -85,9 +85,20 @@ export async function createVscodeConfig(options: VscodeTargetOptions): Promise<
|
|
|
85
85
|
const workspaceRoot = options.workspaceRoot ?? lookupProjectRoot();
|
|
86
86
|
const isDev = options.isDev ?? process.env.NODE_ENV !== "production";
|
|
87
87
|
const { tamaguiPlugin } = await import("@tamagui/vite-plugin");
|
|
88
|
+
// The webview entry imports tamagui.css, but the tamagui plugin only
|
|
89
|
+
// writes outputCSS DURING the build — seed it so a fresh clone's first
|
|
90
|
+
// build doesn't die on an unresolvable import.
|
|
91
|
+
const outputCSS = path.join(options.targetDir, "tamagui.css");
|
|
92
|
+
if (!fs.existsSync(outputCSS)) {
|
|
93
|
+
fs.writeFileSync(outputCSS, "/* generated by @tamagui/vite-plugin during build */\n");
|
|
94
|
+
}
|
|
88
95
|
return {
|
|
89
96
|
root: options.targetDir,
|
|
90
|
-
|
|
97
|
+
// Always root-absolute: the vscode plugin rewrites built asset URLs as
|
|
98
|
+
// `{{baseUri}}${attr}` (string concatenation), so a "./"-relative base
|
|
99
|
+
// would produce `<baseUri>./assets/…` — a literal `webview./assets`
|
|
100
|
+
// path segment the webview resource host 404s.
|
|
101
|
+
base: "/",
|
|
91
102
|
build: {
|
|
92
103
|
outDir: options.outDir,
|
|
93
104
|
emptyOutDir: true,
|
|
@@ -213,10 +224,49 @@ export interface VsceManifest {
|
|
|
213
224
|
license?: string;
|
|
214
225
|
}
|
|
215
226
|
|
|
227
|
+
/** Correct the webview dist path baked into the extension-host bundle.
|
|
228
|
+
*
|
|
229
|
+
* @tomjs/vite-plugin-vscode computes `VITE_WEBVIEW_DIST` (the segment its
|
|
230
|
+
* runtime joins onto `context.extensionUri` to form the webview base URI)
|
|
231
|
+
* by stripping `process.cwd()` off the resolved outDir. That model assumes
|
|
232
|
+
* the extension is packaged from the vite project root; with an
|
|
233
|
+
* out-of-tree staging dir (ours: apps/<name>/dist-vscode + generated
|
|
234
|
+
* manifest) the strip misses and the BUILD MACHINE'S ABSOLUTE PATH gets
|
|
235
|
+
* baked into the bundle — at runtime the webview base URI doubles into
|
|
236
|
+
* `…/dist-vscode/Users/…/dist-vscode/webview` and every asset 404s.
|
|
237
|
+
*
|
|
238
|
+
* In the staging layout the correct value is always the literal
|
|
239
|
+
* `"webview"` (the assets dir next to the generated package.json), so the
|
|
240
|
+
* staging step rewrites the joinPath call site — anchored on the
|
|
241
|
+
* `.extensionUri` property read, which survives minification. */
|
|
242
|
+
export async function fixWebviewDistPath(stagingDir: string): Promise<boolean> {
|
|
243
|
+
const bundles = ["extension/index.js", "extension/index.cjs"].map((file) =>
|
|
244
|
+
path.join(stagingDir, file),
|
|
245
|
+
);
|
|
246
|
+
let fixed = false;
|
|
247
|
+
for (const bundle of bundles) {
|
|
248
|
+
if (!fs.existsSync(bundle)) continue;
|
|
249
|
+
const source = await fs.promises.readFile(bundle, "utf-8");
|
|
250
|
+
const rewritten = source.replace(
|
|
251
|
+
// The dist segment may be emitted as a quoted string OR a template
|
|
252
|
+
// literal (tsdown's env define does both depending on content).
|
|
253
|
+
/joinPath\(([A-Za-z_$][\w$]*\.extensionUri),\s*("[^"\n]*"|'[^'\n]*'|`[^`\n]*`)\)/g,
|
|
254
|
+
'joinPath($1, "webview")',
|
|
255
|
+
);
|
|
256
|
+
if (rewritten !== source) {
|
|
257
|
+
await fs.promises.writeFile(bundle, rewritten, "utf-8");
|
|
258
|
+
fixed = true;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return fixed;
|
|
262
|
+
}
|
|
263
|
+
|
|
216
264
|
/** Write the extension-manifest package.json into the staging dir. A VS
|
|
217
265
|
* Code extension's package.json IS its manifest — the product app's own
|
|
218
266
|
* package.json (an Expo/One app manifest) can't double as it, so `vsce
|
|
219
|
-
* package` runs against the staging dir instead.
|
|
267
|
+
* package` runs against the staging dir instead. Also applies
|
|
268
|
+
* `fixWebviewDistPath` — staging is the earliest race-free point after
|
|
269
|
+
* the plugin's detached extension-host build has finished. */
|
|
220
270
|
export async function writeVsceManifest(stagingDir: string, manifest: VsceManifest): Promise<void> {
|
|
221
271
|
const { engines, main, ...rest } = manifest;
|
|
222
272
|
const packageJson = {
|
|
@@ -230,4 +280,5 @@ export async function writeVsceManifest(stagingDir: string, manifest: VsceManife
|
|
|
230
280
|
`${JSON.stringify(packageJson, null, 2)}\n`,
|
|
231
281
|
"utf-8",
|
|
232
282
|
);
|
|
283
|
+
await fixWebviewDistPath(stagingDir);
|
|
233
284
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -49,9 +49,27 @@ export interface VsceManifest {
|
|
|
49
49
|
repository?: unknown;
|
|
50
50
|
license?: string;
|
|
51
51
|
}
|
|
52
|
+
/** Correct the webview dist path baked into the extension-host bundle.
|
|
53
|
+
*
|
|
54
|
+
* @tomjs/vite-plugin-vscode computes `VITE_WEBVIEW_DIST` (the segment its
|
|
55
|
+
* runtime joins onto `context.extensionUri` to form the webview base URI)
|
|
56
|
+
* by stripping `process.cwd()` off the resolved outDir. That model assumes
|
|
57
|
+
* the extension is packaged from the vite project root; with an
|
|
58
|
+
* out-of-tree staging dir (ours: apps/<name>/dist-vscode + generated
|
|
59
|
+
* manifest) the strip misses and the BUILD MACHINE'S ABSOLUTE PATH gets
|
|
60
|
+
* baked into the bundle — at runtime the webview base URI doubles into
|
|
61
|
+
* `…/dist-vscode/Users/…/dist-vscode/webview` and every asset 404s.
|
|
62
|
+
*
|
|
63
|
+
* In the staging layout the correct value is always the literal
|
|
64
|
+
* `"webview"` (the assets dir next to the generated package.json), so the
|
|
65
|
+
* staging step rewrites the joinPath call site — anchored on the
|
|
66
|
+
* `.extensionUri` property read, which survives minification. */
|
|
67
|
+
export declare function fixWebviewDistPath(stagingDir: string): Promise<boolean>;
|
|
52
68
|
/** Write the extension-manifest package.json into the staging dir. A VS
|
|
53
69
|
* Code extension's package.json IS its manifest — the product app's own
|
|
54
70
|
* package.json (an Expo/One app manifest) can't double as it, so `vsce
|
|
55
|
-
* package` runs against the staging dir instead.
|
|
71
|
+
* package` runs against the staging dir instead. Also applies
|
|
72
|
+
* `fixWebviewDistPath` — staging is the earliest race-free point after
|
|
73
|
+
* the plugin's detached extension-host build has finished. */
|
|
56
74
|
export declare function writeVsceManifest(stagingDir: string, manifest: VsceManifest): Promise<void>;
|
|
57
75
|
//# sourceMappingURL=index.d.ts.map
|
package/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,KAAK,EAAU,UAAU,EAAE,MAAM,MAAM,CAAC;AAEtD;;;0CAG0C;AAC1C,eAAO,MAAM,mBAAmB,yRAAqR,CAAC;AAEtT,MAAM,WAAW,mBAAmB;IAClC;kCAC8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB;kEAC8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;CACnB;AAgBD;kEACkE;AAClE,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAInE;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,KAAK,EAAU,UAAU,EAAE,MAAM,MAAM,CAAC;AAEtD;;;0CAG0C;AAC1C,eAAO,MAAM,mBAAmB,yRAAqR,CAAC;AAEtT,MAAM,WAAW,mBAAmB;IAClC;kCAC8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB;kEAC8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;CACnB;AAgBD;kEACkE;AAClE,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAInE;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAuH1F;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC7B,2CAA2C;IAC3C,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACpD,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;kEAckE;AAClE,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoB7E;AAED;;;;;+DAK+D;AAC/D,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAcjG"}
|