@serwist/build 9.0.0-preview.0 → 9.0.0-preview.10
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/chunks/glob.js +0 -2
- package/dist/chunks/serwist-config-error.js +1 -4
- package/dist/chunks/webpack.js +1 -2
- package/dist/index.js +10 -216
- package/dist/index.next.js +5 -2
- package/dist/lib/errors.d.ts +0 -3
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/get-file-details.d.ts +2 -2
- package/dist/lib/get-file-details.d.ts.map +1 -1
- package/dist/schema/assertType.d.ts +3 -0
- package/dist/schema/assertType.d.ts.map +1 -0
- package/dist/schema/base.d.ts.map +1 -1
- package/dist/schema/getManifest.d.ts.map +1 -1
- package/dist/schema/glob.d.ts.map +1 -1
- package/dist/schema/injectManifest.d.ts.map +1 -1
- package/dist/schema/next.d.ts +12 -15
- package/dist/schema/next.d.ts.map +1 -1
- package/dist/schema/swDest.d.ts.map +1 -1
- package/dist/schema/vite.d.ts.map +1 -1
- package/dist/schema/webpack.d.ts +0 -6
- package/dist/schema/webpack.d.ts.map +1 -1
- package/dist/types.d.ts +9 -16
- package/dist/types.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/lib/errors.ts +0 -6
- package/src/lib/get-file-details.ts +5 -5
- package/src/lib/get-file-manifest-entries.ts +4 -4
- package/src/schema/assertType.ts +5 -0
- package/src/schema/base.ts +5 -1
- package/src/schema/getManifest.ts +5 -6
- package/src/schema/glob.ts +11 -11
- package/src/schema/injectManifest.ts +8 -6
- package/src/schema/next.ts +10 -12
- package/src/schema/swDest.ts +8 -2
- package/src/schema/vite.ts +5 -5
- package/src/schema/webpack.ts +11 -12
- package/src/types.ts +9 -16
- package/src/_types.js +0 -112
package/dist/chunks/glob.js
CHANGED
|
@@ -51,8 +51,6 @@ const globPartial = z.object({
|
|
|
51
51
|
z.object({
|
|
52
52
|
globDirectory: z.string().optional()
|
|
53
53
|
}).strict("Do not pass invalid properties to OptionalGlobDirectoryPartial!");
|
|
54
|
-
// This needs to be set when using GetManifest or InjectManifest. This is
|
|
55
|
-
// enforced via runtime validation, and needs to be documented.
|
|
56
54
|
const requiredGlobDirectoryPartial = z.object({
|
|
57
55
|
globDirectory: z.string()
|
|
58
56
|
}).strict("Do not pass invalid properties to RequiredGlobDirectoryPartial!");
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
3
|
const validationErrorMap = (error, ctx)=>{
|
|
4
|
-
|
|
5
|
-
This is where you override the various error codes
|
|
6
|
-
*/ switch(error.code){
|
|
4
|
+
switch(error.code){
|
|
7
5
|
case z.ZodIssueCode.invalid_type:
|
|
8
6
|
{
|
|
9
7
|
return {
|
|
@@ -41,7 +39,6 @@ const validationErrorMap = (error, ctx)=>{
|
|
|
41
39
|
};
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
|
-
// Fallback to the default message.
|
|
45
42
|
return {
|
|
46
43
|
message: ctx.defaultError
|
|
47
44
|
};
|
package/dist/chunks/webpack.js
CHANGED
|
@@ -21,8 +21,7 @@ const webpackPartial = z.object({
|
|
|
21
21
|
z.function(z.tuple([
|
|
22
22
|
z.any()
|
|
23
23
|
]), z.boolean())
|
|
24
|
-
])).optional()
|
|
25
|
-
mode: z.string().nullable().optional()
|
|
24
|
+
])).optional()
|
|
26
25
|
}).strict("Do not pass invalid properties to WebpackPartial!");
|
|
27
26
|
const webpackInjectManifestPartial = z.object({
|
|
28
27
|
compileSrc: z.boolean().default(true),
|
package/dist/index.js
CHANGED
|
@@ -3,9 +3,10 @@ export { default as stringify } from 'fast-json-stable-stringify';
|
|
|
3
3
|
import assert from 'assert';
|
|
4
4
|
import { oneLine } from 'common-tags';
|
|
5
5
|
import crypto from 'crypto';
|
|
6
|
-
import {
|
|
6
|
+
import { globSync } from 'glob';
|
|
7
7
|
import upath from 'upath';
|
|
8
8
|
import fse from 'fs-extra';
|
|
9
|
+
import prettyBytes from 'pretty-bytes';
|
|
9
10
|
import { v as validationErrorMap, S as SerwistConfigError } from './chunks/serwist-config-error.js';
|
|
10
11
|
import { SourceMapGenerator, SourceMapConsumer } from 'source-map';
|
|
11
12
|
import 'zod';
|
|
@@ -74,12 +75,6 @@ const errors = {
|
|
|
74
75
|
Please remove or fix the following: `,
|
|
75
76
|
"bad-template-urls-asset": oneLine`There was an issue using one of the provided
|
|
76
77
|
'templatedURLs'.`,
|
|
77
|
-
"invalid-runtime-caching": oneLine`The 'runtimeCaching' parameter must an an
|
|
78
|
-
array of objects with at least a 'urlPattern' and 'handler'.`,
|
|
79
|
-
"urlPattern-is-required": oneLine`The 'urlPattern' option is required when using
|
|
80
|
-
'runtimeCaching'.`,
|
|
81
|
-
"handler-is-required": oneLine`The 'handler' option is required when using
|
|
82
|
-
runtimeCaching.`,
|
|
83
78
|
"invalid-generate-file-manifest-arg": oneLine`The input to generateFileManifest()
|
|
84
79
|
must be an Object.`,
|
|
85
80
|
"invalid-sw-src": `The 'swSrc' file can't be read.`,
|
|
@@ -144,11 +139,11 @@ function getFileSize(file) {
|
|
|
144
139
|
}
|
|
145
140
|
}
|
|
146
141
|
|
|
147
|
-
|
|
142
|
+
const getFileDetails = ({ globDirectory, globFollow, globIgnores, globPattern })=>{
|
|
148
143
|
let globbedFiles;
|
|
149
144
|
let warning = "";
|
|
150
145
|
try {
|
|
151
|
-
globbedFiles =
|
|
146
|
+
globbedFiles = globSync(globPattern, {
|
|
152
147
|
cwd: globDirectory,
|
|
153
148
|
follow: globFollow,
|
|
154
149
|
ignore: globIgnores
|
|
@@ -180,7 +175,7 @@ function getFileDetails({ globDirectory, globFollow, globIgnores, globPattern })
|
|
|
180
175
|
globbedFileDetails,
|
|
181
176
|
warning
|
|
182
177
|
};
|
|
183
|
-
}
|
|
178
|
+
};
|
|
184
179
|
|
|
185
180
|
function getStringDetails(url, str) {
|
|
186
181
|
return {
|
|
@@ -195,8 +190,6 @@ const additionalPrecacheEntriesTransform = (additionalPrecacheEntries)=>{
|
|
|
195
190
|
const warnings = [];
|
|
196
191
|
const stringEntries = new Set();
|
|
197
192
|
for (const additionalEntry of additionalPrecacheEntries){
|
|
198
|
-
// Warn about either a string or an object that lacks a revision property.
|
|
199
|
-
// (An object with a revision property set to null is okay.)
|
|
200
193
|
if (typeof additionalEntry === "string") {
|
|
201
194
|
stringEntries.add(additionalEntry);
|
|
202
195
|
manifest.push({
|
|
@@ -227,110 +220,6 @@ const additionalPrecacheEntriesTransform = (additionalPrecacheEntries)=>{
|
|
|
227
220
|
};
|
|
228
221
|
};
|
|
229
222
|
|
|
230
|
-
const BYTE_UNITS = [
|
|
231
|
-
'B',
|
|
232
|
-
'kB',
|
|
233
|
-
'MB',
|
|
234
|
-
'GB',
|
|
235
|
-
'TB',
|
|
236
|
-
'PB',
|
|
237
|
-
'EB',
|
|
238
|
-
'ZB',
|
|
239
|
-
'YB'
|
|
240
|
-
];
|
|
241
|
-
const BIBYTE_UNITS = [
|
|
242
|
-
'B',
|
|
243
|
-
'KiB',
|
|
244
|
-
'MiB',
|
|
245
|
-
'GiB',
|
|
246
|
-
'TiB',
|
|
247
|
-
'PiB',
|
|
248
|
-
'EiB',
|
|
249
|
-
'ZiB',
|
|
250
|
-
'YiB'
|
|
251
|
-
];
|
|
252
|
-
const BIT_UNITS = [
|
|
253
|
-
'b',
|
|
254
|
-
'kbit',
|
|
255
|
-
'Mbit',
|
|
256
|
-
'Gbit',
|
|
257
|
-
'Tbit',
|
|
258
|
-
'Pbit',
|
|
259
|
-
'Ebit',
|
|
260
|
-
'Zbit',
|
|
261
|
-
'Ybit'
|
|
262
|
-
];
|
|
263
|
-
const BIBIT_UNITS = [
|
|
264
|
-
'b',
|
|
265
|
-
'kibit',
|
|
266
|
-
'Mibit',
|
|
267
|
-
'Gibit',
|
|
268
|
-
'Tibit',
|
|
269
|
-
'Pibit',
|
|
270
|
-
'Eibit',
|
|
271
|
-
'Zibit',
|
|
272
|
-
'Yibit'
|
|
273
|
-
];
|
|
274
|
-
/*
|
|
275
|
-
Formats the given number using `Number#toLocaleString`.
|
|
276
|
-
- If locale is a string, the value is expected to be a locale-key (for example: `de`).
|
|
277
|
-
- If locale is true, the system default locale is used for translation.
|
|
278
|
-
- If no value for locale is specified, the number is returned unmodified.
|
|
279
|
-
*/ const toLocaleString = (number, locale, options)=>{
|
|
280
|
-
let result = number;
|
|
281
|
-
if (typeof locale === 'string' || Array.isArray(locale)) {
|
|
282
|
-
result = number.toLocaleString(locale, options);
|
|
283
|
-
} else if (locale === true || options !== undefined) {
|
|
284
|
-
result = number.toLocaleString(undefined, options);
|
|
285
|
-
}
|
|
286
|
-
return result;
|
|
287
|
-
};
|
|
288
|
-
function prettyBytes(number, options) {
|
|
289
|
-
if (!Number.isFinite(number)) {
|
|
290
|
-
throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`);
|
|
291
|
-
}
|
|
292
|
-
options = {
|
|
293
|
-
bits: false,
|
|
294
|
-
binary: false,
|
|
295
|
-
space: true,
|
|
296
|
-
...options
|
|
297
|
-
};
|
|
298
|
-
const UNITS = options.bits ? options.binary ? BIBIT_UNITS : BIT_UNITS : options.binary ? BIBYTE_UNITS : BYTE_UNITS;
|
|
299
|
-
const separator = options.space ? ' ' : '';
|
|
300
|
-
if (options.signed && number === 0) {
|
|
301
|
-
return ` 0${separator}${UNITS[0]}`;
|
|
302
|
-
}
|
|
303
|
-
const isNegative = number < 0;
|
|
304
|
-
const prefix = isNegative ? '-' : options.signed ? '+' : '';
|
|
305
|
-
if (isNegative) {
|
|
306
|
-
number = -number;
|
|
307
|
-
}
|
|
308
|
-
let localeOptions;
|
|
309
|
-
if (options.minimumFractionDigits !== undefined) {
|
|
310
|
-
localeOptions = {
|
|
311
|
-
minimumFractionDigits: options.minimumFractionDigits
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
if (options.maximumFractionDigits !== undefined) {
|
|
315
|
-
localeOptions = {
|
|
316
|
-
maximumFractionDigits: options.maximumFractionDigits,
|
|
317
|
-
...localeOptions
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
if (number < 1) {
|
|
321
|
-
const numberString = toLocaleString(number, options.locale, localeOptions);
|
|
322
|
-
return prefix + numberString + separator + UNITS[0];
|
|
323
|
-
}
|
|
324
|
-
const exponent = Math.min(Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3), UNITS.length - 1);
|
|
325
|
-
number /= (options.binary ? 1024 : 1000) ** exponent;
|
|
326
|
-
if (!localeOptions) {
|
|
327
|
-
number = number.toPrecision(3);
|
|
328
|
-
}
|
|
329
|
-
const numberString = toLocaleString(Number(number), options.locale, localeOptions);
|
|
330
|
-
const unit = UNITS[exponent];
|
|
331
|
-
return prefix + numberString + separator + unit;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
223
|
function maximumSizeTransform(maximumFileSizeToCacheInBytes) {
|
|
335
224
|
return (originalManifest)=>{
|
|
336
225
|
const warnings = [];
|
|
@@ -348,13 +237,6 @@ function maximumSizeTransform(maximumFileSizeToCacheInBytes) {
|
|
|
348
237
|
};
|
|
349
238
|
}
|
|
350
239
|
|
|
351
|
-
/*
|
|
352
|
-
Copyright 2019 Google LLC
|
|
353
|
-
|
|
354
|
-
Use of this source code is governed by an MIT-style
|
|
355
|
-
license that can be found in the LICENSE file or at
|
|
356
|
-
https://opensource.org/licenses/MIT.
|
|
357
|
-
*/ // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
|
|
358
240
|
const escapeRegExp = (str)=>{
|
|
359
241
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
360
242
|
};
|
|
@@ -363,8 +245,6 @@ function modifyURLPrefixTransform(modifyURLPrefix) {
|
|
|
363
245
|
if (!modifyURLPrefix || typeof modifyURLPrefix !== "object" || Array.isArray(modifyURLPrefix)) {
|
|
364
246
|
throw new Error(errors["modify-url-prefix-bad-prefixes"]);
|
|
365
247
|
}
|
|
366
|
-
// If there are no entries in modifyURLPrefix, just return an identity
|
|
367
|
-
// function as a shortcut.
|
|
368
248
|
if (Object.keys(modifyURLPrefix).length === 0) {
|
|
369
249
|
return (manifest)=>{
|
|
370
250
|
return {
|
|
@@ -377,12 +257,8 @@ function modifyURLPrefixTransform(modifyURLPrefix) {
|
|
|
377
257
|
throw new Error(errors["modify-url-prefix-bad-prefixes"]);
|
|
378
258
|
}
|
|
379
259
|
}
|
|
380
|
-
// Escape the user input so it's safe to use in a regex.
|
|
381
260
|
const safeModifyURLPrefixes = Object.keys(modifyURLPrefix).map(escapeRegExp);
|
|
382
|
-
// Join all the `modifyURLPrefix` keys so a single regex can be used.
|
|
383
261
|
const prefixMatchesStrings = safeModifyURLPrefixes.join("|");
|
|
384
|
-
// Add `^` to the front the prefix matches so it only matches the start of
|
|
385
|
-
// a string.
|
|
386
262
|
const modifyRegex = new RegExp(`^(${prefixMatchesStrings})`);
|
|
387
263
|
return (originalManifest)=>{
|
|
388
264
|
const manifest = originalManifest.map((entry)=>{
|
|
@@ -430,8 +306,6 @@ async function transformManifest({ additionalPrecacheEntries, dontCacheBustURLsM
|
|
|
430
306
|
};
|
|
431
307
|
}
|
|
432
308
|
const allWarnings = [];
|
|
433
|
-
// Take the array of fileDetail objects and convert it into an array of
|
|
434
|
-
// {url, revision, size} objects, with \ replaced with /.
|
|
435
309
|
const normalizedManifest = fileDetails.map((fileDetails)=>{
|
|
436
310
|
return {
|
|
437
311
|
url: fileDetails.file.replace(/\\/g, "/"),
|
|
@@ -449,11 +323,9 @@ async function transformManifest({ additionalPrecacheEntries, dontCacheBustURLsM
|
|
|
449
323
|
if (dontCacheBustURLsMatching) {
|
|
450
324
|
transformsToApply.push(noRevisionForURLsMatchingTransform(dontCacheBustURLsMatching));
|
|
451
325
|
}
|
|
452
|
-
// Run any manifestTransforms functions second-to-last.
|
|
453
326
|
if (manifestTransforms) {
|
|
454
327
|
transformsToApply.push(...manifestTransforms);
|
|
455
328
|
}
|
|
456
|
-
// Run additionalPrecacheEntriesTransform last.
|
|
457
329
|
if (additionalPrecacheEntries) {
|
|
458
330
|
transformsToApply.push(additionalPrecacheEntriesTransform(additionalPrecacheEntries));
|
|
459
331
|
}
|
|
@@ -466,13 +338,10 @@ async function transformManifest({ additionalPrecacheEntries, dontCacheBustURLsM
|
|
|
466
338
|
transformedManifest = result.manifest;
|
|
467
339
|
allWarnings.push(...result.warnings || []);
|
|
468
340
|
}
|
|
469
|
-
// Generate some metadata about the manifest before we clear out the size
|
|
470
|
-
// properties from each entry.
|
|
471
341
|
const count = transformedManifest.length;
|
|
472
342
|
let size = 0;
|
|
473
343
|
for (const manifestEntry of transformedManifest){
|
|
474
344
|
size += manifestEntry.size || 0;
|
|
475
|
-
// biome-ignore lint/performance/noDelete: I don't understand this part yet.
|
|
476
345
|
delete manifestEntry.size;
|
|
477
346
|
}
|
|
478
347
|
return {
|
|
@@ -513,8 +382,6 @@ async function getFileManifestEntries({ additionalPrecacheEntries, dontCacheBust
|
|
|
513
382
|
}
|
|
514
383
|
}
|
|
515
384
|
} catch (error) {
|
|
516
|
-
// If there's an exception thrown while globbing, then report
|
|
517
|
-
// it back as a warning, and don't consider it fatal.
|
|
518
385
|
if (error instanceof Error && error.message) {
|
|
519
386
|
warnings.push(error.message);
|
|
520
387
|
}
|
|
@@ -540,11 +407,11 @@ async function getFileManifestEntries({ additionalPrecacheEntries, dontCacheBust
|
|
|
540
407
|
} catch (error) {
|
|
541
408
|
const debugObj = {};
|
|
542
409
|
debugObj[url] = dependencies;
|
|
543
|
-
throw new Error(`${errors["bad-template-urls-asset"]}
|
|
410
|
+
throw new Error(`${errors["bad-template-urls-asset"]} '${globPattern}' from '${JSON.stringify(debugObj)}':\n${error instanceof Error ? error.toString() : ""}`);
|
|
544
411
|
}
|
|
545
412
|
}, []);
|
|
546
413
|
if (details.length === 0) {
|
|
547
|
-
throw new Error(`${errors["bad-template-urls-asset"]} The glob
|
|
414
|
+
throw new Error(`${errors["bad-template-urls-asset"]} The glob pattern '${dependencies.toString()}' did not match anything.`);
|
|
548
415
|
}
|
|
549
416
|
allFileDetails.set(url, getCompositeDetails(url, details));
|
|
550
417
|
} else if (typeof dependencies === "string") {
|
|
@@ -614,34 +481,11 @@ const validateViteInjectManifestOptions = async (input)=>{
|
|
|
614
481
|
return result.data;
|
|
615
482
|
};
|
|
616
483
|
|
|
617
|
-
|
|
618
|
-
* This method returns a list of URLs to precache, referred to as a "precache
|
|
619
|
-
* manifest", along with details about the number of entries and their size,
|
|
620
|
-
* based on the options you provide.
|
|
621
|
-
*
|
|
622
|
-
* ```
|
|
623
|
-
* // The following lists some common options; see the rest of the documentation
|
|
624
|
-
* // for the full set of options and defaults.
|
|
625
|
-
* const {count, manifestEntries, size, warnings} = await getManifest({
|
|
626
|
-
* dontCacheBustURLsMatching: [new RegExp('...')],
|
|
627
|
-
* globDirectory: '...',
|
|
628
|
-
* globPatterns: ['...', '...'],
|
|
629
|
-
* maximumFileSizeToCacheInBytes: ...,
|
|
630
|
-
* });
|
|
631
|
-
* ```
|
|
632
|
-
*/ const getManifest = async (config)=>{
|
|
484
|
+
const getManifest = async (config)=>{
|
|
633
485
|
const options = await validateGetManifestOptions(config);
|
|
634
486
|
return await getFileManifestEntries(options);
|
|
635
487
|
};
|
|
636
488
|
|
|
637
|
-
/*
|
|
638
|
-
Copyright 2022 Google LLC
|
|
639
|
-
|
|
640
|
-
Use of this source code is governed by an MIT-style
|
|
641
|
-
license that can be found in the LICENSE file or at
|
|
642
|
-
https://opensource.org/licenses/MIT.
|
|
643
|
-
*/ // Adapted from https://github.com/lydell/source-map-url/blob/master/source-map-url.js
|
|
644
|
-
// See https://github.com/GoogleChrome/workbox/issues/3019
|
|
645
489
|
const innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/;
|
|
646
490
|
const regex = RegExp(`(?:/\\*(?:\\s*\r?\n(?://)?)?(?:${innerRegex.source})\\s*\\*/|//(?:${innerRegex.source}))\\s*`);
|
|
647
491
|
function getSourceMapURL(srcContents) {
|
|
@@ -650,24 +494,13 @@ function getSourceMapURL(srcContents) {
|
|
|
650
494
|
}
|
|
651
495
|
|
|
652
496
|
function rebasePath({ baseDirectory, file }) {
|
|
653
|
-
// The initial path is relative to the current directory, so make it absolute.
|
|
654
497
|
const absolutePath = upath.resolve(file);
|
|
655
|
-
// Convert the absolute path so that it's relative to the baseDirectory.
|
|
656
498
|
const relativePath = upath.relative(baseDirectory, absolutePath);
|
|
657
|
-
// Remove any leading ./ as it won't work in a glob pattern.
|
|
658
499
|
const normalizedPath = upath.normalize(relativePath);
|
|
659
500
|
return normalizedPath;
|
|
660
501
|
}
|
|
661
502
|
|
|
662
|
-
|
|
663
|
-
* Adapted from https://github.com/nsams/sourcemap-aware-replace, with modern
|
|
664
|
-
* JavaScript updates, along with additional properties copied from originalMap.
|
|
665
|
-
*
|
|
666
|
-
* @param options
|
|
667
|
-
* @returns An object containing both
|
|
668
|
-
* originalSource with the replacement applied, and the modified originalMap.
|
|
669
|
-
* @private
|
|
670
|
-
*/ async function replaceAndUpdateSourceMap({ jsFilename, originalMap, originalSource, replaceString, searchString }) {
|
|
503
|
+
async function replaceAndUpdateSourceMap({ jsFilename, originalMap, originalSource, replaceString, searchString }) {
|
|
671
504
|
const generator = new SourceMapGenerator({
|
|
672
505
|
file: jsFilename
|
|
673
506
|
});
|
|
@@ -717,8 +550,6 @@ function rebasePath({ baseDirectory, file }) {
|
|
|
717
550
|
return mapping;
|
|
718
551
|
});
|
|
719
552
|
consumer.destroy();
|
|
720
|
-
// JSON.parse returns any.
|
|
721
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
722
553
|
const updatedSourceMap = Object.assign(JSON.parse(generator.toString()), {
|
|
723
554
|
names: originalMap.names,
|
|
724
555
|
sourceRoot: originalMap.sourceRoot,
|
|
@@ -751,34 +582,8 @@ function translateURLToSourcemapPaths(url, swSrc, swDest) {
|
|
|
751
582
|
};
|
|
752
583
|
}
|
|
753
584
|
|
|
754
|
-
|
|
755
|
-
* This method creates a list of URLs to precache, referred to as a "precache
|
|
756
|
-
* manifest", based on the options you provide.
|
|
757
|
-
*
|
|
758
|
-
* The manifest is injected into the `swSrc` file, and the placeholder string
|
|
759
|
-
* `injectionPoint` determines where in the file the manifest should go.
|
|
760
|
-
*
|
|
761
|
-
* The final service worker file, with the manifest injected, is written to
|
|
762
|
-
* disk at `swDest`.
|
|
763
|
-
*
|
|
764
|
-
* This method will not compile or bundle your `swSrc` file; it just handles
|
|
765
|
-
* injecting the manifest.
|
|
766
|
-
*
|
|
767
|
-
* ```
|
|
768
|
-
* // The following lists some common options; see the rest of the documentation
|
|
769
|
-
* // for the full set of options and defaults.
|
|
770
|
-
* const {count, size, warnings} = await injectManifest({
|
|
771
|
-
* dontCacheBustURLsMatching: [new RegExp('...')],
|
|
772
|
-
* globDirectory: '...',
|
|
773
|
-
* globPatterns: ['...', '...'],
|
|
774
|
-
* maximumFileSizeToCacheInBytes: ...,
|
|
775
|
-
* swDest: '...',
|
|
776
|
-
* swSrc: '...',
|
|
777
|
-
* });
|
|
778
|
-
* ```
|
|
779
|
-
*/ const injectManifest = async (config)=>{
|
|
585
|
+
const injectManifest = async (config)=>{
|
|
780
586
|
const options = await validateInjectManifestOptions(config);
|
|
781
|
-
// Make sure we leave swSrc and swDest out of the precache manifest.
|
|
782
587
|
for (const file of [
|
|
783
588
|
options.swSrc,
|
|
784
589
|
options.swDest
|
|
@@ -797,7 +602,6 @@ function translateURLToSourcemapPaths(url, swSrc, swDest) {
|
|
|
797
602
|
throw new Error(`${errors["invalid-sw-src"]} ${error instanceof Error && error.message ? error.message : ""}`);
|
|
798
603
|
}
|
|
799
604
|
const injectionResults = swFileContents.match(globalRegexp);
|
|
800
|
-
// See https://github.com/GoogleChrome/workbox/issues/2230
|
|
801
605
|
const injectionPoint = options.injectionPoint ? options.injectionPoint : "";
|
|
802
606
|
if (!injectionResults) {
|
|
803
607
|
if (upath.resolve(options.swSrc) === upath.resolve(options.swDest)) {
|
|
@@ -809,17 +613,10 @@ function translateURLToSourcemapPaths(url, swSrc, swDest) {
|
|
|
809
613
|
const manifestString = manifestEntries === undefined ? "undefined" : stringify(manifestEntries);
|
|
810
614
|
const filesToWrite = {};
|
|
811
615
|
const url = getSourceMapURL(swFileContents);
|
|
812
|
-
// See https://github.com/GoogleChrome/workbox/issues/2957
|
|
813
616
|
const { destPath, srcPath, warning } = translateURLToSourcemapPaths(url, options.swSrc, options.swDest);
|
|
814
617
|
if (warning) {
|
|
815
618
|
warnings.push(warning);
|
|
816
619
|
}
|
|
817
|
-
// If our swSrc file contains a sourcemap, we would invalidate that
|
|
818
|
-
// mapping if we just replaced injectionPoint with the stringified manifest.
|
|
819
|
-
// Instead, we need to update the swDest contents as well as the sourcemap
|
|
820
|
-
// (assuming it's a real file, not a data: URL) at the same time.
|
|
821
|
-
// See https://github.com/GoogleChrome/workbox/issues/2235
|
|
822
|
-
// and https://github.com/GoogleChrome/workbox/issues/2648
|
|
823
620
|
if (srcPath && destPath) {
|
|
824
621
|
const originalMap = await fse.readJSON(srcPath, {
|
|
825
622
|
encoding: "utf8"
|
|
@@ -834,8 +631,6 @@ function translateURLToSourcemapPaths(url, swSrc, swDest) {
|
|
|
834
631
|
filesToWrite[options.swDest] = source;
|
|
835
632
|
filesToWrite[destPath] = map;
|
|
836
633
|
} else {
|
|
837
|
-
// If there's no sourcemap associated with swSrc, a simple string
|
|
838
|
-
// replacement will suffice.
|
|
839
634
|
filesToWrite[options.swDest] = swFileContents.replace(globalRegexp, manifestString);
|
|
840
635
|
}
|
|
841
636
|
for (const [file, contents] of Object.entries(filesToWrite)){
|
|
@@ -850,7 +645,6 @@ function translateURLToSourcemapPaths(url, swSrc, swDest) {
|
|
|
850
645
|
count,
|
|
851
646
|
size,
|
|
852
647
|
warnings,
|
|
853
|
-
// Use upath.resolve() to make all the paths absolute.
|
|
854
648
|
filePaths: Object.keys(filesToWrite).map((f)=>upath.resolve(f))
|
|
855
649
|
};
|
|
856
650
|
};
|
package/dist/index.next.js
CHANGED
|
@@ -5,13 +5,16 @@ import { v as validationErrorMap, S as SerwistConfigError } from './chunks/serwi
|
|
|
5
5
|
import './chunks/glob.js';
|
|
6
6
|
|
|
7
7
|
const nextInjectManifestPartial = z.object({
|
|
8
|
-
|
|
8
|
+
cacheOnNavigation: z.boolean().default(false),
|
|
9
9
|
disable: z.boolean().default(false),
|
|
10
10
|
register: z.boolean().default(true),
|
|
11
11
|
reloadOnOnline: z.boolean().default(true),
|
|
12
12
|
scope: z.string().optional(),
|
|
13
13
|
swUrl: z.string().default("/sw.js"),
|
|
14
|
-
globPublicPatterns: z.
|
|
14
|
+
globPublicPatterns: z.union([
|
|
15
|
+
z.string(),
|
|
16
|
+
z.array(z.string())
|
|
17
|
+
]).default([
|
|
15
18
|
"**/*"
|
|
16
19
|
])
|
|
17
20
|
}).strict("Do not pass invalid properties to NextInjectManifestPartial!");
|
package/dist/lib/errors.d.ts
CHANGED
|
@@ -35,9 +35,6 @@ export declare const errors: {
|
|
|
35
35
|
"multiple-injection-points": string;
|
|
36
36
|
"useless-glob-pattern": string;
|
|
37
37
|
"bad-template-urls-asset": string;
|
|
38
|
-
"invalid-runtime-caching": string;
|
|
39
|
-
"urlPattern-is-required": string;
|
|
40
|
-
"handler-is-required": string;
|
|
41
38
|
"invalid-generate-file-manifest-arg": string;
|
|
42
39
|
"invalid-sw-src": string;
|
|
43
40
|
"same-src-and-dest": string;
|
package/dist/lib/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,MAAM
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkFlB,CAAC"}
|
|
@@ -4,10 +4,10 @@ interface FileDetails {
|
|
|
4
4
|
hash: string;
|
|
5
5
|
size: number;
|
|
6
6
|
}
|
|
7
|
-
export declare
|
|
7
|
+
export declare const getFileDetails: ({ globDirectory, globFollow, globIgnores, globPattern, }: Omit<GlobPartial, "globPatterns" | "templatedURLs" | "globDirectory"> & {
|
|
8
8
|
globDirectory: string;
|
|
9
9
|
globPattern: string;
|
|
10
|
-
})
|
|
10
|
+
}) => {
|
|
11
11
|
globbedFileDetails: FileDetails[];
|
|
12
12
|
warning: string;
|
|
13
13
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-file-details.d.ts","sourceRoot":"","sources":["../../src/lib/get-file-details.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,
|
|
1
|
+
{"version":3,"file":"get-file-details.d.ts","sourceRoot":"","sources":["../../src/lib/get-file-details.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,cAAc;mBAOV,MAAM;iBACR,MAAM;;wBAEC,WAAW,EAAE;aACxB,MAAM;CAkChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertType.d.ts","sourceRoot":"","sources":["../../src/schema/assertType.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;AAEtF,wBAAgB,UAAU,CAAC,EAAE,SAAS,IAAI,UAEzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/schema/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/schema/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASmC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getManifest.d.ts","sourceRoot":"","sources":["../../src/schema/getManifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAM7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"getManifest.d.ts","sourceRoot":"","sources":["../../src/schema/getManifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAM7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGmC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/schema/glob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/schema/glob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;EAQmC,CAAC;AAE5D,eAAO,MAAM,4BAA4B;;;;;;EAImC,CAAC;AAI7E,eAAO,MAAM,4BAA4B;;;;;;EAImC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injectManifest.d.ts","sourceRoot":"","sources":["../../src/schema/injectManifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"injectManifest.d.ts","sourceRoot":"","sources":["../../src/schema/injectManifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,aAAa;;;;;;;;;EAKmC,CAAC;AAE9D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKmC,CAAC"}
|
package/dist/schema/next.d.ts
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const nextInjectManifestPartial: z.ZodObject<{
|
|
3
|
-
|
|
3
|
+
cacheOnNavigation: z.ZodDefault<z.ZodBoolean>;
|
|
4
4
|
disable: z.ZodDefault<z.ZodBoolean>;
|
|
5
5
|
register: z.ZodDefault<z.ZodBoolean>;
|
|
6
6
|
reloadOnOnline: z.ZodDefault<z.ZodBoolean>;
|
|
7
7
|
scope: z.ZodOptional<z.ZodString>;
|
|
8
8
|
swUrl: z.ZodDefault<z.ZodString>;
|
|
9
|
-
globPublicPatterns: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
9
|
+
globPublicPatterns: z.ZodDefault<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
10
10
|
}, "strict", z.ZodTypeAny, {
|
|
11
|
-
|
|
11
|
+
cacheOnNavigation: boolean;
|
|
12
12
|
disable: boolean;
|
|
13
13
|
register: boolean;
|
|
14
14
|
reloadOnOnline: boolean;
|
|
15
15
|
swUrl: string;
|
|
16
|
-
globPublicPatterns: string[];
|
|
16
|
+
globPublicPatterns: (string | string[]) & (string | string[] | undefined);
|
|
17
17
|
scope?: string | undefined;
|
|
18
18
|
}, {
|
|
19
|
-
|
|
19
|
+
cacheOnNavigation?: boolean | undefined;
|
|
20
20
|
disable?: boolean | undefined;
|
|
21
21
|
register?: boolean | undefined;
|
|
22
22
|
reloadOnOnline?: boolean | undefined;
|
|
23
23
|
scope?: string | undefined;
|
|
24
24
|
swUrl?: string | undefined;
|
|
25
|
-
globPublicPatterns?: string[] | undefined;
|
|
25
|
+
globPublicPatterns?: string | string[] | undefined;
|
|
26
26
|
}>;
|
|
27
27
|
export declare const nextInjectManifestOptions: z.ZodObject<Omit<{
|
|
28
28
|
disablePrecacheManifest: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -132,29 +132,28 @@ export declare const nextInjectManifestOptions: z.ZodObject<Omit<{
|
|
|
132
132
|
chunks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
133
133
|
excludeChunks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
134
134
|
include: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>, z.ZodFunction<z.ZodTuple<[z.ZodAny], null>, z.ZodBoolean>]>, "many">>;
|
|
135
|
-
mode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
136
135
|
compileSrc: z.ZodDefault<z.ZodBoolean>;
|
|
137
136
|
webpackCompilationPlugins: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
|
|
138
137
|
swDest: z.ZodString;
|
|
139
|
-
|
|
138
|
+
cacheOnNavigation: z.ZodDefault<z.ZodBoolean>;
|
|
140
139
|
disable: z.ZodDefault<z.ZodBoolean>;
|
|
141
140
|
register: z.ZodDefault<z.ZodBoolean>;
|
|
142
141
|
reloadOnOnline: z.ZodDefault<z.ZodBoolean>;
|
|
143
142
|
scope: z.ZodOptional<z.ZodString>;
|
|
144
143
|
swUrl: z.ZodDefault<z.ZodString>;
|
|
145
|
-
globPublicPatterns: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
144
|
+
globPublicPatterns: z.ZodDefault<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
146
145
|
}, "disablePrecacheManifest">, "strict", z.ZodTypeAny, {
|
|
147
146
|
maximumFileSizeToCacheInBytes: number;
|
|
148
147
|
injectionPoint: string;
|
|
149
148
|
swSrc: string;
|
|
150
149
|
exclude: (string | RegExp | ((args_0: any) => boolean))[];
|
|
151
150
|
compileSrc: boolean;
|
|
152
|
-
|
|
151
|
+
cacheOnNavigation: boolean;
|
|
153
152
|
disable: boolean;
|
|
154
153
|
register: boolean;
|
|
155
154
|
reloadOnOnline: boolean;
|
|
156
155
|
swUrl: string;
|
|
157
|
-
globPublicPatterns: string[];
|
|
156
|
+
globPublicPatterns: (string | string[]) & (string | string[] | undefined);
|
|
158
157
|
swDest: string;
|
|
159
158
|
additionalPrecacheEntries?: (string | {
|
|
160
159
|
revision: string | null;
|
|
@@ -188,7 +187,6 @@ export declare const nextInjectManifestOptions: z.ZodObject<Omit<{
|
|
|
188
187
|
chunks?: string[] | undefined;
|
|
189
188
|
excludeChunks?: string[] | undefined;
|
|
190
189
|
include?: (string | RegExp | ((args_0: any) => boolean))[] | undefined;
|
|
191
|
-
mode?: string | null | undefined;
|
|
192
190
|
webpackCompilationPlugins?: any[] | undefined;
|
|
193
191
|
scope?: string | undefined;
|
|
194
192
|
}, {
|
|
@@ -229,15 +227,14 @@ export declare const nextInjectManifestOptions: z.ZodObject<Omit<{
|
|
|
229
227
|
chunks?: string[] | undefined;
|
|
230
228
|
excludeChunks?: string[] | undefined;
|
|
231
229
|
include?: (string | RegExp | ((args_0: any) => boolean))[] | undefined;
|
|
232
|
-
mode?: string | null | undefined;
|
|
233
230
|
compileSrc?: boolean | undefined;
|
|
234
231
|
webpackCompilationPlugins?: any[] | undefined;
|
|
235
|
-
|
|
232
|
+
cacheOnNavigation?: boolean | undefined;
|
|
236
233
|
disable?: boolean | undefined;
|
|
237
234
|
register?: boolean | undefined;
|
|
238
235
|
reloadOnOnline?: boolean | undefined;
|
|
239
236
|
swUrl?: string | undefined;
|
|
240
|
-
globPublicPatterns?: string[] | undefined;
|
|
237
|
+
globPublicPatterns?: string | string[] | undefined;
|
|
241
238
|
scope?: string | undefined;
|
|
242
239
|
}>;
|
|
243
240
|
//# sourceMappingURL=next.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../../src/schema/next.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../../src/schema/next.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;EAUmC,CAAC;AAE1E,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAImC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swDest.d.ts","sourceRoot":"","sources":["../../src/schema/swDest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"swDest.d.ts","sourceRoot":"","sources":["../../src/schema/swDest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,qBAAqB;;;;;;EAI4B,CAAC;AAE/D,eAAO,MAAM,qBAAqB;;;;;;EAI4B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../../src/schema/vite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../../src/schema/vite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAS7B,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKmC,CAAC"}
|