PageSourceSearch

https://arona-note.netlify.app/sw.js

js arona-note.netlify.app collected 2026-10-03 10:28:06 UTC 154,031 bytes, 3,074 lines download raw bytes

1// @ts-ignore
2try {
3    self['workbox:core:7.3.0'] && _();
4}
5catch (e) { }
6
7const fallback = (code, ...args) => {
8  let msg = code;
9  if (args.length > 0) {
10    msg += ` :: ${JSON.stringify(args)}`;
11  }
12  return msg;
13};
14const messageGenerator = fallback ;
15
16/*
17  Copyright 2018 Google LLC
18
19  Use of this source code is governed by an MIT-style
20  license that can be found in the LICENSE file or at
21  https://opensource.org/licenses/MIT.
22*/
23/**
24 * Workbox errors should be thrown with this class.
25 * This allows use to ensure the type easily in tests,
26 * helps developers identify errors from workbox
27 * easily and allows use to optimise error
28 * messages correctly.
29 *
30 * @private
31 */
32class WorkboxError extends Error {
33    /**
34     *
35     * @param {string} errorCode The error code that
36     * identifies this particular error.
37     * @param {Object=} details Any relevant arguments
38     * that will help developers identify issues should
39     * be added as a key on the context object.
40     */
41    constructor(errorCode, details) {
42        const message = messageGenerator(errorCode, details);
43        super(message);
44        this.name = errorCode;
45        this.details = details;
46    }
47}
48
49/*
50  Copyright 2018 Google LLC
51
52  Use of this source code is governed by an MIT-style
53  license that can be found in the LICENSE file or at
54  https://opensource.org/licenses/MIT.
55*/
56const _cacheNameDetails = {
57    googleAnalytics: 'googleAnalytics',
58    precache: 'precache-v2',
59    prefix: 'workbox',
60    runtime: 'runtime',
61    suffix: typeof registration !== 'undefined' ? registration.scope : '',
62};
63const _createCacheName = (cacheName) => {
64    return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix]
65        .filter((value) => value && value.length > 0)
66        .join('-');
67};
68const eachCacheNameDetail = (fn) => {
69    for (const key of Object.keys(_cacheNameDetails)) {
70        fn(key);
71    }
72};
73const cacheNames = {
74    updateDetails: (details) => {
75        eachCacheNameDetail((key) => {
76            if (typeof details[key] === 'string') {
77                _cacheNameDetails[key] = details[key];
78            }
79        });
80    },
81    getGoogleAnalyticsName: (userCacheName) => {
82        return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);
83    },
84    getPrecacheName: (userCacheName) => {
85        return userCacheName || _createCacheName(_cacheNameDetails.precache);
86    },
87    getPrefix: () => {
88        return _cacheNameDetails.prefix;
89    },
90    getRuntimeName: (userCacheName) => {
91        return userCacheName || _createCacheName(_cacheNameDetails.runtime);
92    },
93    getSuffix: () => {
94        return _cacheNameDetails.suffix;
95    },
96};
97
98const logger = null ;
99
100/*
101  Copyright 2020 Google LLC
102  Use of this source code is governed by an MIT-style
103  license that can be found in the LICENSE file or at
104  https://opensource.org/licenses/MIT.
105*/
106/**
107 * A utility method that makes it easier to use `event.waitUntil` with
108 * async functions and return the result.
109 *
110 * @param {ExtendableEvent} event
111 * @param {Function} asyncFn
112 * @return {Function}
113 * @private
114 */
115function waitUntil(event, asyncFn) {
116    const returnPromise = asyncFn();
117    event.waitUntil(returnPromise);
118    return returnPromise;
119}
120
121// @ts-ignore
122try {
123    self['workbox:precaching:7.3.0'] && _();
124}
125catch (e) { }
126
127/*
128  Copyright 2018 Google LLC
129
130  Use of this source code is governed by an MIT-style
131  license that can be found in the LICENSE file or at
132  https://opensource.org/licenses/MIT.
133*/
134// Name of the search parameter used to store revision info.
135const REVISION_SEARCH_PARAM = '__WB_REVISION__';
136/**
137 * Converts a manifest entry into a versioned URL suitable for precaching.
138 *
139 * @param {Object|string} entry
140 * @return {string} A URL with versioning info.
141 *
142 * @private
143 * @memberof workbox-precaching
144 */
145function createCacheKey(entry) {
146    if (!entry) {
147        throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });
148    }
149    // If a precache manifest entry is a string, it's assumed to be a versioned
150    // URL, like '/app.abcd1234.js'. Return as-is.
151    if (typeof entry === 'string') {
152        const urlObject = new URL(entry, location.href);
153        return {
154            cacheKey: urlObject.href,
155            url: urlObject.href,
156        };
157    }
158    const { revision, url } = entry;
159    if (!url) {
160        throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });
161    }
162    // If there's just a URL and no revision, then it's also assumed to be a
163    // versioned URL.
164    if (!revision) {
165        const urlObject = new URL(url, location.href);
166        return {
167            cacheKey: urlObject.href,
168            url: urlObject.href,
169        };
170    }
171    // Otherwise, construct a properly versioned URL using the custom Workbox
172    // search parameter along with the revision info.
173    const cacheKeyURL = new URL(url, location.href);
174    const originalURL = new URL(url, location.href);
175    cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);
176    return {
177        cacheKey: cacheKeyURL.href,
178        url: originalURL.href,
179    };
180}
181
182/*
183  Copyright 2020 Google LLC
184
185  Use of this source code is governed by an MIT-style
186  license that can be found in the LICENSE file or at
187  https://opensource.org/licenses/MIT.
188*/
189/**
190 * A plugin, designed to be used with PrecacheController, to determine the
191 * of assets that were updated (or not updated) during the install event.
192 *
193 * @private
194 */
195class PrecacheInstallReportPlugin {
196    constructor() {
197        this.updatedURLs = [];
198        this.notUpdatedURLs = [];
199        this.handlerWillStart = async ({ request, state, }) => {
200            // TODO: `state` should never be undefined...
201            if (state) {
202                state.originalRequest = request;
203            }
204        };
205        this.cachedResponseWillBeUsed = async ({ event, state, cachedResponse, }) => {
206            if (event.type === 'install') {
207                if (state &&
208                    state.originalRequest &&
209                    state.originalRequest instanceof Request) {
210                    // TODO: `state` should never be undefined...
211                    const url = state.originalRequest.url;
212                    if (cachedResponse) {
213                        this.notUpdatedURLs.push(url);
214                    }
215                    else {
216                        this.updatedURLs.push(url);
217                    }
218                }
219            }
220            return cachedResponse;
221        };
222    }
223}
224
225/*
226  Copyright 2020 Google LLC
227
228  Use of this source code is governed by an MIT-style
229  license that can be found in the LICENSE file or at
230  https://opensource.org/licenses/MIT.
231*/
232/**
233 * A plugin, designed to be used with PrecacheController, to translate URLs into
234 * the corresponding cache key, based on the current revision info.
235 *
236 * @private
237 */
238class PrecacheCacheKeyPlugin {
239    constructor({ precacheController }) {
240        this.cacheKeyWillBeUsed = async ({ request, params, }) => {
241            // Params is type any, can't change right now.
242            /* eslint-disable */
243            const cacheKey = (params === null || params === void 0 ? void 0 : params.cacheKey) ||
244                this._precacheController.getCacheKeyForURL(request.url);
245            /* eslint-enable */
246            return cacheKey
247                ? new Request(cacheKey, { headers: request.headers })
248                : request;
249        };
250        this._precacheController = precacheController;
251    }
252}
253
254/*
255  Copyright 2019 Google LLC
256
257  Use of this source code is governed by an MIT-style
258  license that can be found in the LICENSE file or at
259  https://opensource.org/licenses/MIT.
260*/
261let supportStatus;
262/**
263 * A utility function that determines whether the current browser supports
264 * constructing a new `Response` from a `response.body` stream.
265 *
266 * @return {boolean} `true`, if the current browser can successfully
267 *     construct a `Response` from a `response.body` stream, `false` otherwise.
268 *
269 * @private
270 */
271function canConstructResponseFromBodyStream() {
272    if (supportStatus === undefined) {
273        const testResponse = new Response('');
274        if ('body' in testResponse) {
275            try {
276                new Response(testResponse.body);
277                supportStatus = true;
278            }
279            catch (error) {
280                supportStatus = false;
281            }
282        }
283        supportStatus = false;
284    }
285    return supportStatus;
286}
287
288/*
289  Copyright 2019 Google LLC
290
291  Use of this source code is governed by an MIT-style
292  license that can be found in the LICENSE file or at
293  https://opensource.org/licenses/MIT.
294*/
295/**
296 * Allows developers to copy a response and modify its `headers`, `status`,
297 * or `statusText` values (the values settable via a
298 * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax}
299 * object in the constructor).
300 * To modify these values, pass a function as the second argument. That
301 * function will be invoked with a single object with the response properties
302 * `{headers, status, statusText}`. The return value of this function will
303 * be used as the `ResponseInit` for the new `Response`. To change the values
304 * either modify the passed parameter(s) and return it, or return a totally
305 * new object.
306 *
307 * This method is intentionally limited to same-origin responses, regardless of
308 * whether CORS was used or not.
309 *
310 * @param {Response} response
311 * @param {Function} modifier
312 * @memberof workbox-core
313 */
314async function copyResponse(response, modifier) {
315    let origin = null;
316    // If response.url isn't set, assume it's cross-origin and keep origin null.
317    if (response.url) {
318        const responseURL = new URL(response.url);
319        origin = responseURL.origin;
320    }
321    if (origin !== self.location.origin) {
322        throw new WorkboxError('cross-origin-copy-response', { origin });
323    }
324    const clonedResponse = response.clone();
325    // Create a fresh `ResponseInit` object by cloning the headers.
326    const responseInit = {
327        headers: new Headers(clonedResponse.headers),
328        status: clonedResponse.status,
329        statusText: clonedResponse.statusText,
330    };
331    // Apply any user modifications.
332    const modifiedResponseInit = responseInit;
333    // Create the new response from the body stream and `ResponseInit`
334    // modifications. Note: not all browsers support the Response.body stream,
335    // so fall back to reading the entire body into memory as a blob.
336    const body = canConstructResponseFromBodyStream()
337        ? clonedResponse.body
338        : await clonedResponse.blob();
339    return new Response(body, modifiedResponseInit);
340}
341
342/*
343  Copyright 2018 Google LLC
344
345  Use of this source code is governed by an MIT-style
346  license that can be found in the LICENSE file or at
347  https://opensource.org/licenses/MIT.
348*/
349const getFriendlyURL = (url) => {
350    const urlObj = new URL(String(url), location.href);
351    // See https://github.com/GoogleChrome/workbox/issues/2323
352    // We want to include everything, except for the origin if it's same-origin.
353    return urlObj.href.replace(new RegExp(`^${location.origin}`), '');
354};
355
356/*
357  Copyright 2020 Google LLC
358  Use of this source code is governed by an MIT-style
359  license that can be found in the LICENSE file or at
360  https://opensource.org/licenses/MIT.
361*/
362function stripParams(fullURL, ignoreParams) {
363    const strippedURL = new URL(fullURL);
364    for (const param of ignoreParams) {
365        strippedURL.searchParams.delete(param);
366    }
367    return strippedURL.href;
368}
369/**
370 * Matches an item in the cache, ignoring specific URL params. This is similar
371 * to the `ignoreSearch` option, but it allows you to ignore just specific
372 * params (while continuing to match on the others).
373 *
374 * @private
375 * @param {Cache} cache
376 * @param {Request} request
377 * @param {Object} matchOptions
378 * @param {Array<string>} ignoreParams
379 * @return {Promise<Response|undefined>}
380 */
381async function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) {
382    const strippedRequestURL = stripParams(request.url, ignoreParams);
383    // If the request doesn't include any ignored params, match as normal.
384    if (request.url === strippedRequestURL) {
385        return cache.match(request, matchOptions);
386    }
387    // Otherwise, match by comparing keys
388    const keysOptions = Object.assign(Object.assign({}, matchOptions), { ignoreSearch: true });
389    const cacheKeys = await cache.keys(request, keysOptions);
390    for (const cacheKey of cacheKeys) {
391        const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams);
392        if (strippedRequestURL === strippedCacheKeyURL) {
393            return cache.match(cacheKey, matchOptions);
394        }
395    }
396    return;
397}
398
399/*
400  Copyright 2018 Google LLC
401
402  Use of this source code is governed by an MIT-style
403  license that can be found in the LICENSE file or at
404  https://opensource.org/licenses/MIT.
405*/
406/**
407 * The Deferred class composes Promises in a way that allows for them to be
408 * resolved or rejected from outside the constructor. In most cases promises
409 * should be used directly, but Deferreds can be necessary when the logic to
410 * resolve a promise must be separate.
411 *
412 * @private
413 */
414class Deferred {
415    /**
416     * Creates a promise and exposes its resolve and reject functions as methods.
417     */
418    constructor() {
419        this.promise = new Promise((resolve, reject) => {
420            this.resolve = resolve;
421            this.reject = reject;
422        });
423    }
424}
425
426/*
427  Copyright 2018 Google LLC
428
429  Use of this source code is governed by an MIT-style
430  license that can be found in the LICENSE file or at
431  https://opensource.org/licenses/MIT.
432*/
433// Callbacks to be executed whenever there's a quota error.
434// Can't change Function type right now.
435// eslint-disable-next-line @typescript-eslint/ban-types
436const quotaErrorCallbacks = new Set();
437
438async function executeQuotaErrorCallbacks() {
439  for (const callback of quotaErrorCallbacks) {
440    await callback();
441  }
442}
443
444/*
445  Copyright 2019 Google LLC
446  Use of this source code is governed by an MIT-style
447  license that can be found in the LICENSE file or at
448  https://opensource.org/licenses/MIT.
449*/
450/**
451 * Returns a promise that resolves and the passed number of milliseconds.
452 * This utility is an async/await-friendly version of `setTimeout`.
453 *
454 * @param {number} ms
455 * @return {Promise}
456 * @private
457 */
458function timeout(ms) {
459    return new Promise((resolve) => setTimeout(resolve, ms));
460}
461
462// @ts-ignore
463try {
464    self['workbox:strategies:7.3.0'] && _();
465}
466catch (e) { }
467
468function toRequest(input) {
469  return typeof input === "string" ? new Request(input) : input;
470}
471class StrategyHandler {
472  /**
473   * Creates a new instance associated with the passed strategy and event
474   * that's handling the request.
475   *
476   * The constructor also initializes the state that will be passed to each of
477   * the plugins handling this request.
478   *
479   * @param {workbox-strategies.Strategy} strategy
480   * @param {Object} options
481   * @param {Request|string} options.request A request to run this strategy for.
482   * @param {ExtendableEvent} options.event The event associated with the
483   *     request.
484   * @param {URL} [options.url]
485   * @param {*} [options.params] The return value from the
486   *     {@link workbox-routing~matchCallback} (if applicable).
487   */
488  constructor(strategy, options) {
489    this._cacheKeys = {};
490    Object.assign(this, options);
491    this.event = options.event;
492    this._strategy = strategy;
493    this._handlerDeferred = new Deferred();
494    this._extendLifetimePromises = [];
495    this._plugins = [...strategy.plugins];
496    this._pluginStateMap = /* @__PURE__ */ new Map();
497    for (const plugin of this._plugins) {
498      this._pluginStateMap.set(plugin, {});
499    }
500    this.event.waitUntil(this._handlerDeferred.promise);
501  }
502  /**
503   * Fetches a given request (and invokes any applicable plugin callback
504   * methods) using the `fetchOptions` (for non-navigation requests) and
505   * `plugins` defined on the `Strategy` object.
506   *
507   * The following plugin lifecycle methods are invoked when using this method:
508   * - `requestWillFetch()`
509   * - `fetchDidSucceed()`
510   * - `fetchDidFail()`
511   *
512   * @param {Request|string} input The URL or request to fetch.
513   * @return {Promise<Response>}
514   */
515  async fetch(input) {
516    const { event } = this;
517    let request = toRequest(input);
518    if (request.mode === "navigate" && event instanceof FetchEvent && event.preloadResponse) {
519      const possiblePreloadResponse = await event.preloadResponse;
520      if (possiblePreloadResponse) {
521        return possiblePreloadResponse;
522      }
523    }
524    const originalRequest = this.hasCallback("fetchDidFail") ? request.clone() : null;
525    try {
526      for (const cb of this.iterateCallbacks("requestWillFetch")) {
527        request = await cb({ request: request.clone(), event });
528      }
529    } catch (err) {
530      if (err instanceof Error) {
531        throw new WorkboxError("plugin-error-request-will-fetch", {
532          thrownErrorMessage: err.message
533        });
534      }
535    }
536    const pluginFilteredRequest = request.clone();
537    try {
538      let fetchResponse;
539      fetchResponse = await fetch(request, request.mode === "navigate" ? void 0 : this._strategy.fetchOptions);
540      if (false) ;
541      for (const callback of this.iterateCallbacks("fetchDidSucceed")) {
542        fetchResponse = await callback({
543          event,
544          request: pluginFilteredRequest,
545          response: fetchResponse
546        });
547      }
548      return fetchResponse;
549    } catch (error) {
550      if (originalRequest) {
551        await this.runCallbacks("fetchDidFail", {
552          error,
553          event,
554          originalRequest: originalRequest.clone(),
555          request: pluginFilteredRequest.clone()
556        });
557      }
558      throw error;
559    }
560  }
561  /**
562   * Calls `this.fetch()` and (in the background) runs `this.cachePut()` on
563   * the response generated by `this.fetch()`.
564   *
565   * The call to `this.cachePut()` automatically invokes `this.waitUntil()`,
566   * so you do not have to manually call `waitUntil()` on the event.
567   *
568   * @param {Request|string} input The request or URL to fetch and cache.
569   * @return {Promise<Response>}
570   */
571  async fetchAndCachePut(input) {
572    const response = await this.fetch(input);
573    const responseClone = response.clone();
574    void this.waitUntil(this.cachePut(input, responseClone));
575    return response;
576  }
577  /**
578   * Matches a request from the cache (and invokes any applicable plugin
579   * callback methods) using the `cacheName`, `matchOptions`, and `plugins`
580   * defined on the strategy object.
581   *
582   * The following plugin lifecycle methods are invoked when using this method:
583   * - cacheKeyWillBeUsed()
584   * - cachedResponseWillBeUsed()
585   *
586   * @param {Request|string} key The Request or URL to use as the cache key.
587   * @return {Promise<Response|undefined>} A matching response, if found.
588   */
589  async cacheMatch(key) {
590    const request = toRequest(key);
591    let cachedResponse;
592    const { cacheName, matchOptions } = this._strategy;
593    const effectiveRequest = await this.getCacheKey(request, "read");
594    const multiMatchOptions = Object.assign(Object.assign({}, matchOptions), { cacheName });
595    cachedResponse = await caches.match(effectiveRequest, multiMatchOptions);
596    for (const callback of this.iterateCallbacks("cachedResponseWillBeUsed")) {
597      cachedResponse = await callback({
598        cacheName,
599        matchOptions,
600        cachedResponse,
601        request: effectiveRequest,
602        event: this.event
603      }) || void 0;
604    }
605    return cachedResponse;
606  }
607  /**
608   * Puts a request/response pair in the cache (and invokes any applicable
609   * plugin callback methods) using the `cacheName` and `plugins` defined on
610   * the strategy object.
611   *
612   * The following plugin lifecycle methods are invoked when using this method:
613   * - cacheKeyWillBeUsed()
614   * - cacheWillUpdate()
615   * - cacheDidUpdate()
616   *
617   * @param {Request|string} key The request or URL to use as the cache key.
618   * @param {Response} response The response to cache.
619   * @return {Promise<boolean>} `false` if a cacheWillUpdate caused the response
620   * not be cached, and `true` otherwise.
621   */
622  async cachePut(key, response) {
623    const request = toRequest(key);
624    await timeout(0);
625    const effectiveRequest = await this.getCacheKey(request, "write");
626    if (!response) {
627      throw new WorkboxError("cache-put-with-no-response", {
628        url: getFriendlyURL(effectiveRequest.url)
629      });
630    }
631    const responseToCache = await this._ensureResponseSafeToCache(response);
632    if (!responseToCache) {
633      return false;
634    }
635    const { cacheName, matchOptions } = this._strategy;
636    const cache = await self.caches.open(cacheName);
637    const hasCacheUpdateCallback = this.hasCallback("cacheDidUpdate");
638    const oldResponse = hasCacheUpdateCallback ? await cacheMatchIgnoreParams(
639      // TODO(philipwalton): the `__WB_REVISION__` param is a precaching
640      // feature. Consider into ways to only add this behavior if using
641      // precaching.
642      cache,
643      effectiveRequest.clone(),
644      ["__WB_REVISION__"],
645      matchOptions
646    ) : null;
647    try {
648      await cache.put(effectiveRequest, hasCacheUpdateCallback ? responseToCache.clone() : responseToCache);
649    } catch (error) {
650      if (error instanceof Error) {
651        if (error.name === "QuotaExceededError") {
652          await executeQuotaErrorCallbacks();
653        }
654        throw error;
655      }
656    }
657    for (const callback of this.iterateCallbacks("cacheDidUpdate")) {
658      await callback({
659        cacheName,
660        oldResponse,
661        newResponse: responseToCache.clone(),
662        request: effectiveRequest,
663        event: this.event
664      });
665    }
666    return true;
667  }
668  /**
669   * Checks the list of plugins for the `cacheKeyWillBeUsed` callback, and
670   * executes any of those callbacks found in sequence. The final `Request`
671   * object returned by the last plugin is treated as the cache key for cache
672   * reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have
673   * been registered, the passed request is returned unmodified
674   *
675   * @param {Request} request
676   * @param {string} mode
677   * @return {Promise<Request>}
678   */
679  async getCacheKey(request, mode) {
680    const key = `${request.url} | ${mode}`;
681    if (!this._cacheKeys[key]) {
682      let effectiveRequest = request;
683      for (const callback of this.iterateCallbacks("cacheKeyWillBeUsed")) {
684        effectiveRequest = toRequest(await callback({
685          mode,
686          request: effectiveRequest,
687          event: this.event,
688          // params has a type any can't change right now.
689          params: this.params
690          // eslint-disable-line
691        }));
692      }
693      this._cacheKeys[key] = effectiveRequest;
694    }
695    return this._cacheKeys[key];
696  }
697  /**
698   * Returns true if the strategy has at least one plugin with the given
699   * callback.
700   *
701   * @param {string} name The name of the callback to check for.
702   * @return {boolean}
703   */
704  hasCallback(name) {
705    for (const plugin of this._strategy.plugins) {
706      if (name in plugin) {
707        return true;
708      }
709    }
710    return false;
711  }
712  /**
713   * Runs all plugin callbacks matching the given name, in order, passing the
714   * given param object (merged ith the current plugin state) as the only
715   * argument.
716   *
717   * Note: since this method runs all plugins, it's not suitable for cases
718   * where the return value of a callback needs to be applied prior to calling
719   * the next callback. See
720   * {@link workbox-strategies.StrategyHandler#iterateCallbacks}
721   * below for how to handle that case.
722   *
723   * @param {string} name The name of the callback to run within each plugin.
724   * @param {Object} param The object to pass as the first (and only) param
725   *     when executing each callback. This object will be merged with the
726   *     current plugin state prior to callback execution.
727   */
728  async runCallbacks(name, param) {
729    for (const callback of this.iterateCallbacks(name)) {
730      await callback(param);
731    }
732  }
733  /**
734   * Accepts a callback and returns an iterable of matching plugin callbacks,
735   * where each callback is wrapped with the current handler state (i.e. when
736   * you call each callback, whatever object parameter you pass it will
737   * be merged with the plugin's current state).
738   *
739   * @param {string} name The name fo the callback to run
740   * @return {Array<Function>}
741   */
742  *iterateCallbacks(name) {
743    for (const plugin of this._strategy.plugins) {
744      if (typeof plugin[name] === "function") {
745        const state = this._pluginStateMap.get(plugin);
746        const statefulCallback = (param) => {
747          const statefulParam = Object.assign(Object.assign({}, param), { state });
748          return plugin[name](statefulParam);
749        };
750        yield statefulCallback;
751      }
752    }
753  }
754  /**
755   * Adds a promise to the
756   * [extend lifetime promises]{@link https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises}
757   * of the event associated with the request being handled (usually a
758   * `FetchEvent`).
759   *
760   * Note: you can await
761   * {@link workbox-strategies.StrategyHandler~doneWaiting}
762   * to know when all added promises have settled.
763   *
764   * @param {Promise} promise A promise to add to the extend lifetime promises
765   *     of the event that triggered the request.
766   */
767  waitUntil(promise) {
768    this._extendLifetimePromises.push(promise);
769    return promise;
770  }
771  /**
772   * Returns a promise that resolves once all promises passed to
773   * {@link workbox-strategies.StrategyHandler~waitUntil}
774   * have settled.
775   *
776   * Note: any work done after `doneWaiting()` settles should be manually
777   * passed to an event's `waitUntil()` method (not this handler's
778   * `waitUntil()` method), otherwise the service worker thread may be killed
779   * prior to your work completing.
780   */
781  async doneWaiting() {
782    while (this._extendLifetimePromises.length) {
783      const promises = this._extendLifetimePromises.splice(0);
784      const result = await Promise.allSettled(promises);
785      const firstRejection = result.find((i) => i.status === "rejected");
786      if (firstRejection) {
787        throw firstRejection.reason;
788      }
789    }
790  }
791  /**
792   * Stops running the strategy and immediately resolves any pending
793   * `waitUntil()` promises.
794   */
795  destroy() {
796    this._handlerDeferred.resolve(null);
797  }
798  /**
799   * This method will call cacheWillUpdate on the available plugins (or use
800   * status === 200) to determine if the Response is safe and valid to cache.
801   *
802   * @param {Request} options.request
803   * @param {Response} options.response
804   * @return {Promise<Response|undefined>}
805   *
806   * @private
807   */
808  async _ensureResponseSafeToCache(response) {
809    let responseToCache = response;
810    let pluginsUsed = false;
811    for (const callback of this.iterateCallbacks("cacheWillUpdate")) {
812      responseToCache = await callback({
813        request: this.request,
814        response: responseToCache,
815        event: this.event
816      }) || void 0;
817      pluginsUsed = true;
818      if (!responseToCache) {
819        break;
820      }
821    }
822    if (!pluginsUsed) {
823      if (responseToCache && responseToCache.status !== 200) {
824        responseToCache = void 0;
825      }
826    }
827    return responseToCache;
828  }
829}
830
831class Strategy {
832  /**
833   * Creates a new instance of the strategy and sets all documented option
834   * properties as public instance properties.
835   *
836   * Note: if a custom strategy class extends the base Strategy class and does
837   * not need more than these properties, it does not need to define its own
838   * constructor.
839   *
840   * @param {Object} [options]
841   * @param {string} [options.cacheName] Cache name to store and retrieve
842   * requests. Defaults to the cache names provided by
843   * {@link workbox-core.cacheNames}.
844   * @param {Array<Object>} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
845   * to use in conjunction with this caching strategy.
846   * @param {Object} [options.fetchOptions] Values passed along to the
847   * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
848   * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796)
849   * `fetch()` requests made by this strategy.
850   * @param {Object} [options.matchOptions] The
851   * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions}
852   * for any `cache.match()` or `cache.put()` calls made by this strategy.
853   */
854  constructor(options = {}) {
855    this.cacheName = cacheNames.getRuntimeName(options.cacheName);
856    this.plugins = options.plugins || [];
857    this.fetchOptions = options.fetchOptions;
858    this.matchOptions = options.matchOptions;
859  }
860  /**
861   * Perform a request strategy and returns a `Promise` that will resolve with
862   * a `Response`, invoking all relevant plugin callbacks.
863   *
864   * When a strategy instance is registered with a Workbox
865   * {@link workbox-routing.Route}, this method is automatically
866   * called when the route matches.
867   *
868   * Alternatively, this method can be used in a standalone `FetchEvent`
869   * listener by passing it to `event.respondWith()`.
870   *
871   * @param {FetchEvent|Object} options A `FetchEvent` or an object with the
872   *     properties listed below.
873   * @param {Request|string} options.request A request to run this strategy for.
874   * @param {ExtendableEvent} options.event The event associated with the
875   *     request.
876   * @param {URL} [options.url]
877   * @param {*} [options.params]
878   */
879  handle(options) {
880    const [responseDone] = this.handleAll(options);
881    return responseDone;
882  }
883  /**
884   * Similar to {@link workbox-strategies.Strategy~handle}, but
885   * instead of just returning a `Promise` that resolves to a `Response` it
886   * it will return an tuple of `[response, done]` promises, where the former
887   * (`response`) is equivalent to what `handle()` returns, and the latter is a
888   * Promise that will resolve once any promises that were added to
889   * `event.waitUntil()` as part of performing the strategy have completed.
890   *
891   * You can await the `done` promise to ensure any extra work performed by
892   * the strategy (usually caching responses) completes successfully.
893   *
894   * @param {FetchEvent|Object} options A `FetchEvent` or an object with the
895   *     properties listed below.
896   * @param {Request|string} options.request A request to run this strategy for.
897   * @param {ExtendableEvent} options.event The event associated with the
898   *     request.
899   * @param {URL} [options.url]
900   * @param {*} [options.params]
901   * @return {Array<Promise>} A tuple of [response, done]
902   *     promises that can be used to determine when the response resolves as
903   *     well as when the handler has completed all its work.
904   */
905  handleAll(options) {
906    if (options instanceof FetchEvent) {
907      options = {
908        event: options,
909        request: options.request
910      };
911    }
912    const event = options.event;
913    const request = typeof options.request === "string" ? new Request(options.request) : options.request;
914    const params = "params" in options ? options.params : void 0;
915    const handler = new StrategyHandler(this, { event, request, params });
916    const responseDone = this._getResponse(handler, request, event);
917    const handlerDone = this._awaitComplete(responseDone, handler, request, event);
918    return [responseDone, handlerDone];
919  }
920  async _getResponse(handler, request, event) {
921    await handler.runCallbacks("handlerWillStart", { event, request });
922    let response = void 0;
923    try {
924      response = await this._handle(request, handler);
925      if (!response || response.type === "error") {
926        throw new WorkboxError("no-response", { url: request.url });
927      }
928    } catch (error) {
929      if (error instanceof Error) {
930        for (const callback of handler.iterateCallbacks("handlerDidError")) {
931          response = await callback({ error, event, request });
932          if (response) {
933            break;
934          }
935        }
936      }
937      if (!response) {
938        throw error;
939      }
940    }
941    for (const callback of handler.iterateCallbacks("handlerWillRespond")) {
942      response = await callback({ event, request, response });
943    }
944    return response;
945  }
946  async _awaitComplete(responseDone, handler, request, event) {
947    let response;
948    let error;
949    try {
950      response = await responseDone;
951    } catch (error2) {
952    }
953    try {
954      await handler.runCallbacks("handlerDidRespond", {
955        event,
956        request,
957        response
958      });
959      await handler.doneWaiting();
960    } catch (waitUntilError) {
961      if (waitUntilError instanceof Error) {
962        error = waitUntilError;
963      }
964    }
965    await handler.runCallbacks("handlerDidComplete", {
966      event,
967      request,
968      response,
969      error
970    });
971    handler.destroy();
972    if (error) {
973      throw error;
974    }
975  }
976}
977
978class PrecacheStrategy extends Strategy {
979  /**
980   *
981   * @param {Object} [options]
982   * @param {string} [options.cacheName] Cache name to store and retrieve
983   * requests. Defaults to the cache names provided by
984   * {@link workbox-core.cacheNames}.
985   * @param {Array<Object>} [options.plugins] {@link https://developers.google.com/web/tools/workbox/guides/using-plugins|Plugins}
986   * to use in conjunction with this caching strategy.
987   * @param {Object} [options.fetchOptions] Values passed along to the
988   * {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init}
989   * of all fetch() requests made by this strategy.
990   * @param {Object} [options.matchOptions] The
991   * {@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions|CacheQueryOptions}
992   * for any `cache.match()` or `cache.put()` calls made by this strategy.
993   * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to
994   * get the response from the network if there's a precache miss.
995   */
996  constructor(options = {}) {
997    options.cacheName = cacheNames.getPrecacheName(options.cacheName);
998    super(options);
999    this._fallbackToNetwork = options.fallbackToNetwork === false ? false : true;
1000    this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin);
1001  }
1002  /**
1003   * @private
1004   * @param {Request|string} request A request to run this strategy for.
1005   * @param {workbox-strategies.StrategyHandler} handler The event that
1006   *     triggered the request.
1007   * @return {Promise<Response>}
1008   */
1009  async _handle(request, handler) {
1010    const response = await handler.cacheMatch(request);
1011    if (response) {
1012      return response;
1013    }
1014    if (handler.event && handler.event.type === "install") {
1015      return await this._handleInstall(request, handler);
1016    }
1017    return await this._handleFetch(request, handler);
1018  }
1019  async _handleFetch(request, handler) {
1020    let response;
1021    const params = handler.params || {};
1022    if (this._fallbackToNetwork) {
1023      const integrityInManifest = params.integrity;
1024      const integrityInRequest = request.integrity;
1025      const noIntegrityConflict = !integrityInRequest || integrityInRequest === integrityInManifest;
1026      response = await handler.fetch(new Request(request, {
1027        integrity: request.mode !== "no-cors" ? integrityInRequest || integrityInManifest : void 0
1028      }));
1029      if (integrityInManifest && noIntegrityConflict && request.mode !== "no-cors") {
1030        this._useDefaultCacheabilityPluginIfNeeded();
1031        await handler.cachePut(request, response.clone());
1032      }
1033    } else {
1034      throw new WorkboxError("missing-precache-entry", {
1035        cacheName: this.cacheName,
1036        url: request.url
1037      });
1038    }
1039    return response;
1040  }
1041  async _handleInstall(request, handler) {
1042    this._useDefaultCacheabilityPluginIfNeeded();
1043    const response = await handler.fetch(request);
1044    const wasCached = await handler.cachePut(request, response.clone());
1045    if (!wasCached) {
1046      throw new WorkboxError("bad-precaching-response", {
1047        url: request.url,
1048        status: response.status
1049      });
1050    }
1051    return response;
1052  }
1053  /**
1054   * This method is complex, as there a number of things to account for:
1055   *
1056   * The `plugins` array can be set at construction, and/or it might be added to
1057   * to at any time before the strategy is used.
1058   *
1059   * At the time the strategy is used (i.e. during an `install` event), there
1060   * needs to be at least one plugin that implements `cacheWillUpdate` in the
1061   * array, other than `copyRedirectedCacheableResponsesPlugin`.
1062   *
1063   * - If this method is called and there are no suitable `cacheWillUpdate`
1064   * plugins, we need to add `defaultPrecacheCacheabilityPlugin`.
1065   *
1066   * - If this method is called and there is exactly one `cacheWillUpdate`, then
1067   * we don't have to do anything (this might be a previously added
1068   * `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin).
1069   *
1070   * - If this method is called and there is more than one `cacheWillUpdate`,
1071   * then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so,
1072   * we need to remove it. (This situation is unlikely, but it could happen if
1073   * the strategy is used multiple times, the first without a `cacheWillUpdate`,
1074   * and then later on after manually adding a custom `cacheWillUpdate`.)
1075   *
1076   * See https://github.com/GoogleChrome/workbox/issues/2737 for more context.
1077   *
1078   * @private
1079   */
1080  _useDefaultCacheabilityPluginIfNeeded() {
1081    let defaultPluginIndex = null;
1082    let cacheWillUpdatePluginCount = 0;
1083    for (const [index, plugin] of this.plugins.entries()) {
1084      if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) {
1085        continue;
1086      }
1087      if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) {
1088        defaultPluginIndex = index;
1089      }
1090      if (plugin.cacheWillUpdate) {
1091        cacheWillUpdatePluginCount++;
1092      }
1093    }
1094    if (cacheWillUpdatePluginCount === 0) {
1095      this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin);
1096    } else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) {
1097      this.plugins.splice(defaultPluginIndex, 1);
1098    }
1099  }
1100}
1101PrecacheStrategy.defaultPrecacheCacheabilityPlugin = {
1102  async cacheWillUpdate({ response }) {
1103    if (!response || response.status >= 400) {
1104      return null;
1105    }
1106    return response;
1107  }
1108};
1109PrecacheStrategy.copyRedirectedCacheableResponsesPlugin = {
1110  async cacheWillUpdate({ response }) {
1111    return response.redirected ? await copyResponse(response) : response;
1112  }
1113};
1114
1115class PrecacheController {
1116  /**
1117   * Create a new PrecacheController.
1118   *
1119   * @param {Object} [options]
1120   * @param {string} [options.cacheName] The cache to use for precaching.
1121   * @param {string} [options.plugins] Plugins to use when precaching as well
1122   * as responding to fetch events for precached assets.
1123   * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to
1124   * get the response from the network if there's a precache miss.
1125   */
1126  constructor({ cacheName, plugins = [], fallbackToNetwork = true } = {}) {
1127    this._urlsToCacheKeys = /* @__PURE__ */ new Map();
1128    this._urlsToCacheModes = /* @__PURE__ */ new Map();
1129    this._cacheKeysToIntegrities = /* @__PURE__ */ new Map();
1130    this._strategy = new PrecacheStrategy({
1131      cacheName: cacheNames.getPrecacheName(cacheName),
1132      plugins: [
1133        ...plugins,
1134        new PrecacheCacheKeyPlugin({ precacheController: this })
1135      ],
1136      fallbackToNetwork
1137    });
1138    this.install = this.install.bind(this);
1139    this.activate = this.activate.bind(this);
1140  }
1141  /**
1142   * @type {workbox-precaching.PrecacheStrategy} The strategy created by this controller and
1143   * used to cache assets and respond to fetch events.
1144   */
1145  get strategy() {
1146    return this._strategy;
1147  }
1148  /**
1149   * Adds items to the precache list, removing any duplicates and
1150   * stores the files in the
1151   * {@link workbox-core.cacheNames|"precache cache"} when the service
1152   * worker installs.
1153   *
1154   * This method can be called multiple times.
1155   *
1156   * @param {Array<Object|string>} [entries=[]] Array of entries to precache.
1157   */
1158  precache(entries) {
1159    this.addToCacheList(entries);
1160    if (!this._installAndActiveListenersAdded) {
1161      self.addEventListener("install", this.install);
1162      self.addEventListener("activate", this.activate);
1163      this._installAndActiveListenersAdded = true;
1164    }
1165  }
1166  /**
1167   * This method will add items to the precache list, removing duplicates
1168   * and ensuring the information is valid.
1169   *
1170   * @param {Array<workbox-precaching.PrecacheController.PrecacheEntry|string>} entries
1171   *     Array of entries to precache.
1172   */
1173  addToCacheList(entries) {
1174    const urlsToWarnAbout = [];
1175    for (const entry of entries) {
1176      if (typeof entry === "string") {
1177        urlsToWarnAbout.push(entry);
1178      } else if (entry && entry.revision === void 0) {
1179        urlsToWarnAbout.push(entry.url);
1180      }
1181      const { cacheKey, url } = createCacheKey(entry);
1182      const cacheMode = typeof entry !== "string" && entry.revision ? "reload" : "default";
1183      if (this._urlsToCacheKeys.has(url) && this._urlsToCacheKeys.get(url) !== cacheKey) {
1184        throw new WorkboxError("add-to-cache-list-conflicting-entries", {
1185          firstEntry: this._urlsToCacheKeys.get(url),
1186          secondEntry: cacheKey
1187        });
1188      }
1189      if (typeof entry !== "string" && entry.integrity) {
1190        if (this._cacheKeysToIntegrities.has(cacheKey) && this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) {
1191          throw new WorkboxError("add-to-cache-list-conflicting-integrities", {
1192            url
1193          });
1194        }
1195        this._cacheKeysToIntegrities.set(cacheKey, entry.integrity);
1196      }
1197      this._urlsToCacheKeys.set(url, cacheKey);
1198      this._urlsToCacheModes.set(url, cacheMode);
1199      if (urlsToWarnAbout.length > 0) {
1200        const warningMessage = `Workbox is precaching URLs without revision info: ${urlsToWarnAbout.join(", ")}
1201This is generally NOT safe. Learn more at https://bit.ly/wb-precache`;
1202        {
1203          console.warn(warningMessage);
1204        }
1205      }
1206    }
1207  }
1208  /**
1209   * Precaches new and updated assets. Call this method from the service worker
1210   * install event.
1211   *
1212   * Note: this method calls `event.waitUntil()` for you, so you do not need
1213   * to call it yourself in your event handlers.
1214   *
1215   * @param {ExtendableEvent} event
1216   * @return {Promise<workbox-precaching.InstallResult>}
1217   */
1218  install(event) {
1219    return waitUntil(event, async () => {
1220      const installReportPlugin = new PrecacheInstallReportPlugin();
1221      this.strategy.plugins.push(installReportPlugin);
1222      for (const [url, cacheKey] of this._urlsToCacheKeys) {
1223        const integrity = this._cacheKeysToIntegrities.get(cacheKey);
1224        const cacheMode = this._urlsToCacheModes.get(url);
1225        const request = new Request(url, {
1226          integrity,
1227          cache: cacheMode,
1228          credentials: "same-origin"
1229        });
1230        await Promise.all(this.strategy.handleAll({
1231          params: { cacheKey },
1232          request,
1233          event
1234        }));
1235      }
1236      const { updatedURLs, notUpdatedURLs } = installReportPlugin;
1237      return { updatedURLs, notUpdatedURLs };
1238    });
1239  }
1240  /**
1241   * Deletes assets that are no longer present in the current precache manifest.
1242   * Call this method from the service worker activate event.
1243   *
1244   * Note: this method calls `event.waitUntil()` for you, so you do not need
1245   * to call it yourself in your event handlers.
1246   *
1247   * @param {ExtendableEvent} event
1248   * @return {Promise<workbox-precaching.CleanupResult>}
1249   */
1250  activate(event) {
1251    return waitUntil(event, async () => {
1252      const cache = await self.caches.open(this.strategy.cacheName);
1253      const currentlyCachedRequests = await cache.keys();
1254      const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());
1255      const deletedURLs = [];
1256      for (const request of currentlyCachedRequests) {
1257        if (!expectedCacheKeys.has(request.url)) {
1258          await cache.delete(request);
1259          deletedURLs.push(request.url);
1260        }
1261      }
1262      return { deletedURLs };
1263    });
1264  }
1265  /**
1266   * Returns a mapping of a precached URL to the corresponding cache key, taking
1267   * into account the revision information for the URL.
1268   *
1269   * @return {Map<string, string>} A URL to cache key mapping.
1270   */
1271  getURLsToCacheKeys() {
1272    return this._urlsToCacheKeys;
1273  }
1274  /**
1275   * Returns a list of all the URLs that have been precached by the current
1276   * service worker.
1277   *
1278   * @return {Array<string>} The precached URLs.
1279   */
1280  getCachedURLs() {
1281    return [...this._urlsToCacheKeys.keys()];
1282  }
1283  /**
1284   * Returns the cache key used for storing a given URL. If that URL is
1285   * unversioned, like `/index.html', then the cache key will be the original
1286   * URL with a search parameter appended to it.
1287   *
1288   * @param {string} url A URL whose cache key you want to look up.
1289   * @return {string} The versioned URL that corresponds to a cache key
1290   * for the original URL, or undefined if that URL isn't precached.
1291   */
1292  getCacheKeyForURL(url) {
1293    const urlObject = new URL(url, location.href);
1294    return this._urlsToCacheKeys.get(urlObject.href);
1295  }
1296  /**
1297   * @param {string} url A cache key whose SRI you want to look up.
1298   * @return {string} The subresource integrity associated with the cache key,
1299   * or undefined if it's not set.
1300   */
1301  getIntegrityForCacheKey(cacheKey) {
1302    return this._cacheKeysToIntegrities.get(cacheKey);
1303  }
1304  /**
1305   * This acts as a drop-in replacement for
1306   * [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match)
1307   * with the following differences:
1308   *
1309   * - It knows what the name of the precache is, and only checks in that cache.
1310   * - It allows you to pass in an "original" URL without versioning parameters,
1311   * and it will automatically look up the correct cache key for the currently
1312   * active revision of that URL.
1313   *
1314   * E.g., `matchPrecache('index.html')` will find the correct precached
1315   * response for the currently active service worker, even if the actual cache
1316   * key is `'/index.html?__WB_REVISION__=1234abcd'`.
1317   *
1318   * @param {string|Request} request The key (without revisioning parameters)
1319   * to look up in the precache.
1320   * @return {Promise<Response|undefined>}
1321   */
1322  async matchPrecache(request) {
1323    const url = request instanceof Request ? request.url : request;
1324    const cacheKey = this.getCacheKeyForURL(url);
1325    if (cacheKey) {
1326      const cache = await self.caches.open(this.strategy.cacheName);
1327      return cache.match(cacheKey);
1328    }
1329    return void 0;
1330  }
1331  /**
1332   * Returns a function that looks up `url` in the precache (taking into
1333   * account revision information), and returns the corresponding `Response`.
1334   *
1335   * @param {string} url The precached URL which will be used to lookup the
1336   * `Response`.
1337   * @return {workbox-routing~handlerCallback}
1338   */
1339  createHandlerBoundToURL(url) {
1340    const cacheKey = this.getCacheKeyForURL(url);
1341    if (!cacheKey) {
1342      throw new WorkboxError("non-precached-url", { url });
1343    }
1344    return (options) => {
1345      options.request = new Request(url);
1346      options.params = Object.assign({ cacheKey }, options.params);
1347      return this.strategy.handle(options);
1348    };
1349  }
1350}
1351
1352/*
1353  Copyright 2019 Google LLC
1354
1355  Use of this source code is governed by an MIT-style
1356  license that can be found in the LICENSE file or at
1357  https://opensource.org/licenses/MIT.
1358*/
1359let precacheController;
1360/**
1361 * @return {PrecacheController}
1362 * @private
1363 */
1364const getOrCreatePrecacheController = () => {
1365    if (!precacheController) {
1366        precacheController = new PrecacheController();
1367    }
1368    return precacheController;
1369};
1370
1371// @ts-ignore
1372try {
1373    self['workbox:routing:7.3.0'] && _();
1374}
1375catch (e) { }
1376
1377/*
1378  Copyright 2018 Google LLC
1379
1380  Use of this source code is governed by an MIT-style
1381  license that can be found in the LICENSE file or at
1382  https://opensource.org/licenses/MIT.
1383*/
1384/**
1385 * The default HTTP method, 'GET', used when there's no specific method
1386 * configured for a route.
1387 *
1388 * @type {string}
1389 *
1390 * @private
1391 */
1392const defaultMethod = 'GET';
1393
1394const normalizeHandler = (handler) => {
1395  if (handler && typeof handler === "object") {
1396    return handler;
1397  } else {
1398    return { handle: handler };
1399  }
1400};
1401
1402class Route {
1403  /**
1404   * Constructor for Route class.
1405   *
1406   * @param {workbox-routing~matchCallback} match
1407   * A callback function that determines whether the route matches a given
1408   * `fetch` event by returning a non-falsy value.
1409   * @param {workbox-routing~handlerCallback} handler A callback
1410   * function that returns a Promise resolving to a Response.
1411   * @param {string} [method='GET'] The HTTP method to match the Route
1412   * against.
1413   */
1414  constructor(match, handler, method = defaultMethod) {
1415    this.handler = normalizeHandler(handler);
1416    this.match = match;
1417    this.method = method;
1418  }
1419  /**
1420   *
1421   * @param {workbox-routing-handlerCallback}
1421 handler A callback
1422   * function that returns a Promise resolving to a Response
1423   */
1424  setCatchHandler(handler) {
1425    this.catchHandler = normalizeHandler(handler);
1426  }
1427}
1428
1429class RegExpRoute extends Route {
1430  /**
1431   * If the regular expression contains
1432   * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references},
1433   * the captured values will be passed to the
1434   * {@link workbox-routing~handlerCallback} `params`
1435   * argument.
1436   *
1437   * @param {RegExp} regExp The regular expression to match against URLs.
1438   * @param {workbox-routing~handlerCallback} handler A callback
1439   * function that returns a Promise resulting in a Response.
1440   * @param {string} [method='GET'] The HTTP method to match the Route
1441   * against.
1442   */
1443  constructor(regExp, handler, method) {
1444    const match = ({ url }) => {
1445      const result = regExp.exec(url.href);
1446      if (!result) {
1447        return;
1448      }
1449      if (url.origin !== location.origin && result.index !== 0) {
1450        return;
1451      }
1452      return result.slice(1);
1453    };
1454    super(match, handler, method);
1455  }
1456}
1457
1458class Router {
1459  /**
1460   * Initializes a new Router.
1461   */
1462  constructor() {
1463    this._routes = /* @__PURE__ */ new Map();
1464    this._defaultHandlerMap = /* @__PURE__ */ new Map();
1465  }
1466  /**
1467   * @return {Map<string, Array<workbox-routing.Route>>} routes A `Map` of HTTP
1468   * method name ('GET', etc.) to an array of all the corresponding `Route`
1469   * instances that are registered.
1470   */
1471  get routes() {
1472    return this._routes;
1473  }
1474  /**
1475   * Adds a fetch event listener to respond to events when a route matches
1476   * the event's request.
1477   */
1478  addFetchListener() {
1479    self.addEventListener("fetch", ((event) => {
1480      const { request } = event;
1481      const responsePromise = this.handleRequest({ request, event });
1482      if (responsePromise) {
1483        event.respondWith(responsePromise);
1484      }
1485    }));
1486  }
1487  /**
1488   * Adds a message event listener for URLs to cache from the window.
1489   * This is useful to cache resources loaded on the page prior to when the
1490   * service worker started controlling it.
1491   *
1492   * The format of the message data sent from the window should be as follows.
1493   * Where the `urlsToCache` array may consist of URL strings or an array of
1494   * URL string + `requestInit` object (the same as you'd pass to `fetch()`).
1495   *
1496   * ```
1497   * {
1498   *   type: 'CACHE_URLS',
1499   *   payload: {
1500   *     urlsToCache: [
1501   *       './script1.js',
1502   *       './script2.js',
1503   *       ['./script3.js', {mode: 'no-cors'}],
1504   *     ],
1505   *   },
1506   * }
1507   * ```
1508   */
1509  addCacheListener() {
1510    self.addEventListener("message", ((event) => {
1511      if (event.data && event.data.type === "CACHE_URLS") {
1512        const { payload } = event.data;
1513        const requestPromises = Promise.all(payload.urlsToCache.map((entry) => {
1514          if (typeof entry === "string") {
1515            entry = [entry];
1516          }
1517          const request = new Request(...entry);
1518          return this.handleRequest({ request, event });
1519        }));
1520        event.waitUntil(requestPromises);
1521        if (event.ports && event.ports[0]) {
1522          void requestPromises.then(() => event.ports[0].postMessage(true));
1523        }
1524      }
1525    }));
1526  }
1527  /**
1528   * Apply the routing rules to a FetchEvent object to get a Response from an
1529   * appropriate Route's handler.
1530   *
1531   * @param {Object} options
1532   * @param {Request} options.request The request to handle.
1533   * @param {ExtendableEvent} options.event The event that triggered the
1534   *     request.
1535   * @return {Promise<Response>|undefined} A promise is returned if a
1536   *     registered route can handle the request. If there is no matching
1537   *     route and there's no `defaultHandler`, `undefined` is returned.
1538   */
1539  handleRequest({ request, event }) {
1540    const url = new URL(request.url, location.href);
1541    if (!url.protocol.startsWith("http")) {
1542      return;
1543    }
1544    const sameOrigin = url.origin === location.origin;
1545    const { params, route } = this.findMatchingRoute({
1546      event,
1547      request,
1548      sameOrigin,
1549      url
1550    });
1551    let handler = route && route.handler;
1552    const method = request.method;
1553    if (!handler && this._defaultHandlerMap.has(method)) {
1554      handler = this._defaultHandlerMap.get(method);
1555    }
1556    if (!handler) {
1557      return;
1558    }
1559    let responsePromise;
1560    try {
1561      responsePromise = handler.handle({ url, request, event, params });
1562    } catch (err) {
1563      responsePromise = Promise.reject(err);
1564    }
1565    const catchHandler = route && route.catchHandler;
1566    if (responsePromise instanceof Promise && (this._catchHandler || catchHandler)) {
1567      responsePromise = responsePromise.catch(async (err) => {
1568        if (catchHandler) {
1569          try {
1570            return await catchHandler.handle({ url, request, event, params });
1571          } catch (catchErr) {
1572            if (catchErr instanceof Error) {
1573              err = catchErr;
1574            }
1575          }
1576        }
1577        if (this._catchHandler) {
1578          return this._catchHandler.handle({ url, request, event });
1579        }
1580        throw err;
1581      });
1582    }
1583    return responsePromise;
1584  }
1585  /**
1586   * Checks a request and URL (and optionally an event) against the list of
1587   * registered routes, and if there's a match, returns the corresponding
1588   * route along with any params generated by the match.
1589   *
1590   * @param {Object} options
1591   * @param {URL} options.url
1592   * @param {boolean} options.sameOrigin The result of comparing `url.origin`
1593   *     against the current origin.
1594   * @param {Request} options.request The request to match.
1595   * @param {Event} options.event The corresponding event.
1596   * @return {Object} An object with `route` and `params` properties.
1597   *     They are populated if a matching route was found or `undefined`
1598   *     otherwise.
1599   */
1600  findMatchingRoute({ url, sameOrigin, request, event }) {
1601    const routes = this._routes.get(request.method) || [];
1602    for (const route of routes) {
1603      let params;
1604      const matchResult = route.match({ url, sameOrigin, request, event });
1605      if (matchResult) {
1606        params = matchResult;
1607        if (Array.isArray(params) && params.length === 0) {
1608          params = void 0;
1609        } else if (matchResult.constructor === Object && // eslint-disable-line
1610        Object.keys(matchResult).length === 0) {
1611          params = void 0;
1612        } else if (typeof matchResult === "boolean") {
1613          params = void 0;
1614        }
1615        return { route, params };
1616      }
1617    }
1618    return {};
1619  }
1620  /**
1621   * Define a default `handler` that's called when no routes explicitly
1622   * match the incoming request.
1623   *
1624   * Each HTTP method ('GET', 'POST', etc.) gets its own default handler.
1625   *
1626   * Without a default handler, unmatched requests will go against the
1627   * network as if there were no service worker present.
1628   *
1629   * @param {workbox-routing~handlerCallback}
1629 handler A callback
1630   * function that returns a Promise resulting in a Response.
1631   * @param {string} [method='GET'] The HTTP method to associate with this
1632   * default handler. Each method has its own default.
1633   */
1634  setDefaultHandler(handler, method = defaultMethod) {
1635    this._defaultHandlerMap.set(method, normalizeHandler(handler));
1636  }
1637  /**
1638   * If a Route throws an error while handling a request, this `handler`
1639   * will be called and given a chance to provide a response.
1640   *
1641   * @param {workbox-routing~handlerCallback} handler A callback
1642   * function that returns a Promise resulting in a Response.
1643   */
1644  setCatchHandler(handler) {
1645    this._catchHandler = normalizeHandler(handler);
1646  }
1647  /**
1648   * Registers a route with the router.
1649   *
1650   * @param {workbox-routing.Route} route The route to register.
1651   */
1652  registerRoute(route) {
1653    if (!this._routes.has(route.method)) {
1654      this._routes.set(route.method, []);
1655    }
1656    this._routes.get(route.method).push(route);
1657  }
1658  /**
1659   * Unregisters a route with the router.
1660   *
1661   * @param {workbox-routing.Route} route The route to unregister.
1662   */
1663  unregisterRoute(route) {
1664    if (!this._routes.has(route.method)) {
1665      throw new WorkboxError("unregister-route-but-not-found-with-method", {
1666        method: route.method
1667      });
1668    }
1669    const routeIndex = this._routes.get(route.method).indexOf(route);
1670    if (routeIndex > -1) {
1671      this._routes.get(route.method).splice(routeIndex, 1);
1672    } else {
1673      throw new WorkboxError("unregister-route-route-not-registered");
1674    }
1675  }
1676}
1677
1678/*
1679  Copyright 2019 Google LLC
1680
1681  Use of this source code is governed by an MIT-style
1682  license that can be found in the LICENSE file or at
1683  https://opensource.org/licenses/MIT.
1684*/
1685let defaultRouter;
1686/**
1687 * Creates a new, singleton Router instance if one does not exist. If one
1688 * does already exist, that instance is returned.
1689 *
1690 * @private
1691 * @return {Router}
1692 */
1693const getOrCreateDefaultRouter = () => {
1694    if (!defaultRouter) {
1695        defaultRouter = new Router();
1696        // The helpers that use the default Router assume these listeners exist.
1697        defaultRouter.addFetchListener();
1698        defaultRouter.addCacheListener();
1699    }
1700    return defaultRouter;
1701};
1702
1703function registerRoute(capture, handler, method) {
1704  let route;
1705  if (typeof capture === "string") {
1706    const captureUrl = new URL(capture, location.href);
1707    const matchCallback = ({ url }) => {
1708      return url.href === captureUrl.href;
1709    };
1710    route = new Route(matchCallback, handler, method);
1711  } else if (capture instanceof RegExp) {
1712    route = new RegExpRoute(capture, handler, method);
1713  } else if (typeof capture === "function") {
1714    route = new Route(capture, handler, method);
1715  } else if (capture instanceof Route) {
1716    route = capture;
1717  } else {
1718    throw new WorkboxError("unsupported-route-type", {
1719      moduleName: "workbox-routing",
1720      funcName: "registerRoute",
1721      paramName: "capture"
1722    });
1723  }
1724  const defaultRouter = getOrCreateDefaultRouter();
1725  defaultRouter.registerRoute(route);
1726  return route;
1727}
1728
1729/*
1730  Copyright 2018 Google LLC
1731
1732  Use of this source code is governed by an MIT-style
1733  license that can be found in the LICENSE file or at
1734  https://opensource.org/licenses/MIT.
1735*/
1736/**
1737 * Removes any URL search parameters that should be ignored.
1738 *
1739 * @param {URL} urlObject The original URL.
1740 * @param {Array<RegExp>} ignoreURLParametersMatching RegExps to test against
1741 * each search parameter name. Matches mean that the search parameter should be
1742 * ignored.
1743 * @return {URL} The URL with any ignored search parameters removed.
1744 *
1745 * @private
1746 * @memberof workbox-precaching
1747 */
1748function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) {
1749    // Convert the iterable into an array at the start of the loop to make sure
1750    // deletion doesn't mess up iteration.
1751    for (const paramName of [...urlObject.searchParams.keys()]) {
1752        if (ignoreURLParametersMatching.some((regExp) => regExp.test(paramName))) {
1753            urlObject.searchParams.delete(paramName);
1754        }
1755    }
1756    return urlObject;
1757}
1758
1759/*
1760  Copyright 2019 Google LLC
1761
1762  Use of this source code is governed by an MIT-style
1763  license that can be found in the LICENSE file or at
1764  https://opensource.org/licenses/MIT.
1765*/
1766/**
1767 * Generator function that yields possible variations on the original URL to
1768 * check, one at a time.
1769 *
1770 * @param {string} url
1771 * @param {Object} options
1772 *
1773 * @private
1774 * @memberof workbox-precaching
1775 */
1776function* generateURLVariations(url, { ignoreURLParametersMatching = [/^utm_/, /^fbclid$/], directoryIndex = 'index.html', cleanURLs = true, urlManipulation, } = {}) {
1777    const urlObject = new URL(url, location.href);
1778    urlObject.hash = '';
1779    yield urlObject.href;
1780    const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching);
1781    yield urlWithoutIgnoredParams.href;
1782    if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) {
1783        const directoryURL = new URL(urlWithoutIgnoredParams.href);
1784        directoryURL.pathname += directoryIndex;
1785        yield directoryURL.href;
1786    }
1787    if (cleanURLs) {
1788        const cleanURL = new URL(urlWithoutIgnoredParams.href);
1789        cleanURL.pathname += '.html';
1790        yield cleanURL.href;
1791    }
1792    if (urlManipulation) {
1793        const additionalURLs = urlManipulation({ url: urlObject });
1794        for (const urlToAttempt of additionalURLs) {
1795            yield urlToAttempt.href;
1796        }
1797    }
1798}
1799
1800class PrecacheRoute extends Route {
1801  /**
1802   * @param {PrecacheController} precacheController A `PrecacheController`
1803   * instance used to both match requests and respond to fetch events.
1804   * @param {Object} [options] Options to control how requests are matched
1805   * against the list of precached URLs.
1806   * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will
1807   * check cache entries for a URLs ending with '/' to see if there is a hit when
1808   * appending the `directoryIndex` value.
1809   * @param {Array<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An
1810   * array of regex's to remove search params when looking for a cache match.
1811   * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will
1812   * check the cache for the URL with a `.html` added to the end of the end.
1813   * @param {workbox-precaching~urlManipulation} [options.urlManipulation]
1814   * This is a function that should take a URL and return an array of
1815   * alternative URLs that should be checked for precache matches.
1816   */
1817  constructor(precacheController, options) {
1818    const match = ({ request }) => {
1819      const urlsToCacheKeys = precacheController.getURLsToCacheKeys();
1820      for (const possibleURL of generateURLVariations(request.url, options)) {
1821        const cacheKey = urlsToCacheKeys.get(possibleURL);
1822        if (cacheKey) {
1823          const integrity = precacheController.getIntegrityForCacheKey(cacheKey);
1824          return { cacheKey, integrity };
1825        }
1826      }
1827      return;
1828    };
1829    super(match, precacheController.strategy);
1830  }
1831}
1832
1833/*
1834  Copyright 2019 Google LLC
1835  Use of this source code is governed by an MIT-style
1836  license that can be found in the LICENSE file or at
1837  https://opensource.org/licenses/MIT.
1838*/
1839/**
1840 * Add a `fetch` listener to the service worker that will
1841 * respond to
1842 * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}
1843 * with precached assets.
1844 *
1845 * Requests for assets that aren't precached, the `FetchEvent` will not be
1846 * responded to, allowing the event to fall through to other `fetch` event
1847 * listeners.
1848 *
1849 * @param {Object} [options] See the {@link workbox-precaching.PrecacheRoute}
1850 * options.
1851 *
1852 * @memberof workbox-precaching
1853 */
1854function addRoute(options) {
1855    const precacheController = getOrCreatePrecacheController();
1856    const precacheRoute = new PrecacheRoute(precacheController, options);
1857    registerRoute(precacheRoute);
1858}
1859
1860/*
1861  Copyright 2019 Google LLC
1862
1863  Use of this source code is governed by an MIT-style
1864  license that can be found in the LICENSE file or at
1865  https://opensource.org/licenses/MIT.
1866*/
1867/**
1868 * Helper function that calls
1869 * {@link PrecacheController#matchPrecache} on the default
1870 * {@link PrecacheController} instance.
1871 *
1872 * If you are creating your own {@link PrecacheController}, then call
1873 * {@link PrecacheController#matchPrecache} on that instance,
1874 * instead of using this function.
1875 *
1876 * @param {string|Request} request The key (without revisioning parameters)
1877 * to look up in the precache.
1878 * @return {Promise<Response|undefined>}
1879 *
1880 * @memberof workbox-precaching
1881 */
1882function matchPrecache(request) {
1883    const precacheController = getOrCreatePrecacheController();
1884    return precacheController.matchPrecache(request);
1885}
1886
1887/*
1888  Copyright 2019 Google LLC
1889
1890  Use of this source code is governed by an MIT-style
1891  license that can be found in the LICENSE file or at
1892  https://opensource.org/licenses/MIT.
1893*/
1894/**
1895 * Adds items to the precache list, removing any duplicates and
1896 * stores the files in the
1897 * {@link workbox-core.cacheNames|"precache cache"} when the service
1898 * worker installs.
1899 *
1900 * This method can be called multiple times.
1901 *
1902 * Please note: This method **will not** serve any of the cached files for you.
1903 * It only precaches files. To respond to a network request you call
1904 * {@link workbox-precaching.addRoute}.
1905 *
1906 * If you have a single array of files to precache, you can just call
1907 * {@link workbox-precaching.precacheAndRoute}.
1908 *
1909 * @param {Array<Object|string>} [entries=[]] Array of entries to precache.
1910 *
1911 * @memberof workbox-precaching
1912 */
1913function precache(entries) {
1914    const precacheController = getOrCreatePrecacheController();
1915    precacheController.precache(entries);
1916}
1917
1918/*
1919  Copyright 2019 Google LLC
1920
1921  Use of this source code is governed by an MIT-style
1922  license that can be found in the LICENSE file or at
1923  https://opensource.org/licenses/MIT.
1924*/
1925/**
1926 * This method will add entries to the precache list and add a route to
1927 * respond to fetch events.
1928 *
1929 * This is a convenience method that will call
1930 * {@link workbox-precaching.precache} and
1931 * {@link workbox-precaching.addRoute} in a single call.
1932 *
1933 * @param {Array<Object|string>} entries Array of entries to precache.
1934 * @param {Object} [options] See the
1935 * {@link workbox-precaching.PrecacheRoute} options.
1936 *
1937 * @memberof workbox-precaching
1938 */
1939function precacheAndRoute(entries, options) {
1940    precache(entries);
1941    addRoute(options);
1942}
1943
1944class NavigationRoute extends Route {
1945  /**
1946   * If both `denylist` and `allowlist` are provided, the `denylist` will
1947   * take precedence and the request will not match this route.
1948   *
1949   * The regular expressions in `allowlist` and `denylist`
1950   * are matched against the concatenated
1951   * [`pathname`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname}
1952   * and [`search`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search}
1953   * portions of the requested URL.
1954   *
1955   * *Note*: These RegExps may be evaluated against every destination URL during
1956   * a navigation. Avoid using
1957   * [complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077),
1958   * or else your users may see delays when navigating your site.
1959   *
1960   * @param {workbox-routing~handlerCallback} handler A callback
1961   * function that returns a Promise resulting in a Response.
1962   * @param {Object} options
1963   * @param {Array<RegExp>} [options.denylist] If any of these patterns match,
1964   * the route will not handle the request (even if a allowlist RegExp matches).
1965   * @param {Array<RegExp>} [options.allowlist=[/./]] If any of these patterns
1966   * match the URL's pathname and search parameter, the route will handle the
1967   * request (assuming the denylist doesn't match).
1968   */
1969  constructor(handler, { allowlist = [/./], denylist = [] } = {}) {
1970    super((options) => this._match(options), handler);
1971    this._allowlist = allowlist;
1972    this._denylist = denylist;
1973  }
1974  /**
1975   * Routes match handler.
1976   *
1977   * @param {Object} options
1978   * @param {URL} options.url
1979   * @param {Request} options.request
1980   * @return {boolean}
1981   *
1982   * @private
1983   */
1984  _match({ url, request }) {
1985    if (request && request.mode !== "navigate") {
1986      return false;
1987    }
1988    const pathnameAndSearch = url.pathname + url.search;
1989    for (const regExp of this._denylist) {
1990      if (regExp.test(pathnameAndSearch)) {
1991        return false;
1992      }
1993    }
1994    if (this._allowlist.some((regExp) => regExp.test(pathnameAndSearch))) {
1995      return true;
1996    }
1997    return false;
1998  }
1999}
2000
2001class CacheFirst extends Strategy {
2002  /**
2003   * @private
2004   * @param {Request|string} request A request to run this strategy for.
2005   * @param {workbox-strategies.StrategyHandler} handler The event that
2006   *     triggered the request.
2007   * @return {Promise<Response>}
2008   */
2009  async _handle(request, handler) {
2010    let response = await handler.cacheMatch(request);
2011    let error = void 0;
2012    if (!response) {
2013      try {
2014        response = await handler.fetchAndCachePut(request);
2015      } catch (err) {
2016        if (err instanceof Error) {
2017          error = err;
2018        }
2019      }
2020    }
2021    if (!response) {
2022      throw new WorkboxError("no-response", { url: request.url, error });
2023    }
2024    return response;
2025  }
2026}
2027
2028/*
2029  Copyright 2018 Google LLC
2030
2031  Use of this source code is governed by an MIT-style
2032  license that can be found in the LICENSE file or at
2033  https://opensource.org/licenses/MIT.
2034*/
2035const cacheOkAndOpaquePlugin = {
2036    /**
2037     * Returns a valid response (to allow caching) if the status is 200 (OK) or
2038     * 0 (opaque).
2039     *
2040     * @param {Object} options
2041     * @param {Response} options.response
2042     * @return {Response|null}
2043     *
2044     * @private
2045     */
2046    cacheWillUpdate: async ({ response }) => {
2047        if (response.status === 200 || response.status === 0) {
2048            return response;
2049        }
2050        return null;
2051    },
2052};
2053
2054class NetworkFirst extends Strategy {
2055  /**
2056   * @param {Object} [options]
2057   * @param {string} [options.cacheName] Cache name to store and retrieve
2058   * requests. Defaults to cache names provided by
2059   * {@link workbox-core.cacheNames}.
2060   * @param {Array<Object>} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
2061   * to use in conjunction with this caching strategy.
2062   * @param {Object} [options.fetchOptions] Values passed along to the
2063   * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
2064   * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796)
2065   * `fetch()` requests made by this strategy.
2066   * @param {Object} [options.matchOptions] [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)
2067   * @param {number} [options.networkTimeoutSeconds] If set, any network requests
2068   * that fail to respond within the timeout will fallback to the cache.
2069   *
2070   * This option can be used to combat
2071   * "[lie-fi]{@link https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi}"
2072   * scenarios.
2073   */
2074  constructor(options = {}) {
2075    super(options);
2076    if (!this.plugins.some((p) => "cacheWillUpdate" in p)) {
2077      this.plugins.unshift(cacheOkAndOpaquePlugin);
2078    }
2079    this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0;
2080  }
2081  /**
2082   * @private
2083   * @param {Request|string} request A request to run this strategy for.
2084   * @param {workbox-strategies.StrategyHandler} handler The event that
2085   *     triggered the request.
2086   * @return {Promise<Response>}
2087   */
2088  async _handle(request, handler) {
2089    const logs = [];
2090    const promises = [];
2091    let timeoutId;
2092    if (this._networkTimeoutSeconds) {
2093      const { id, promise } = this._getTimeoutPromise({ request, logs, handler });
2094      timeoutId = id;
2095      promises.push(promise);
2096    }
2097    const networkPromise = this._getNetworkPromise({
2098      timeoutId,
2099      request,
2100      logs,
2101      handler
2102    });
2103    promises.push(networkPromise);
2104    const response = await handler.waitUntil((async () => {
2105      return await handler.waitUntil(Promise.race(promises)) || // If Promise.race() resolved with null, it might be due to a network
2106      // timeout + a cache miss. If that were to happen, we'd rather wait until
2107      // the networkPromise resolves instead of returning null.
2108      // Note that it's fine to await an already-resolved promise, so we don't
2109      // have to check to see if it's still "in flight".
2110      await networkPromise;
2111    })());
2112    if (!response) {
2113      throw new WorkboxError("no-response", { url: request.url });
2114    }
2115    return response;
2116  }
2117  /**
2118   * @param {Object} options
2119   * @param {Request} options.request
2120   * @param {Array} options.logs A reference to the logs array
2121   * @param {Event} options.event
2122   * @return {Promise<Response>}
2123   *
2124   * @private
2125   */
2126  _getTimeoutPromise({ request, logs, handler }) {
2127    let timeoutId;
2128    const timeoutPromise = new Promise((resolve) => {
2129      const onNetworkTimeout = async () => {
2130        resolve(await handler.cacheMatch(request));
2131      };
2132      timeoutId = setTimeout(onNetworkTimeout, this._networkTimeoutSeconds * 1e3);
2133    });
2134    return {
2135      promise: timeoutPromise,
2136      id: timeoutId
2137    };
2138  }
2139  /**
2140   * @param {Object} options
2141   * @param {number|undefined} options.timeoutId
2142   * @param {Request} options.request
2143   * @param {Array} options.logs A reference to the logs Array.
2144   * @param {Event} options.event
2145   * @return {Promise<Response>}
2146   *
2147   * @private
2148   */
2149  async _getNetworkPromise({ timeoutId, request, logs, handler }) {
2150    let error;
2151    let response;
2152    try {
2153      response = await handler.fetchAndCachePut(request);
2154    } catch (fetchError) {
2155      if (fetchError instanceof Error) {
2156        error = fetchError;
2157      }
2158    }
2159    if (timeoutId) {
2160      clearTimeout(timeoutId);
2161    }
2162    if (error || !response) {
2163      response = await handler.cacheMatch(request);
2164    }
2165    return response;
2166  }
2167}
2168
2169/*
2170  Copyright 2019 Google LLC
2171  Use of this source code is governed by an MIT-style
2172  license that can be found in the LICENSE file or at
2173  https://opensource.org/licenses/MIT.
vendor: 5,282 bytes, lines 2174-2319
2174*/
2175/**
2176 * A helper function that prevents a promise from being flagged as unused.
2177 *
2178 * @private
2179 **/
2180function dontWaitFor(promise) {
2181    // Effective no-op.
2182    void promise.then(() => { });
2183}
2184
2185const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
2186
2187let idbProxyableTypes;
2188let cursorAdvanceMethods;
2189// This is a function to prevent it throwing up in node environments.
2190function getIdbProxyableTypes() {
2191    return (idbProxyableTypes ||
2192        (idbProxyableTypes = [
2193            IDBDatabase,
2194            IDBObjectStore,
2195            IDBIndex,
2196            IDBCursor,
2197            IDBTransaction,
2198        ]));
2199}
2200// This is a function to prevent it throwing up in node environments.
2201function getCursorAdvanceMethods() {
2202    return (cursorAdvanceMethods ||
2203        (cursorAdvanceMethods = [
2204            IDBCursor.prototype.advance,
2205            IDBCursor.prototype.continue,
2206            IDBCursor.prototype.continuePrimaryKey,
2207        ]));
2208}
2209const cursorRequestMap = new WeakMap();
2210const transactionDoneMap = new WeakMap();
2211const transactionStoreNamesMap = new WeakMap();
2212const transformCache = new WeakMap();
2213const reverseTransformCache = new WeakMap();
2214function promisifyRequest(request) {
2215    const promise = new Promise((resolve, reject) => {
2216        const unlisten = () => {
2217            request.removeEventListener('success', success);
2218            request.removeEventListener('error', error);
2219        };
2220        const success = () => {
2221            resolve(wrap(request.result));
2222            unlisten();
2223        };
2224        const error = () => {
2225            reject(request.error);
2226            unlisten();
2227        };
2228        request.addEventListener('success', success);
2229        request.addEventListener('error', error);
2230    });
2231    promise
2232        .then((value) => {
2233        // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval
2234        // (see wrapFunction).
2235        if (value instanceof IDBCursor) {
2236            cursorRequestMap.set(value, request);
2237        }
2238        // Catching to avoid "Uncaught Promise exceptions"
2239    })
2240        .catch(() => { });
2241    // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This
2242    // is because we create many promises from a single IDBRequest.
2243    reverseTransformCache.set(promise, request);
2244    return promise;
2245}
2246function cacheDonePromiseForTransaction(tx) {
2247    // Early bail if we've already created a done promise for this transaction.
2248    if (transactionDoneMap.has(tx))
2249        return;
2250    const done = new Promise((resolve, reject) => {
2251        const unlisten = () => {
2252            tx.removeEventListener('complete', complete);
2253            tx.removeEventListener('error', error);
2254            tx.removeEventListener('abort', error);
2255        };
2256        const complete = () => {
2257            resolve();
2258            unlisten();
2259        };
2260        const error = () => {
2261            reject(tx.error || new DOMException('AbortError', 'AbortError'));
2262            unlisten();
2263        };
2264        tx.addEventListener('complete', complete);
2265        tx.addEventListener('error', error);
2266        tx.addEventListener('abort', error);
2267    });
2268    // Cache it for later retrieval.
2269    transactionDoneMap.set(tx, done);
2270}
2271let idbProxyTraps = {
2272    get(target, prop, receiver) {
2273        if (target instanceof IDBTransaction) {
2274            // Special handling for transaction.done.
2275            if (prop === 'done')
2276                return transactionDoneMap.get(target);
2277            // Polyfill for objectStoreNames because of Edge.
2278            if (prop === 'objectStoreNames') {
2279                return target.objectStoreNames || transactionStoreNamesMap.get(target);
2280            }
2281            // Make tx.store return the only store in the transaction, or undefined if there are many.
2282            if (prop === 'store') {
2283                return receiver.objectStoreNames[1]
2284                    ? undefined
2285                    : receiver.objectStore(receiver.objectStoreNames[0]);
2286            }
2287        }
2288        // Else transform whatever we get back.
2289        return wrap(target[prop]);
2290    },
2291    set(target, prop, value) {
2292        target[prop] = value;
2293        return true;
2294    },
2295    has(target, prop) {
2296        if (target instanceof IDBTransaction &&
2297            (prop === 'done' || prop === 'store')) {
2298            return true;
2299        }
2300        return prop in target;
2301    },
2302};
2303function replaceTraps(callback) {
2304    idbProxyTraps = callback(idbProxyTraps);
2305}
2306function wrapFunction(func) {
2307    // Due to expected object equality (which is enforced by the caching in `wrap`), we
2308    // only create one new func per func.
2309    // Edge doesn't support objectStoreNames (booo), so we polyfill it here.
2310    if (func === IDBDatabase.prototype.transaction &&
2311        !('objectStoreNames' in IDBTransaction.prototype)) {
2312        return function (storeNames, ...args) {
2313            const tx = func.call(unwrap(this), storeNames, ...args);
2314            transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);
2315            return wrap(tx);
2316        };
2317    }
2318    // Cursor methods are special, as the behaviour is a little more different to standard IDB. In
2319    // IDB, you advance the cursor and wait for a new 'success' on the ID
vendor: 5,931 bytes, lines 2319-2471
2319BRequest that gave you the
2320    // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
2321    // with real promises, so each advance methods returns a new promise for the cursor object, or
2322    // undefined if the end of the cursor has been reached.
2323    if (getCursorAdvanceMethods().includes(func)) {
2324        return function (...args) {
2325            // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
2326            // the original object.
2327            func.apply(unwrap(this), args);
2328            return wrap(cursorRequestMap.get(this));
2329        };
2330    }
2331    return function (...args) {
2332        // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
2333        // the original object.
2334        return wrap(func.apply(unwrap(this), args));
2335    };
2336}
2337function transformCachableValue(value) {
2338    if (typeof value === 'function')
2339        return wrapFunction(value);
2340    // This doesn't return, it just creates a 'done' promise for the transaction,
2341    // which is later returned for transaction.done (see idbObjectHandler).
2342    if (value instanceof IDBTransaction)
2343        cacheDonePromiseForTransaction(value);
2344    if (instanceOfAny(value, getIdbProxyableTypes()))
2345        return new Proxy(value, idbProxyTraps);
2346    // Return the same value back if we're not going to transform it.
2347    return value;
2348}
2349function wrap(value) {
2350    // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
2351    // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
2352    if (value instanceof IDBRequest)
2353        return promisifyRequest(value);
2354    // If we've already transformed this value before, reuse the transformed value.
2355    // This is faster, but it also provides object equality.
2356    if (transformCache.has(value))
2357        return transformCache.get(value);
2358    const newValue = transformCachableValue(value);
2359    // Not all types are transformed.
2360    // These may be primitive types, so they can't be WeakMap keys.
2361    if (newValue !== value) {
2362        transformCache.set(value, newValue);
2363        reverseTransformCache.set(newValue, value);
2364    }
2365    return newValue;
2366}
2367const unwrap = (value) => reverseTransformCache.get(value);
2368
2369/**
2370 * Open a database.
2371 *
2372 * @param name Name of the database.
2373 * @param version Schema version.
2374 * @param callbacks Additional callbacks.
2375 */
2376function openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {
2377    const request = indexedDB.open(name, version);
2378    const openPromise = wrap(request);
2379    if (upgrade) {
2380        request.addEventListener('upgradeneeded', (event) => {
2381            upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
2382        });
2383    }
2384    if (blocked) {
2385        request.addEventListener('blocked', (event) => blocked(
2386        // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
2387        event.oldVersion, event.newVersion, event));
2388    }
2389    openPromise
2390        .then((db) => {
2391        if (terminated)
2392            db.addEventListener('close', () => terminated());
2393        if (blocking) {
2394            db.addEventListener('versionchange', (event) => blocking(event.oldVersion, event.newVersion, event));
2395        }
2396    })
2397        .catch(() => { });
2398    return openPromise;
2399}
2400/**
2401 * Delete a database.
2402 *
2403 * @param name Name of the database.
2404 */
2405function deleteDB(name, { blocked } = {}) {
2406    const request = indexedDB.deleteDatabase(name);
2407    if (blocked) {
2408        request.addEventListener('blocked', (event) => blocked(
2409        // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
2410        event.oldVersion, event));
2411    }
2412    return wrap(request).then(() => undefined);
2413}
2414
2415const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
2416const writeMethods = ['put', 'add', 'delete', 'clear'];
2417const cachedMethods = new Map();
2418function getMethod(target, prop) {
2419    if (!(target instanceof IDBDatabase &&
2420        !(prop in target) &&
2421        typeof prop === 'string')) {
2422        return;
2423    }
2424    if (cachedMethods.get(prop))
2425        return cachedMethods.get(prop);
2426    const targetFuncName = prop.replace(/FromIndex$/, '');
2427    const useIndex = prop !== targetFuncName;
2428    const isWrite = writeMethods.includes(targetFuncName);
2429    if (
2430    // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
2431    !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||
2432        !(isWrite || readMethods.includes(targetFuncName))) {
2433        return;
2434    }
2435    const method = async function (storeName, ...args) {
2436        // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
2437        const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
2438        let target = tx.store;
2439        if (useIndex)
2440            target = target.index(args.shift());
2441        // Must reject if op rejects.
2442        // If it's a write operation, must reject if tx.done rejects.
2443        // Must reject with op rejection first.
2444        // Must resolve with op value.
2445        // Must handle both promises (no unhandled rejections)
2446        return (await Promise.all([
2447            target[targetFuncName](...args),
2448            isWrite && tx.done,
2449        ]))[0];
2450    };
2451    cachedMethods.set(prop, method);
2452    return method;
2453}
2454replaceTraps((oldTraps) => ({
2455    ...oldTraps,
2456    get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
2457    has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),
2458}));
2459
2460// @ts-ignore
2461try {
2462    self['workbox:expiration:7.3.0'] && _();
2463}
2464catch (e) { }
2465
2466/*
2467  Copyright 2018 Google LLC
2468
2469  Use of this source code is governed by an MIT-style
2470  license that can be found in the LICENSE file or at
2471  https://opensource.org/licenses/MIT.
2472*/
2473const DB_NAME = 'workbox-expiration';
2474const CACHE_OBJECT_STORE = 'cache-entries';
2475const normalizeURL = (unNormalizedUrl) => {
2476    const url = new URL(unNormalizedUrl, location.href);
2477    url.hash = '';
2478    return url.href;
2479};
2480/**
2481 * Returns the timestamp model.
2482 *
2483 * @private
2484 */
2485class CacheTimestampsModel {
2486    /**
2487     *
2488     * @param {string} cacheName
2489     *
2490     * @private
2491     */
2492    constructor(cacheName) {
2493        this._db = null;
2494        this._cacheName = cacheName;
2495    }
2496    /**
2497     * Performs an upgrade of indexedDB.
2498     *
2499     * @param {IDBPDatabase<CacheDbSchema>} db
2500     *
2501     * @private
2502     */
2503    _upgradeDb(db) {
2504        // TODO(philipwalton): EdgeHTML doesn't support arrays as a keyPath, so we
2505        // have to use the `id` keyPath here and create our own values (a
2506        // concatenation of `url + cacheName`) instead of simply using
2507        // `keyPath: ['url', 'cacheName']`, which is supported in other browsers.
2508        const objStore = db.createObjectStore(CACHE_OBJECT_STORE, { keyPath: 'id' });
2509        // TODO(philipwalton): once we don't have to support EdgeHTML, we can
2510        // create a single index with the keyPath `['cacheName', 'timestamp']`
2511        // instead of doing both these indexes.
2512        objStore.createIndex('cacheName', 'cacheName', { unique: false });
2513        objStore.createIndex('timestamp', 'timestamp', { unique: false });
2514    }
2515    /**
2516     * Performs an upgrade of indexedDB and deletes deprecated DBs.
2517     *
2518     * @param {IDBPDatabase<CacheDbSchema>} db
2519     *
2520     * @private
2521     */
2522    _upgradeDbAndDeleteOldDbs(db) {
2523        this._upgradeDb(db);
2524        if (this._cacheName) {
2525            void deleteDB(this._cacheName);
2526        }
2527    }
2528    /**
2529     * @param {string} url
2530     * @param {number} timestamp
2531     *
2532     * @private
2533     */
2534    async setTimestamp(url, timestamp) {
2535        url = normalizeURL(url);
2536        const entry = {
2537            url,
2538            timestamp,
2539            cacheName: this._cacheName,
2540            // Creating an ID from the URL and cache name won't be necessary once
2541            // Edge switches to Chromium and all browsers we support work with
2542            // array keyPaths.
2543            id: this._getId(url),
2544        };
2545        const db = await this.getDb();
2546        const tx = db.transaction(CACHE_OBJECT_STORE, 'readwrite', {
2547            durability: 'relaxed',
2548        });
2549        await tx.store.put(entry);
2550        await tx.done;
2551    }
2552    /**
2553     * Returns the timestamp stored for a given URL.
2554     *
2555     * @param {string} url
2556     * @return {number | undefined}
2557     *
2558     * @private
2559     */
2560    async getTimestamp(url) {
2561        const db = await this.getDb();
2562        const entry = await db.get(CACHE_OBJECT_STORE, this._getId(url));
2563        return entry === null || entry === void 0 ? void 0 : entry.timestamp;
2564    }
2565    /**
2566     * Iterates through all the entries in the object store (from newest to
2567     * oldest) and removes entries once either `maxCount` is reached or the
2568     * entry's timestamp is less than `minTimestamp`.
2569     *
2570     * @param {number} minTimestamp
2571     * @param {number} maxCount
2572     * @return {Array<string>}
2573     *
2574     * @private
2575     */
2576    async expireEntries(minTimestamp, maxCount) {
2577        const db = await this.getDb();
2578        let cursor = await db
2579            .transaction(CACHE_OBJECT_STORE)
2580            .store.index('timestamp')
2581            .openCursor(null, 'prev');
2582        const entriesToDelete = [];
2583        let entriesNotDeletedCount = 0;
2584        while (cursor) {
2585            const result = cursor.value;
2586            // TODO(philipwalton): once we can use a multi-key index, we
2587            // won't have to check `cacheName` here.
2588            if (result.cacheName === this._cacheName) {
2589                // Delete an entry if it's older than the max age or
2590                // if we already have the max number allowed.
2591                if ((minTimestamp && result.timestamp < minTimestamp) ||
2592                    (maxCount && entriesNotDeletedCount >= maxCount)) {
2593                    // TODO(philipwalton): we should be able to delete the
2594                    // entry right here, but doing so causes an iteration
2595                    // bug in Safari stable (fixed in TP). Instead we can
2596                    // store the keys of the entries to delete, and then
2597                    // delete the separate transactions.
2598                    // https://github.com/GoogleChrome/workbox/issues/1978
2599                    // cursor.delete();
2600                    // We only need to return the URL, not the whole entry.
2601                    entriesToDelete.push(cursor.value);
2602                }
2603                else {
2604                    entriesNotDeletedCount++;
2605                }
2606            }
2607            cursor = await cursor.continue();
2608        }
2609        // TODO(philipwalton): once the Safari bug in the following issue is fixed,
2610        // we should be able to remove this loop and do the entry deletion in the
2611        // cursor loop above:
2612        // https://github.com/GoogleChrome/workbox/issues/1978
2613        const urlsDeleted = [];
2614        for (const entry of entriesToDelete) {
2615            await db.delete(CACHE_OBJECT_STORE, entry.id);
2616            urlsDeleted.push(entry.url);
2617        }
2618        return urlsDeleted;
2619    }
2620    /**
2621     * Takes a URL and returns an ID that will be unique in the object store.
2622     *
2623     * @param {string} url
2624     * @return {string}
2625     *
2626     * @private
2627     */
2628    _getId(url) {
2629        // Creating an ID from the URL and cache name won't be necessary once
2630        // Edge switches to Chromium and all browsers we support work with
2631        // array keyPaths.
2632        return this._cacheName + '|' + normalizeURL(url);
2633    }
2634    /**
2635     * Returns an open connection to the database.
2636     *
2637     * @private
2638     */
2639    async getDb() {
2640        if (!this._db) {
2641            this._db = await openDB(DB_NAME, 1, {
2642                upgrade: this._upgradeDbAndDeleteOldDbs.bind(this),
2643            });
2644        }
2645        return this._db;
2646    }
2647}
2648
2649class CacheExpiration {
2650  /**
2651   * To construct a new CacheExpiration instance you must provide at least
2652   * one of the `config` properties.
2653   *
2654   * @param {string} cacheName Name of the cache to apply restrictions to.
2655   * @param {Object} config
2656   * @param {number} [config.maxEntries] The maximum number of entries to cache.
2657   * Entries used the least will be removed as the maximum is reached.
2658   * @param {number} [config.maxAgeSeconds] The maximum age of an entry before
2659   * it's treated as stale and removed.
2660   * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)
2661   * that will be used when calling `delete()` on the cache.
2662   */
2663  constructor(cacheName, config = {}) {
2664    this._isRunning = false;
2665    this._rerunRequested = false;
2666    this._maxEntries = config.maxEntries;
2667    this._maxAgeSeconds = config.maxAgeSeconds;
2668    this._matchOptions = config.matchOptions;
2669    this._cacheName = cacheName;
2670    this._timestampModel = new CacheTimestampsModel(cacheName);
2671  }
2672  /**
2673   * Expires entries for the given cache and given criteria.
2674   */
2675  async expireEntries() {
2676    if (this._isRunning) {
2677      this._rerunRequested = true;
2678      return;
2679    }
2680    this._isRunning = true;
2681    const minTimestamp = this._maxAgeSeconds ? Date.now() - this._maxAgeSeconds * 1e3 : 0;
2682    const urlsExpired = await this._timestampModel.expireEntries(minTimestamp, this._maxEntries);
2683    const cache = await self.caches.open(this._cacheName);
2684    for (const url of urlsExpired) {
2685      await cache.delete(url, this._matchOptions);
2686    }
2687    this._isRunning = false;
2688    if (this._rerunRequested) {
2689      this._rerunRequested = false;
2690      dontWaitFor(this.expireEntries());
2691    }
2692  }
2693  /**
2694   * Update the timestamp for the given URL. This ensures the when
2695   * removing entries based on maximum entries, most recently used
2696   * is accurate or when expiring, the timestamp is up-to-date.
2697   *
2698   * @param {string} url
2699   */
2700  async updateTimestamp(url) {
2701    await this._timestampModel.setTimestamp(url, Date.now());
2702  }
2703  /**
2704   * Can be used to check if a URL has expired or not before it's used.
2705   *
2706   * This requires a look up from IndexedDB, so can be slow.
2707   *
2708   * Note: This method will not remove the cached entry, call
2709   * `expireEntries()` to remove indexedDB and Cache entries.
2710   *
2711   * @param {string} url
2712   * @return {boolean}
2713   */
2714  async isURLExpired(url) {
2715    if (!this._maxAgeSeconds) {
2716      return false;
2717    } else {
2718      const timestamp = await this._timestampModel.getTimestamp(url);
2719      const expireOlderThan = Date.now() - this._maxAgeSeconds * 1e3;
2720      return timestamp !== void 0 ? timestamp < expireOlderThan : true;
2721    }
2722  }
2723  /**
2724   * Removes the IndexedDB object store used to keep track of cache expiration
2725   * metadata.
2726   */
2727  async delete() {
2728    this._rerunRequested = false;
2729    await this._timestampModel.expireEntries(Infinity);
2730  }
2731}
2732
2733function registerQuotaErrorCallback(callback) {
2734  quotaErrorCallbacks.add(callback);
2735}
2736
2737class ExpirationPlugin {
2738  /**
2739   * @param {ExpirationPluginOptions} config
2740   * @param {number} [config.maxEntries] The maximum number of entries to cache.
2741   * Entries used the least will be removed as the maximum is reached.
2742   * @param {number} [config.maxAgeSeconds] The maximum age of an entry before
2743   * it's treated as stale and removed.
2744   * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)
2745   * that will be used when calling `delete()` on the cache.
2746   * @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to
2747   * automatic deletion if the available storage quota has been exceeded.
2748   */
2749  constructor(config = {}) {
2750    this.cachedResponseWillBeUsed = async ({ event, request, cacheName, cachedResponse }) => {
2751      if (!cachedResponse) {
2752        return null;
2753      }
2754      const isFresh = this._isResponseDateFresh(cachedResponse);
2755      const cacheExpiration = this._getCacheExpiration(cacheName);
2756      dontWaitFor(cacheExpiration.expireEntries());
2757      const updateTimestampDone = cacheExpiration.updateTimestamp(request.url);
2758      if (event) {
2759        try {
2760          event.waitUntil(updateTimestampDone);
2761        } catch (error) {
2762        }
2763      }
2764      return isFresh ? cachedResponse : null;
2765    };
2766    this.cacheDidUpdate = async ({ cacheName, request }) => {
2767      const cacheExpiration = this._getCacheExpiration(cacheName);
2768      await cacheExpiration.updateTimestamp(request.url);
2769      await cacheExpiration.expireEntries();
2770    };
2771    this._config = config;
2772    this._maxAgeSeconds = config.maxAgeSeconds;
2773    this._cacheExpirations = /* @__PURE__ */ new Map();
2774    if (config.purgeOnQuotaError) {
2775      registerQuotaErrorCallback(() => this.deleteCacheAndMetadata());
2776    }
2777  }
2778  /**
2779   * A simple helper method to return a CacheExpiration instance for a given
2780   * cache name.
2781   *
2782   * @param {string} cacheName
2783   * @return {CacheExpiration}
2784   *
2785   * @private
2786   */
2787  _getCacheExpiration(cacheName) {
2788    if (cacheName === cacheNames.getRuntimeName()) {
2789      throw new WorkboxError("expire-custom-caches-only");
2790    }
2791    let cacheExpiration = this._cacheExpirations.get(cacheName);
2792    if (!cacheExpiration) {
2793      cacheExpiration = new CacheExpiration(cacheName, this._config);
2794      this._cacheExpirations.set(cacheName, cacheExpiration);
2795    }
2796    return cacheExpiration;
2797  }
2798  /**
2799   * @param {Response} cachedResponse
2800   * @return {boolean}
2801   *
2802   * @private
2803   */
2804  _isResponseDateFresh(cachedResponse) {
2805    if (!this._maxAgeSeconds) {
2806      return true;
2807    }
2808    const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse);
2809    if (dateHeaderTimestamp === null) {
2810      return true;
2811    }
2812    const now = Date.now();
2813    return dateHeaderTimestamp >= now - this._maxAgeSeconds * 1e3;
2814  }
2815  /**
2816   * This method will extract the data header and parse it into a useful
2817   * value.
2818   *
2819   * @param {Response} cachedResponse
2820   * @return {number|null}
2821   *
2822   * @private
2823   */
2824  _getDateHeaderTimestamp(cachedResponse) {
2825    if (!cachedResponse.headers.has("date")) {
2826      return null;
2827    }
2828    const dateHeader = cachedResponse.headers.get("date");
2829    const parsedDate = new Date(dateHeader);
2830    const headerTime = parsedDate.getTime();
2831    if (isNaN(headerTime)) {
2832      return null;
2833    }
2834    return headerTime;
2835  }
2836  /**
2837   * This is a helper method that performs two operations:
2838   *
2839   * - Deletes *all* the underlying Cache instances associated with this plugin
2840   * instance, by calling caches.delete() on your behalf.
2841   * - Deletes the metadata from IndexedDB used to keep track of expiration
2842   * details for each Cache instance.
2843   *
2844   * When using cache expiration, calling this method is preferable to calling
2845   * `caches.delete()` directly, since this will ensure that the IndexedDB
2846   * metadata is also cleanly removed and open IndexedDB instances are deleted.
2847   *
2848   * Note that if you're *not* using cache expiration for a given cache, calling
2849   * `caches.delete()` and passing in the cache's name should be sufficient.
2850   * There is no Workbox-specific method needed for cleanup in that case.
2851   */
2852  async deleteCacheAndMetadata() {
2853    for (const [cacheName, cacheExpiration] of this._cacheExpirations) {
2854      await self.caches.delete(cacheName);
2855      await cacheExpiration.delete();
2856    }
2857    this._cacheExpirations = /* @__PURE__ */ new Map();
2858  }
2859}
2860
2861// @ts-ignore
2862try {
2863    self['workbox:cacheable-response:7.3.0'] && _();
2864}
2865catch (e) { }
2866
2867class CacheableResponse {
2868  /**
2869   * To construct a new CacheableResponse instance you must provide at least
2870   * one of the `config` properties.
2871   *
2872   * If both `statuses` and `headers` are specified, then both conditions must
2873   * be met for the `Response` to be considered cacheable.
2874   *
2875   * @param {Object} config
2876   * @param {Array<number>} [config.statuses] One or more status codes that a
2877   * `Response` can have and be considered cacheable.
2878   * @param {Object<string,string>} [config.headers] A mapping of header names
2879   * and expected values that a `Response` can have and be considered cacheable.
2880   * If multiple headers are provided, only one needs to be present.
2881   */
2882  constructor(config = {}) {
2883    this._statuses = config.statuses;
2884    this._headers = config.headers;
2885  }
2886  /**
2887   * Checks a response to see whether it's cacheable or not, based on this
2888   * object's configuration.
2889   *
2890   * @param {Response} response The response whose cacheability is being
2891   * checked.
2892   * @return {boolean} `true` if the `Response` is cacheable, and `false`
2893   * otherwise.
2894   */
2895  isResponseCacheable(response) {
2896    let cacheable = true;
2897    if (this._statuses) {
2898      cacheable = this._statuses.includes(response.status);
2899    }
2900    if (this._headers && cacheable) {
2901      cacheable = Object.keys(this._headers).some((headerName) => {
2902        return response.headers.get(headerName) === this._headers[headerName];
2903      });
2904    }
2905    return cacheable;
2906  }
2907}
2908
2909/*
2910  Copyright 2018 Google LLC
2911
2912  Use of this source code is governed by an MIT-style
2913  license that can be found in the LICENSE file or at
2914  https://opensource.org/licenses/MIT.
2915*/
2916/**
2917 * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it
2918 * easier to add in cacheability checks to requests made via Workbox's built-in
2919 * strategies.
2920 *
2921 * @memberof workbox-cacheable-response
2922 */
2923class CacheableResponsePlugin {
2924    /**
2925     * To construct a new CacheableResponsePlugin instance you must provide at
2926     * least one of the `config` properties.
2927     *
2928     * If both `statuses` and `headers` are specified, then both conditions must
2929     * be met for the `Response` to be considered cacheable.
2930     *
2931     * @param {Object} config
2932     * @param {Array<number>} [config.statuses] One or more status codes that a
2933     * `Response` can have and be considered cacheable.
2934     * @param {Object<string,string>} [config.headers] A mapping of header names
2935     * and expected values that a `Response` can have and be considered cacheable.
2936     * If multiple headers are provided, only one needs to be present.
2937     */
2938    constructor(config) {
2939        /**
2940         * @param {Object} options
2941         * @param {Response} options.response
2942         * @return {Response|null}
2943         * @private
2944         */
2945        this.cacheWillUpdate = async ({ response }) => {
2946            if (this._cacheableResponse.isResponseCacheable(response)) {
2947                return response;
2948            }
2949            return null;
2950        };
2951        this._cacheableResponse = new CacheableResponse(config);
2952    }
2953}
2954
2955precacheAndRoute([{"revision":"3f6ddb4405a506f37de408adf084a447","url":"sitemap-index.xml"},{"revision":"c05247762e2110b0ccc882c5f61fd677","url":"sitemap-0.xml"},{"revision":"63c2344db9f057dc27539d28a22e37f0","url":"rss.xml"},{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"d238dd45c029adab8aed4ca255af556d","url":"pwa-512x512.png"},{"revision":"ad1672d3c7c6a53f531a067df66b38f9","url":"pwa-192x192.png"},{"revision":"9b9693cecffdfeab302e29b54a94343f","url":"/"},{"revision":"8c13f40658976ea1dfb8ba37a8be0e8d","url":"favicon.svg"},{"revision":"b966553a1a0de83ff2a41b2ae9ed485f","url":"404"},{"revision":"075a3744600a2f9007d269d7d428e1a9","url":"tags"},{"revision":"d26e987a41c15190dda7359b5eb0a747","url":"tags/部署"},{"revision":"c4ce67c0caa88973a64b8afbefe71d61","url":"tags/设计模式"},{"revision":"41892ef09cdb0dfdc8863124deb0460f","url":"tags/编程"},{"revision":"c707fd68a11f831312069bf2c3a458b0","url":"tags/版本控制"},{"revision":"63b2b531bb75dd6b843a9fd375d114e2","url":"tags/样式"},{"revision":"98d0da85e1b9b591e705874c855d5f1c","url":"tags/架构"},{"revision":"dcf9d0a09bd5378912ba9e868937eced","url":"tags/最佳实践"},{"revision":"312d2838a713eff585d9cad410e0932d","url":"tags/数学"},{"revision":"92b13b01fd213e0a656d1f100b03044a","url":"tags/教程"},{"revision":"0682b4be6c9c0bf96cbf313a004d548c","url":"tags/性能"},{"revision":"e529a091f7cb2a56749fc147f73674f4","url":"tags/微前端"},{"revision":"54ba90dce245d9819792d0d31764b4a2","url":"tags/布局"},{"revision":"a689443f443a1628f7d54cd04fda6f8d","url":"tags/安全"},{"revision":"a29bf4d34b3f93fae1156e3a30b3c715","url":"tags/后端"},{"revision":"49d9edea847ca95eaaa52ad2f5665682","url":"tags/协作"},{"revision":"1a0bfd7c0c6c03e28a5ad08c284c9f29","url":"tags/前端"},{"revision":"91b550c852b404d37e55d56ef9ae821e","url":"tags/优化"},{"revision":"8691135c5c91bdd481d789bc65978b68","url":"tags/WebAssembly"},{"revision":"6e5cfc8b49d35c4a7aced7643943f1ee","url":"tags/Web"},{"revision":"31784b041e3e8c7f38c70f2d46e59861","url":"tags/Vue"},{"revision":"7b909f930556bd3aedafbcf61506ef90","url":"tags/TypeScript"},{"revision":"480803b8496c966c2ae0dae24ecc3c75","url":"tags/Test"},{"revision":"ad8018fec72ea9af1028abc3bae9678d","url":"tags/Style"},{"revision":"758d29a1b2156b1f847e42825fa3539d","url":"tags/React"},{"revision":"23a0de74d3f5b52d12fa75fa92f196fd","url":"tags/Node.js"}
2955,{"revision":"0cddb00cf0e926fe0dfdd69d8f12f3f0","url":"tags/Markdown"},{"revision":"631ee8b0c3b561cecd32536cec78ae14","url":"tags/MDX"},{"revision":"d2939766b9c08698e324db180aebb272","url":"tags/Lorem"},{"revision":"e5091456452701e82382e3166bb664ca","url":"tags/KaTeX"},{"revision":"aea17709b86af3074382e7c5f00253d5","url":"tags/JavaScript"},{"revision":"4e056ca3a705c0744d700126c38aa703","url":"tags/Ipsum"},{"revision":"02a414960075ab685a77b0953279822c","url":"tags/Hooks"},{"revision":"32104fd6c963517b5d71c51fd8eb73df","url":"tags/Guide"},{"revision":"a5a22551103c93e4143c98a444991ef2","url":"tags/GraphQL"},{"revision":"57d78c9bf1f31f2471452d8e3c8f07e0","url":"tags/Git"},{"revision":"2a66d897c6071dd1df74221153ebac2a","url":"tags/Docker"},{"revision":"3be5bee4f8e59072349aa3560b3cd9ec","url":"tags/DevOps"},{"revision":"dab608fdfef4cb66d90e71733662c138","url":"tags/CSS"},{"revision":"efd7ed089a3023154a686270057af85b","url":"tags/Astro"},{"revision":"4ea3bd55c11a10af345ca99c7c58bcd6","url":"tags/API"},{"revision":"e8dceb1cce3dbb84fc16606c64e62cdf","url":"spine_assets/plana/NP0035_spr.skel"},{"revision":"045a64c70016a8f8f5a1525fa54b8618","url":"spine_assets/plana/NP0035_spr.png"},{"revision":"573b904a86b9a188727157eacec80c65","url":"spine_assets/plana/NP0035_spr.atlas"},{"revision":"b5344b34173d2a8e1d862f943c047b80","url":"spine_assets/plana/audio/zh/plana_05.ogg"},{"revision":"70b0c0e74182fa7cd053c06dd7c421fb","url":"spine_assets/plana/audio/zh/plana_04.ogg"},{"revision":"cb8d91a4222bc9926df6ce44950f8e18","url":"spine_assets/plana/audio/zh/plana_03.ogg"},{"revision":"bed174e5313ef40ad39b5688c6991b83","url":"spine_assets/plana/audio/zh/plana_02.ogg"},{"revision":"73d495bb0c14bd63db631251d2ce6967","url":"spine_assets/plana/audio/zh/plana_01.ogg"},{"revision":"de43fb33032d3036e34f4a6881541e41","url":"spine_assets/kei/CH0335_noweapon_spr.skel"},{"revision":"228bcd8e09ac5a1e60752fa47e376ed5","url":"spine_assets/kei/CH0335_noweapon_spr.png"},{"revision":"d92ab6c1c065a33ed418bf66bb1d5b02","url":"spine_assets/kei/CH0335_noweapon_spr.atlas"},{"revision":"135373f92351ee326335e876f755ec67","url":"spine_assets/kei/audio/kei_copy.ogg"},{"revision":"9cdff0e9ce2aaae52322ef9c42912dc9","url":"spine_assets/kei/audio/kei_05.ogg"},{"revision":"0a1423b525fbee7e5459eae6d0054063","url":"spine_assets/kei/audio/kei_04.ogg"},{"revision":"4528d9a67fd8e729da7fde89d565e0af","url":"spine_assets/kei/audio/kei_03.ogg"},{"revision":"a11a531b1c3cb6b493869cc1abeeb5cd","url":"spine_assets/kei/audio/kei_02.ogg"},{"revision":"218f5834e28cb7f47c683dff6fb25897","url":"spine_assets/kei/audio/kei_01.ogg"},{"revision":"b72e3969ac4fba0de33be9ff1eedbec8","url":"spine_assets/arona/arona_spr.skel"},{"revision":"16e418937d583dcffea752249e5c89c7","url":"spine_assets/arona/arona_spr.png"},{"revision":"c8a2be841f987abab4e9bd03c33f9506","url":"spine_assets/arona/arona_spr.atlas"},{"revision":"584faa39f2275d29688eb97b72c5c6d0","url":"spine_assets/arona/audio/zh/arona_06.ogg"},{"revision":"e27550c325120121bbf93a492905bbb9","url":"spine_assets/arona/audio/zh/arona_05.ogg"},{"revision":"64f27ac13ee9aa99fb098d9d2035e9ef","url":"spine_assets/arona/audio/zh/arona_04.ogg"},{"revision":"1d81761cf7f6ee294c401381d3d9c1e3","url":"spine_assets/arona/audio/zh/arona_03.ogg"},{"revision":"b97b0b783803878ba8a3ef17690bd8b7","url":"spine_assets/arona/audio/zh/arona_02.ogg"},{"revision":"780c1e87c4fa97934b6ff6faf8f37cc8","url":"spine_assets/arona/audio/zh/arona_01.ogg"},{"revision":"57052e7ced3f82166eeffb947fb9dff9","url":"spine_assets/aris/aris_noweapon_spr.skel"},{"revision":"54201d9fd6ab2f03bc56e271313d9cc0","url":"spine_assets/aris/aris_noweapon_spr.png"},{"revision":"022de286f29063e008167a03e31d1ca5","url":"spine_assets/aris/aris_noweapon_spr.atlas"},{"revision":"9c7614bf5d852838621733cbc812920b","url":"spine_assets/aris/audio/aris_copy.mp3"},{"revision":"860c02662838ae41d48b86647cb2d634","url":"spine_assets/aris/audio/aris_05.ogg"},{"revision":"88af00da67efe8c333eb115acdcf2c28","url":"spine_assets/aris/audio/aris_04.ogg"},{"revision":"f440dccfb385317333d7ba8df19c7a08","url":"spine_assets/aris/audio/aris_03.ogg"},{"revision":"6bbd0b2bf4ed371aa73c41c7e73736a1","url":"spine_assets/aris/audio/aris_02.ogg"},{"revision":"89059fc8319212557577217eb74e8462","url":"spine_assets/aris/audio/aris_01.ogg"},{"revision":"f12d7bc7a269aa78d66104f863ea6e22","url":"project"},{"revision":"6af9cf960e2e2581832564d165db883c","url":"offline"},{"revision":"e0404f6d3d3ef9f4f69b04cd1256700b","url":"friends"},{"revision":"1265e63133cb9ca51dcb5c3d8afe1f79","url":"donate/donate.png"},{"revision":"de556cbaad572a755d7442b914bf510d","url":"blog/using-mdx"},{"revision":"260670ede4a64d3c40158b2654dac852","url":"blog/third-post"},{"revision":"cc650441a2102769c26d6348e1d1ba4a","url":"blog/test-post-15"},{"revision":"b22b2718160d43817c63479d81c935d5","url":"blog/test-post-14"},{"revision":"dde9ef6b3683b8b2664661ddbcb24000","url":"blog/test-post-13"},{"revision":"111288277b08972edd771fb756eee227","url":"blog/test-post-12"},{"revision":"cda67b7e2d27696ec30da479b6c837d5","url":"blog/test-post-11"},{"revision":"8dc32dcf81ac0e514271e76b1cdce427","url":"blog/test-post-10"},{"revision":"e2b94cfbf94b25d5f559f70c6b1fac52","url":"blog/test-post-09"},{"revision":"90e90a32e1dabe81915e953d82fe8b3d","url":"blog/test-post-08"},{"revision":"930aa87c5a89a3fbf2c36a0fe77f51ac","url":"blog/test-post-07"},{"revision":"6590ec6cbe455745be34233f5ed25be0","url":"blog/test-post-06"},{"revision":"9189c4c3a70ab1c284a5bb3a4f46143e","url":"blog/test-post-05"}
2955,{"revision":"d2a6930788a57c4f56ecedb84867da6b","url":"blog/test-post-04"},{"revision":"831f76d588462cba4966df559eca3cb0","url":"blog/test-post-03"},{"revision":"445cd12e2d2ca64d57c8752f7bcb6723","url":"blog/test-post-02"},{"revision":"25dccd657871e7bd681097b404d9b396","url":"blog/test-post-01"},{"revision":"fe0ec4ac66ceb1cac79ee7abc16031bd","url":"blog/second-post"},{"revision":"11915c4a86f5196b2189937237bc976a","url":"blog/markdown-style-guide"},{"revision":"e158690b8ae35d148582cf6d30ad78fc","url":"blog/katex-math-guide"},{"revision":"54e21435b1adb1ce694d36c1be9417c1","url":"blog/first-post"},{"revision":"7986802e84c372648a0b2c0ccd10d772","url":"bangumi"},{"revision":"9341f757e58a9a37600dbc32bbc0f028","url":"about"},{"revision":null,"url":"_astro/webworkerAll.CQrcKCR1.js"},{"revision":null,"url":"_astro/toTop.DI_oygYQ.svg"},{"revision":null,"url":"_astro/runtime-dom.esm-bundler.BkDFwomG.js"},{"revision":null,"url":"_astro/runtime-core.esm-bundler.z36Am-N8.js"},{"revision":null,"url":"_astro/preload-helper.CVfkMyKi.js"},{"revision":null,"url":"_astro/photoswipe.esm.BXDdABy_.js"},{"revision":null,"url":"_astro/page.D6zt-6VW.js"},{"revision":null,"url":"_astro/navLogo.DKp2Tzp-_t9aIe.svg"},{"revision":null,"url":"_astro/navLogo.DKp2Tzp-.svg"},{"revision":null,"url":"_astro/musicService.l9si1emE.js"},{"revision":null,"url":"_astro/index.CsdR7HZi.js"},{"revision":null,"url":"_astro/footLogo.D9ml5nCJ_CuOqe.webp"},{"revision":null,"url":"_astro/ff12251e855df71bf279d4515dad38ec.B-zWNHtg.woff2"},{"revision":null,"url":"_astro/fd87ef562fdc5482b83f0fa36471f907.eA17sHVe.woff2"},{"revision":null,"url":"_astro/fcb0cd2a64c0ab97f8126a35b371408d.DpXQCDz5.woff2"},{"revision":null,"url":"_astro/fb24b9e9fdae4c9f016986fc58858fe1.DQmW9uTs.woff2"},{"revision":null,"url":"_astro/fad53f716f9c6aa59576fb49db534aec.Jp4YL7cj.woff2"},{"revision":null,"url":"_astro/fa3c854f415968cc787150e588af56ef.Dc8MSxRk.woff2"},{"revision":null,"url":"_astro/fa3959305d542834978bdc6e93e6f70b.Cn5SPx9h.woff2"},{"revision":null,"url":"_astro/f9325783447077fb5ed8c124bea5045b._kkrlcuP.woff2"},{"revision":null,"url":"_astro/f8d7b5b9a468b0fc0dad60a256d4df95.CVbmofh5.woff2"},{"revision":null,"url":"_astro/f88836afeaec700c8482aade50f79f94.mhgcRjb3.woff2"},{"revision":null,"url":"_astro/f844f48480bedad6f5937e97f4541ce3.C-0-3mbB.woff2"},{"revision":null,"url":"_astro/f6a5b130905cfc33ad47e30f3afb432e.SA5d4DuG.woff2"},{"revision":null,"url":"_astro/f65c77dff61c3e49de327bb71bfc6a08.BTVFu2r1.woff2"},{"revision":null,"url":"_astro/f65819e9eb6e3816c96dc5a1d4b344c2.1JZ7F9km.woff2"},{"revision":null,"url":"_astro/f563c7d10ff3103c857077669bb51466.BRpx3nvb.woff2"},{"revision":null,"url":"_astro/f42a59aab9dae269f1b15671990462ff.CqTJfK86.woff2"},{"revision":null,"url":"_astro/f11250628ce107bff95eeaca8fdba77b.BCV8In0F.woff2"},{"revision":null,"url":"_astro/f0e23961c13272b9dbed35416158abd3.BybEEenW.woff2"},{"revision":null,"url":"_astro/f0ca746af58679df44d7811117f60d78.CemmgVOd.woff2"},{"revision":null,"url":"_astro/f0ab2aabde883947ad62ee036317a92e.Ca6mkPGl.woff2"},{"revision":null,"url":"_astro/ef46c803c347808452c6277389c6c410.Wi8af_AM.woff2"},{"revision":null,"url":"_astro/ee6ee404e89ca278979fd1ed0c7a458a.B2dm3REe.woff2"},{"revision":null,"url":"_astro/edb4b6bf99bb860536485b2eb6ffac7b.wQkYllQZ.woff2"},{"revision":null,"url":"_astro/ecb94b20aebb5b9c81bba793861084e5.BSco4Ybu.woff2"},{"revision":null,"url":"_astro/ec.r0ya5.css"},{"revision":null,"url":"_astro/ec.0vx5m.js"},{"revision":null,"url":"_astro/ebc1e58598229499aad1d807746a1986.CAgVSL77.woff2"},{"revision":null,"url":"_astro/eb150ee725c154742ab86fd2f4596f01.BStBQ2ua.woff2"},{"revision":null,"url":"_astro/eab12f54efd5bf564cdec31202af2439.BDurIvle.woff2"},{"revision":null,"url":"_astro/e95c273f1d9249e7974b6a22fa994e83.CfyF3etY.woff2"},{"revision":null,"url":"_astro/e8d94c876f0238b1017cc3b5b145232f.Dan62l-l.woff2"},{"revision":null,"url":"_astro/e8d072a10ec0fd205c8ac5ef9c0e1132.iohlxCH0.woff2"},{"revision":null,"url":"_astro/e8318075f6fb9cd25bfd6017fb05ea10.DrPWUX2j.woff2"},{"revision":null,"url":"_astro/e79bfb720d70d6d4c365277f2ca8ceee.BtIrG5wN.woff2"},{"revision":null,"url":"_astro/e711770afef84b38ec7e3623b9b893bc.HpIII6OG.woff2"},{"revision":null,"url":"_astro/e664b418b9be4d1560668c2ee4ddcf23.Dve_5JcY.woff2"},{"revision":null,"url":"_astro/e60748baabda7250fb381e18305f79cf.DfI6xKaW.woff2"},{"revision":null,"url":"_astro/e559bde330882ecc8b8dabd734a19b77.BTMKaaEv.woff2"},{"revision":null,"url":"_astro/e556f1852ad59c6c83a8e030801e5bb8.Bm9xjiZI.woff2"},{"revision":null,"url":"_astro/e51ca539aa6937ee2185584de12c1e82.DVTkLEAV.woff2"}
2955,{"revision":null,"url":"_astro/e26ad4c05c69b701b4b7beb7502087a3.D4wwEM9e.woff2"},{"revision":null,"url":"_astro/e0d9c587747ce19356d22c8ed5aec5c4.bmyEzyfJ.woff2"},{"revision":null,"url":"_astro/e0d67bdd35e3596d5e6411cac5ed3fe4.CPKNEjza.woff2"},{"revision":null,"url":"_astro/dfb99b42b38424a4f88da968d3e1c6fb.CBFCkdsH.woff2"},{"revision":null,"url":"_astro/df5ad27029623cff4859ad3e4a306862.1PQ1L-l8.woff2"},{"revision":null,"url":"_astro/deccfd02d6f82e5ab1f602cc1412c20c.DzQqK0MR.woff2"},{"revision":null,"url":"_astro/ddfc8c9c903dc392df82de9968c9a2c4.CtWX47M9.woff2"},{"revision":null,"url":"_astro/dd69e5dae6afd7aed50b5d3296cdd8b0.CA6393Et.woff2"},{"revision":null,"url":"_astro/dd4cc2f18408a5c6f3a0ed73dd37786c.BiNagD0b.woff2"},{"revision":null,"url":"_astro/dd3d3dffbb94202c7e4ea636c6f9d99a.CnptsRfB.woff2"},{"revision":null,"url":"_astro/daa5316eaba34d3382df376eabc373ee.DBFwQaN8.woff2"},{"revision":null,"url":"_astro/da5ed59e47b5dd162c1ae4020828cdb1.BN-acKxA.woff2"},{"revision":null,"url":"_astro/d91b2d8f2636b9ee348ab63fc5a264ad.B9Xv8LPf.woff2"},{"revision":null,"url":"_astro/d89725022f18af677f9cd6f20b9b165d.CY1ytNa0.woff2"},{"revision":null,"url":"_astro/d86bca4ba3064aff38f2786638588c32.gsc-JcPH.woff2"}
2955,{"revision":null,"url":"_astro/d8357a54f4f7d3272e7e147bb19d1e8c.CTlnfN6N.woff2"},{"revision":null,"url":"_astro/d63ec43ef34e9f75aa777475932a304a.BBoYHPB3.woff2"},{"revision":null,"url":"_astro/d5c6c76766f25b15988618efa51285cb.DOL-1aLe.woff2"},{"revision":null,"url":"_astro/d5ad898a826b323d257b8936bf6653ef.MTvJYni0.woff2"},{"revision":null,"url":"_astro/d56e874603219870d94198422fe405f4.S8CwERwo.woff2"},{"revision":null,"url":"_astro/d55850cb2128fc84fd4396f8e0db3805.Cgy5wrqV.woff2"},{"revision":null,"url":"_astro/d4af19a1aa6855f87516dfe51fff3ab7.7HIEd6Su.woff2"},{"revision":null,"url":"_astro/d497396acc5f68edbb4c10cd34fa6f17.CaM1C3z1.woff2"},{"revision":null,"url":"_astro/d4449af9ccd98fed27bf9b2021898222.Bw8Z-VhU.woff2"},{"revision":null,"url":"_astro/d41e81c12cf01b523fb09a62f1693921.D6cvaUot.woff2"},{"revision":null,"url":"_astro/d4138b727d70efd386255a67414d06af.sx-zhdie.woff2"},{"revision":null,"url":"_astro/d394d21164a0edd4a0e9b2632511fa24.B4AvrZD0.woff2"},{"revision":null,"url":"_astro/d37c65540ddd23290afe73628f893452.D_YRlvtx.woff2"},{"revision":null,"url":"_astro/d322563755e807ee04f1185467e65908.DwEa01uO.woff2"},{"revision":null,"url":"_astro/d28de52d6342d2ea1fe79ad88d1e7ad5.CQLqLXfk.woff2"},{"revision":null,"url":"_astro/d244ac0134c51330d257f9f2276bc3e3.DDQbDT5P.woff2"},{"revision":null,"url":"_astro/d0e017c3f4b6d9b64394caef0c6f9096.CL3F-XTV.woff2"},{"revision":null,"url":"_astro/d0af9a5f02191ef1c6d5982f61bf05ba.6k0JTVWD.woff2"},{"revision":null,"url":"_astro/d08c91beb40adf52ed2f79fd91fbc379.CED9ht_R.woff2"},{"revision":null,"url":"_astro/client.CrwFu2hE.js"},{"revision":null,"url":"_astro/cfec4e3bf632f5d9441e9cc80ec3cc7b.SIxj4pqi.woff2"},{"revision":null,"url":"_astro/cef32627bd7e3abd2392fe1287a36cc6.B9Q9r9Sh.woff2"},{"revision":null,"url":"_astro/ce3701e71fb3a3be451badf661b3cc10.CKXpgpm8.woff2"},{"revision":null,"url":"_astro/cc848efcdc3c77262b0977445a0ed8f7.DMW-7hYY.woff2"},{"revision":null,"url":"_astro/cba9c42b58ae234b681ac2c8e0533e65.Exzr4e52.woff2"},{"revision":null,"url":"_astro/c9a60417da0818ac72f62bdb04925cd4.CPuqBwY6.woff2"},{"revision":null,"url":"_astro/c8b50292ca4e40aa1fa9812999b34cf9.D63lWpg-.woff2"},{"revision":null,"url":"_astro/c88e3dbea4d5eb73c50277f29f6f8d10.6Zg1kDEk.woff2"},{"revision":null,"url":"_astro/c865b08298af8395f5473667f37b4aeb.DQPMnnCd.woff2"},{"revision":null,"url":"_astro/c761f7cd4b49081b8d7104fd38151313.B3UoU3fU.woff2"},{"revision":null,"url":"_astro/c7513312111bd5757a7a6cc7f7a6fe55.Di2ZpOkO.woff2"},{"revision":null,"url":"_astro/c736127dbc967a4842ae54091c788848.C_9nGw5i.woff2"},{"revision":null,"url":"_astro/c56ca2cdc6e4c8ad69a9820ce64e664d.B7nIzRz6.woff2"},{"revision":null,"url":"_astro/c52d1743d24ad460b6a0714a1fb09407.S_ijwmYo.woff2"},{"revision":null,"url":"_astro/c4f591f757854eff8b2ce164316d2c27.CpQDlY1y.woff2"},{"revision":null,"url":"_astro/c409e7fb74fa7469714754eb1ed407f2.DKEpZ7DI.woff2"},{"revision":null,"url":"_astro/c31f637e1ded8cf6e5daf137813f7e1b.CAEzit8_.woff2"},{"revision":null,"url":"_astro/browserAll.C24f_xP3.js"},{"revision":null,"url":"_astro/blog-placeholder-about.BtEdEmGp_Z2srqQK.webp"},{"revision":null,"url":"_astro/blog-placeholder-about.BtEdEmGp.jpg"},{"revision":null,"url":"_astro/blog-placeholder-5.CB3Xi-gp_j9V0O.webp"},{"revision":null,"url":"_astro/blog-placeholder-5.CB3Xi-gp.jpg"},{"revision":null,"url":"_astro/blog-placeholder-4.gLBdjEDe_Z15Ss3d.webp"},{"revision":null,"url":"_astro/blog-placeholder-4.gLBdjEDe.jpg"},{"revision":null,"url":"_astro/blog-placeholder-3.ijrf8Ohr_Z1373cG.webp"},{"revision":null,"url":"_astro/blog-placeholder-3.ijrf8Ohr.jpg"},{"revision":null,"url":"_astro/blog-placeholder-2.1WQRLJGH_15TD1q.webp"},{"revision":null,"url":"_astro/blog-placeholder-2.1WQRLJGH.jpg"},{"revision":null,"url":"_astro/blog-placeholder-1.Bx0Zcyzv_Z1v5W1C.webp"},{"revision":null,"url":"_astro/blog-placeholder-1.Bx0Zcyzv.jpg"},{"revision":null,"url":"_astro/bf6230a42422aceec39b3811c4c75756.BMs5o7V9.woff2"},{"revision":null,"url":"_astro/be917719d42ca31eff7134f3b719e491.BwABGLsm.woff2"},{"revision":null,"url":"_astro/be756c71ee61176d435b30cfb607daca.BwuwGb_4.woff2"},{"revision":null,"url":"_astro/be70ccadd88a80b876ae0d524e29d923.dFPJJROn.woff2"},{"revision":null,"url":"_astro/bdecd81e8cb1843d6785d9b0810fea6f.jCAn2Db_.woff2"},{"revision":null,"url":"_astro/bdac513db59a662f04893281212efc21.DHrsj0fB.woff2"},{"revision":null,"url":"_astro/bc7c333983f6a98f64947186e7462f28.DXFjIK13.woff2"},{"revision":null,"url":"_astro/bc4e1caf225389a3a4dfc6add134354a.DIABC9G9.woff2"},{"revision":null,"url":"_astro/bc2b0ed7b41aff7a56580e4fd141ffec.CKD96T1N.woff2"},{"revision":null,"url":"_astro/bbda0e671bc631b0f036f344fe62029e.Bq74HGf1.woff2"},{"revision":null,"url":"_astro/bbbe025b78361933dd8a499a1ada6d2b.EUMqSC7J.woff2"},{"revision":null,"url":"_astro/bbafb8ca6b798ae03a68227f82dcf648.CzVvAghM.woff2"},{"revision":null,"url":"_astro/banner_dark.DYi3kWFc.webp"},{"revision":null,"url":"_astro/banner.H_N5Rg0p.webp"},{"revision":null,"url":"_astro/background_dark.AFOWX2L5.svg"},{"revision":null,"url":"_astro/background.BBwJmske.svg"},{"revision":null,"url":"_astro/bab64f63d2d5ec98fb42a241b6acc30b.BSyrVr1o.woff2"},{"revision":null,"url":"_astro/ba1fadf246a745a30e7b337c508d3edd.BPqGLiFj.woff2"},{"revision":null,"url":"_astro/b9a013be5c5aeb625bd58991626b6916.8QODTq21.woff2"},{"revision":null,"url":"_astro/b96d65a2ff7f6f10e1f6fe10f3de66a5.qNjVyTyD.woff2"},{"revision":null,"url":"_astro/b883d719baaf1d6e927de9c263f1d300.BIV7TJLC.woff2"},{"revision":null,"url":"_astro/b843dac4a47827c9b1a350eaef890609.BbrqTvWJ.woff2"},{"revision":null,"url":"_astro/b7d2448d1850f355bcaaf43723e27bce.CUXP5dFQ.woff2"},{"revision":null,"url":"_astro/b73ee08ca7b322934953a91d680a7228.6u4lmf7Y.woff2"},{"revision":null,"url":"_astro/b6b3df5870cc24dbc31a96b27f642674.D819KYAO.woff2"},{"revision":null,"url":"_astro/b5431d1aaf4c8c073a5cb99f8c137c71.BDxl3GG3.woff2"},{"revision":null,"url":"_astro/b3f267f4155ebd4df445cf2002146506.DRTubLyr.woff2"},{"revision":null,"url":"_astro/b2b41b5ef7d7f11c75da5b58d0266510.Dukge0O0.woff2"},{"revision":null,"url":"_astro/b249ae133c24159ec268e6903948f3ee.CioEFe9x.woff2"},{"revision":null,"url":"_astro/b20c4a6706e0f610695d9221eba4d57e.Cbdfi1Db.woff2"},{"revision":null,"url":"_astro/b124767dfdf43b236ae1ae3a5e1cc287.Bs7b8Yhy.woff2"},{"revision":null,"url":"_astro/b10a6803d0c3fc732ef6804d04781054.lZnH0BGZ.woff2"},{"revision":null,"url":"_astro/b0b14b205d69b49057e5f8fda47571e5.DKjOM9-x.woff2"},{"revision":null,"url":"_astro/b0240d566d3d07a8f349211305f494af.Du6_hzay.woff2"},{"revision":null,"url":"_astro/avatar.BdKdfcnM_1Prj8X.webp"},{"revision":null,"url":"_astro/acdc6809717a1eb16b30eb40c8a2db4c.CVuS2BGf.woff2"},{"revision":null,"url":"_astro/acbff24f5dbae085d3abb24b09d5f852.BzyI50EI.woff2"},{"revision":null,"url":"_astro/acaec8d522cbb4fc8d004406ab61680a.Dcj11mlH.woff2"},{"revision":null,"url":"_astro/ac6a03c30289930eeb15581449862ae3.2EMkwnwL.woff2"},{"revision":null,"url":"_astro/ac48a61d8b2a98264b77f638ad6e9575.C34VuwIg.woff2"},{"revision":null,"url":"_astro/abdc2a1b51428ba2cc333e9261460c26.Bqohx2HC.woff2"},{"revision":null,"url":"_astro/ab858dff1dbf586ccacc4c30e9281d6e.DeKnD3CQ.woff2"},{"revision":null,"url":"_astro/a91c2becc29a2b894ecb22ffe863e84c.lNMBmmk2.woff2"},{"revision":null,"url":"_astro/a8947f6542b9ea94d35f7909086b8683.CRgQNEiF.woff2"},{"revision":null,"url":"_astro/a74b3d4b081bf6119d8c34439ff665c3.B08NJUnd.woff2"},{"revision":null,"url":"_astro/a746dc16fc3f756da7994203b24fd9c6.BJH8RFvc.woff2"},{"revision":null,"url":"_astro/a69577262f43d322f3f56895209f7fc6.gDO3VCUy.woff2"}
2955,{"revision":null,"url":"_astro/a5ec1e4f3189665a3831ad236441ae43.CvOsMiWl.woff2"},{"revision":null,"url":"_astro/a4bf789e77b35512c92ef6b8ebdc1c2f.DOj7Uclv.woff2"},{"revision":null,"url":"_astro/a41ed0ad32a6262e9ed4eebfe5aa3c91.uUcm__mb.woff2"},{"revision":null,"url":"_astro/a3c8e3e722624ccfd9c6f211e7156705.DpiaxIkI.woff2"},{"revision":null,"url":"_astro/a1a392e7dce5c17794ea0f72d507ac87.DQt9dRok.woff2"},{"revision":null,"url":"_astro/a1857674556f27a164c062e35d5d6a31.BT7LJzBk.woff2"},{"revision":null,"url":"_astro/a0305a767f29e73662f2abc59551a07b.BuxjLP3u.woff2"},{"revision":null,"url":"_astro/a019ca4c217b61e8cafdbf95a50f3e3f.D5feljuJ.woff2"},{"revision":null,"url":"_astro/_plugin-vue_export-helper.DlAUqK2U.js"},{"revision":null,"url":"_astro/_commonjsHelpers.Cpj98o6Y.js"},{"revision":null,"url":"_astro/WelcomeBoxController.DHZ7_0PH.js"},{"revision":null,"url":"_astro/WebGPURenderer.B8NSNx_K.js"},{"revision":null,"url":"_astro/WebGLRenderer.BQ6YDYJg.js"},{"revision":null,"url":"_astro/WalineComment.astro_astro_type_script_index_0_lang.CwXO04sd.js"},{"revision":null,"url":"_astro/SpinePlayer.BTZ4ixmH.js"},{"revision":null,"url":"_astro/SpinePlayer.BHeVZB3M.js"},{"revision":null,"url":"_astro/RenderTargetSystem.bDRyAEyo.js"},{"revision":null,"url":"_astro/PhotoSwipe.astro_astro_type_script_index_0_lang.rGeJF7Tz.js"},{"revision":null,"url":"_astro/PageTransition.astro_astro_type_script_index_0_lang.D8bAg6kx.js"},{"revision":null,"url":"_astro/NotFound.BbqB1acd.webp"},{"revision":null,"url":"_astro/MusicControl.astro_astro_type_script_index_0_lang.yylIi8F0.js"},{"revision":null,"url":"_astro/KaTeX_Typewriter-Regular.D3Ib7_Hf.ttf"},{"revision":null,"url":"_astro/KaTeX_Typewriter-Regular.CO6r4hn1.woff2"},{"revision":null,"url":"_astro/KaTeX_Typewriter-Regular.C0xS9mPB.woff"},{"revision":null,"url":"_astro/KaTeX_Size4-Regular.Dl5lxZxV.woff2"},{"revision":null,"url":"_astro/KaTeX_Size4-Regular.DWFBv043.ttf"},{"revision":null,"url":"_astro/KaTeX_Size4-Regular.BF-4gkZK.woff"},{"revision":null,"url":"_astro/KaTeX_Size3-Regular.DgpXs0kz.ttf"},{"revision":null,"url":"_astro/KaTeX_Size3-Regular.CTq5MqoE.woff"},{"revision":null,"url":"_astro/KaTeX_Size2-Regular.oD1tc_U0.woff"},{"revision":null,"url":"_astro/KaTeX_Size2-Regular.Dy4dx90m.woff2"},{"revision":null,"url":"_astro/KaTeX_Size2-Regular.B7gKUWhC.ttf"},{"revision":null,"url":"_astro/KaTeX_Size1-Regular.mCD8mA8B.woff2"},{"revision":null,"url":"_astro/KaTeX_Size1-Regular.Dbsnue_I.ttf"},{"revision":null,"url":"_astro/KaTeX_Size1-Regular.C195tn64.woff"},{"revision":null,"url":"_astro/KaTeX_Script-Regular.D5yQViql.woff"},{"revision":null,"url":"_astro/KaTeX_Script-Regular.D3wIWfF6.woff2"},{"revision":null,"url":"_astro/KaTeX_Script-Regular.C5JkGWo-.ttf"},{"revision":null,"url":"_astro/KaTeX_SansSerif-Regular.DDBCnlJ7.woff2"},{"revision":null,"url":"_astro/KaTeX_SansSerif-Regular.CS6fqUqJ.woff"},{"revision":null,"url":"_astro/KaTeX_SansSerif-Regular.BNo7hRIc.ttf"},{"revision":null,"url":"_astro/KaTeX_SansSerif-Italic.YYjJ1zSn.ttf"},{"revision":null,"url":"_astro/KaTeX_SansSerif-Italic.DN2j7dab.woff"},{"revision":null,"url":"_astro/KaTeX_SansSerif-Italic.C3H0VqGB.woff2"},{"revision":null,"url":"_astro/KaTeX_SansSerif-Bold.DbIhKOiC.woff"},{"revision":null,"url":"_astro/KaTeX_SansSerif-Bold.D1sUS0GD.woff2"},{"revision":null,"url":"_astro/KaTeX_SansSerif-Bold.CFMepnvq.ttf"},{"revision":null,"url":"_astro/KaTeX_Math-Italic.t53AETM-.woff2"},{"revision":null,"url":"_astro/KaTeX_Math-Italic.flOr_0UB.ttf"},{"revision":null,"url":"_astro/KaTeX_Math-Italic.DA0__PXp.woff"},{"revision":null,"url":"_astro/KaTeX_Math-BoldItalic.iY-2wyZ7.woff"},{"revision":null,"url":"_astro/KaTeX_Math-BoldItalic.CZnvNsCZ.woff2"},{"revision":null,"url":"_astro/KaTeX_Math-BoldItalic.B3XSjfu4.ttf"},{"revision":null,"url":"_astro/KaTeX_Main-Regular.ypZvNtVU.ttf"},{"revision":null,"url":"_astro/KaTeX_Main-Regular.Dr94JaBh.woff"},{"revision":null,"url":"_astro/KaTeX_Main-Regular.B22Nviop.woff2"},{"revision":null,"url":"_astro/KaTeX_Main-Italic.NWA7e6Wa.woff2"},{"revision":null,"url":"_astro/KaTeX_Main-Italic.BMLOBm91.woff"},{"revision":null,"url":"_astro/KaTeX_Main-Italic.3WenGoN9.ttf"}
2955,{"revision":null,"url":"_astro/KaTeX_Main-BoldItalic.SpSLRI95.woff"},{"revision":null,"url":"_astro/KaTeX_Main-BoldItalic.DzxPMmG6.ttf"},{"revision":null,"url":"_astro/KaTeX_Main-BoldItalic.DxDJ3AOS.woff2"},{"revision":null,"url":"_astro/KaTeX_Main-Bold.waoOVXN0.ttf"},{"revision":null,"url":"_astro/KaTeX_Main-Bold.Jm3AIy58.woff"},{"revision":null,"url":"_astro/KaTeX_Main-Bold.Cx986IdX.woff2"},{"revision":null,"url":"_astro/KaTeX_Fraktur-Regular.Dxdc4cR9.woff"},{"revision":null,"url":"_astro/KaTeX_Fraktur-Regular.CTYiF6lA.woff2"},{"revision":null,"url":"_astro/KaTeX_Fraktur-Regular.CB_wures.ttf"},{"revision":null,"url":"_astro/KaTeX_Fraktur-Bold.CL6g_b3V.woff2"},{"revision":null,"url":"_astro/KaTeX_Fraktur-Bold.BsDP51OF.woff"},{"revision":null,"url":"_astro/KaTeX_Fraktur-Bold.BdnERNNW.ttf"},{"revision":null,"url":"_astro/KaTeX_Caligraphic-Regular.wX97UBjC.ttf"},{"revision":null,"url":"_astro/KaTeX_Caligraphic-Regular.Di6jR-x-.woff2"},{"revision":null,"url":"_astro/KaTeX_Caligraphic-Regular.CTRA-rTL.woff"},{"revision":null,"url":"_astro/KaTeX_Caligraphic-Bold.Dq_IR9rO.woff2"},{"revision":null,"url":"_astro/KaTeX_Caligraphic-Bold.BEiXGLvX.woff"},{"revision":null,"url":"_astro/KaTeX_Caligraphic-Bold.ATXxdsX0.ttf"},{"revision":null,"url":"_astro/KaTeX_AMS-Regular.DRggAlZN.ttf"},{"revision":null,"url":"_astro/KaTeX_AMS-Regular.DMm9YOAa.woff"},{"revision":null,"url":"_astro/KaTeX_AMS-Regular.BQhdFMY1.woff2"},{"revision":null,"url":"_astro/JetBrainsMono-Regular.BQaDgvhP.woff2"},{"revision":null,"url":"_astro/JetBrainsMono-Italic.CFFf43z2.woff2"},{"revision":null,"url":"_astro/Filter.D4bURMG6.js"},{"revision":null,"url":"_astro/ClientRouter.astro_astro_type_script_index_0_lang.D3CcSXtg.js"},{"revision":null,"url":"_astro/CanvasRenderer.B9uB1Edj.js"},{"revision":null,"url":"_astro/CanvasPool.DxMD5ozV.js"},{"revision":null,"url":"_astro/BufferResource.CIFSdiOa.js"},{"revision":null,"url":"_astro/BitmapFont.G2RZkRQk.js"},{"revision":null,"url":"_astro/Banner.astro_astro_type_script_index_0_lang.DPDBQxub.js"},{"revision":null,"url":"_astro/9f426dfa68b6b86a3b24918cd61ba5f8.C0cilLQj.woff2"},{"revision":null,"url":"_astro/9e8b2d4048301fc4de76a8cdf37a24f8.Dk8mtBhb.woff2"},{"revision":null,"url":"_astro/9e7560d0c89c56055d6587e772be8d13.CUJYFFFy.woff2"},{"revision":null,"url":"_astro/9db92973ab842839c8c66b948b9ac556.Dp0rpGCg.woff2"},{"revision":null,"url":"_astro/9d12af886db1f38cf45613dc55951a84.BFVh_8eD.woff2"},{"revision":null,"url":"_astro/9cc37dfae8f1b2fcd2cf9790cb9c11bc.Kic_lj0K.woff2"},{"revision":null,"url":"_astro/9c10b4c648bc944285db8e9be8c5e80f.K4AcwB0H.woff2"},{"revision":null,"url":"_astro/9afa37f9d9f6b7fb2d696723ee42677a.DlLOaanD.woff2"},{"revision":null,"url":"_astro/9980fd4d4c9601e55ead1dc2cb0bbccc.BOTChj9u.woff2"},{"revision":null,"url":"_astro/98de76e32608d9ce0953e16e359e144d.17cZlNdL.woff2"},{"revision":null,"url":"_astro/987198a47bb3d73caf710b83a7bc95e0.DhX1OdOP.woff2"},{"revision":null,"url":"_astro/985e7ced486b92724d567ff9cec240e0.Bk4ciX-3.woff2"},{"revision":null,"url":"_astro/98503b1ed30513381f5d29c34effe577.9t3URzeG.woff2"},{"revision":null,"url":"_astro/97fc1df31ac590764bdc1d35f32bbc39.rQnuFjFb.woff2"},{"revision":null,"url":"_astro/979ac97c1d7b2efd73bef1fb0f8f7a64.Cg7hYL3o.woff2"},{"revision":null,"url":"_astro/9659a3f5bf35f901a1b2f9def1109bae.ClPmWOLu.woff2"},{"revision":null,"url":"_astro/95be0ad9c37dee07a08ff8fad5589697.BWZ67Pqk.woff2"},{"revision":null,"url":"_astro/954d43246b1ec91ecdc34df561b1889b.Daf3Rj-R.woff2"},{"revision":null,"url":"_astro/950c4fdb64891fcc0c47730236b9e7a4.vYLLpEmw.woff2"},{"revision":null,"url":"_astro/93dad0ee659730b176d79ddde2641e16.TvFdhMXw.woff2"},{"revision":null,"url":"_astro/93d6c1263ff8ba18377bc5ea624e08aa.BhIASOL_.woff2"},{"revision":null,"url":"_astro/926fe3470d3d721c5197eaef53c4c9cf.BHgoVFsh.woff2"},{"revision":null,"url":"_astro/91579fb71f97d487fb9790508ffd9d0c.gjjTYrRt.woff2"},{"revision":null,"url":"_astro/90b3cea36b6d0cd394c0f5cf1c171d7c.B_WU4OhY.woff2"},{"revision":null,"url":"_astro/90871848d354e4924248b92b0235389f.ucm1fAHA.woff2"},{"revision":null,"url":"_astro/9072534829ceedddcabab2a121683afa.Bft69dUL.woff2"},{"revision":null,"url":"_astro/903044fcc7aa39c7c6d9ec0472735e65.CVOqGt7M.woff2"},{"revision":null,"url":"_astro/8fd2770cc627eda56823ee1512970ed9.BkgxtcF3.woff2"},{"revision":null,"url":"_astro/8fb0d45b1286017cc4e04985d0a294d0.C0n38kAB.woff2"},{"revision":null,"url":"_astro/8f6b433817601eb2ed876d48696f7dfc.DqkThtra.woff2"},{"revision":null,"url":"_astro/8ecff440a70e97f55265040ae381c0b1.BTPL83Cm.woff2"},{"revision":null,"url":"_astro/8ecb74fb476a2e4c57d461181771dde1.OTVJR2qa.woff2"},{"revision":null,"url":"_astro/8e688bd424db073d51a206b2638f3bde.BpXvMZwr.woff2"},{"revision":null,"url":"_astro/8e5963f4af3922002144ab88fe137ac6.CZqTuwI3.woff2"},{"revision":null,"url":"_astro/8e298129bb11765ed5dec3e164bfa15a.BloofOp5.woff2"},{"revision":null,"url":"_astro/8d0c089e243235d7ff20952e29a47932.DzWCfXi8.woff2"},{"revision":null,"url":"_astro/8c09f2a621db40775b42aee6ef3c9ee8.BdGyLl5u.woff2"},{"revision":null,"url":"_astro/8ba45d7d00203bc91bc37acdd490d8a9.75woyrZ0.woff2"},{"revision":null,"url":"_astro/8ba21d555b89c7aa99da88282e952363.B873nFp0.woff2"},{"revision":null,"url":"_astro/8b57899f6995071bbc9160529bbe17b8.C-t-6Gxc.woff2"},{"revision":null,"url":"_astro/8b4cd6678fb13992489bea9b7ac9c220.Du-be5bi.woff2"},{"revision":null,"url":"_astro/891505f3587a9d9fd1d0198f2f7c9cd7.D6ehzCdo.woff2"},{"revision":null,"url":"_astro/88b72f0fc737ea052056f6c2aeea44a3.kFBOKHMb.woff2"},{"revision":null,"url":"_astro/8887b5bf51593b9fc9c25b376961c28d.SLYFOQ6B.woff2"},{"revision":null,"url":"_astro/8835dd6747879c0fba990bd87ecd2301.CE0rVYr2.woff2"},{"revision":null,"url":"_astro/87d4bc8c69dcb27ef4de7d59b7709b0d.Di1KlkL1.woff2"},{"revision":null,"url":"_astro/8724be47dff2dfa9d93959096c5ecb46.CgcLMC7R.woff2"},{"revision":null,"url":"_astro/860c568e2eff98d81cda61d46fcecca1.DsqANwHz.woff2"},{"revision":null,"url":"_astro/8454772e4bc3595d2e908dd191a7bd29.ChLjv6UK.woff2"},{"revision":null,"url":"_astro/844ab646a77389c13720fbf14c0093c3.C90zS1gA.woff2"},{"revision":null,"url":"_astro/8405a331c60fdb56463b89656bb49cd4.BvZxfoDj.woff2"},{"revision":null,"url":"_astro/828cc88997f658acf911380de2f6d320.C28F5emo.woff2"},{"revision":null,"url":"_astro/81f2a172727f431d7ca1cc57284a41d9.CsUVNPaV.woff2"},{"revision":null,"url":"_astro/81447e78a0661abe408d0d3da783afc7.CDNDMDvr.woff2"},{"revision":null,"url":"_astro/80e837e4292c4e443a14bf6a63645320.D2qpPMSm.woff2"},{"revision":null,"url":"_astro/80a8feea65f4077fa429813c8726259d.DD-BeWht.woff2"},{"revision":null,"url":"_astro/809b5c3ad4776a8607ccfe5bb4cfa724.CiwnhhAW.woff2"},{"revision":null,"url":"_astro/7f7b6d5117c9e90741bad29ce16f4b23.CKmth-x3.w
2955off2"},{"revision":null,"url":"_astro/7ece3cbfc188d27ae566cf1e90b245fb.CL2erN5z.woff2"},{"revision":null,"url":"_astro/7df84da8dea8bf937b6cd6498b02562c.ZTo6xLPh.woff2"},{"revision":null,"url":"_astro/7de6db0fcc32ead9e132bb862789058e.DKbR9tXw.woff2"},{"revision":null,"url":"_astro/7db7dd37453f81cf7b32d7d7385affdb.CLVR3iW7.woff2"},{"revision":null,"url":"_astro/7da6a25ea397f993b1635e9ec61b6e7d.D9N3YUUF.woff2"},{"revision":null,"url":"_astro/7d5debdadff5205554730a1db3667690.De4I6wZV.woff2"},{"revision":null,"url":"_astro/7d01df4023fdc4af4a248ec626a9dd5a.DSePzLyP.woff2"},{"revision":null,"url":"_astro/7c7b31a6751aa044a5f97fce6245fbbf.Bm1Pt4Ab.woff2"},{"revision":null,"url":"_astro/7b275413b16c0d9560f917c63b6015a4.CIlDAo7V.woff2"},{"revision":null,"url":"_astro/7a681defbe746aab93deb5c75f8a9b4d.CwqvcN8e.woff2"},{"revision":null,"url":"_astro/7a0548edc531408ac5f247e1aa4e11b3.CoHujI9h.woff2"},{"revision":null,"url":"_astro/77d2de639a2e881d67b90cf4ed67d235.CMczvquw.woff2"},{"revision":null,"url":"_astro/77c17c226061f43701e4c8d7c190aae1.DPMf8f5F.woff2"},{"revision":null,"url":"_astro/76f61cbd4f1635fb86f93c062308c7c2.DkP9CYvR.woff2"},{"revision":null,"url":"_astro/76728302ec8e84f94d98e08d4c238ce6.2mA2imie.woff2"},{"revision":null,"url":"_astro/760e4045bf23ccfe5173b9d39b5321b7.DTYCv5wA.woff2"},{"revision":null,"url":"_astro/7544ada24c2d81778c97a307cfc69328.C0Tuh6f0.woff2"},{"revision":null,"url":"_astro/74e2c8c8d31671e7c90233fbc3ec1f9b.jo_6QXKN.woff2"},{"revision":null,"url":"_astro/72c3e410ffc5ee945e88bdcf7ff2b74d.BzXdccKS.woff2"},{"revision":null,"url":"_astro/7275d086574970760b966e1ab403a203.nbB4aqfh.woff2"},{"revision":null,"url":"_astro/720c3fbae0336ef7f8d2815627135892.CxXeieSr.woff2"},{"revision":null,"url":"_astro/71d061f6ee948114c50a46402e7f08ea.BfLCrOMU.woff2"},{"revision":null,"url":"_astro/70edca627d1654b61d2c66eba8a60923.CTjNlL3u.woff2"},{"revision":null,"url":"_astro/70e6c4446907c6fb588091d6b1ffb290.8gMWenc6.woff2"},{"revision":null,"url":"_astro/6f69323fe2d59ce9051b948992e91faa.DjIWnxvv.woff2"},{"revision":null,"url":"_astro/6e8899581ce28e59cdc324b8ff17afba.Dy2g4XDY.woff2"},{"revision":null,"url":"_astro/6e514460f660c6f1872a317933a2b58c.DMWizJmW.woff2"},{"revision":null,"url":"_astro/6cca0055d8112d032cb64a39c99314e8.ChdyOHsi.woff2"},{"revision":null,"url":"_astro/6c9d122ae88e93ec5aa7b5f9e30ec809.BR8112gD.woff2"},{"revision":null,"url":"_astro/6c8432daf49acb058ce0524ec7caa2ce.LBZA2ZGU.woff2"},{"revision":null,"url":"_astro/6b6957d0be5f2ad3c70f7d16abc5db4e.BIkJY-oQ.woff2"},{"revision":null,"url":"_astro/6b4a027abe59e37b4a601aefa813c457.CIchla6q.woff2"},{"revision":null,"url":"_astro/6b22adec943714eea6f3d1462891c76b.Dw_mm8Bk.woff2"},{"revision":null,"url":"_astro/693e8cc50bd8ca9334c9596beaa34e69.D7CW_GVi.woff2"},{"revision":null,"url":"_astro/69365138119fde8520e981b2e7022343.DAwL5-FB.woff2"},{"revision":null,"url":"_astro/68af459315ffdcc08c9adfde1765a6e4.CDWXJhzx.woff2"},{"revision":null,"url":"_astro/67f207248641834075674a7af3f2bda9.DvHfnduI.woff2"},{"revision":null,"url":"_astro/67b2af74e450c3e7dc7747b4840c3d92.CB0OYZlO.woff2"},{"revision":null,"url":"_astro/6707ecacd98f6f610e556c42ab25bc03.CNu0NEAq.woff2"},{"revision":null,"url":"_astro/667aa20fe5275d0f7b32cd19cc659658.mU4IgL0B.woff2"},{"revision":null,"url":"_astro/660290fdb8cb91d68b2355e0e108e0b2.B2iO8qJH.woff2"},{"revision":null,"url":"_astro/657bffaa4d4adfde663ae4174e8d28e3.DW93Uep1.woff2"},{"revision":null,"url":"_astro/64fcae53bcb2f59944eff4ebab77fd54.BB5dUjFI.woff2"},{"revision":null,"url":"_astro/64a09c11d4b3f49f2fed35ac0bd5215f.R6WSTs3R.woff2"},{"revision":null,"url":"_astro/63700f2ecbb2cfbac90fb381acbe5291.BZXymL7f.woff2"},{"revision":null,"url":"_astro/6345d5d44a3b7e2b144b64aad17cde2a.D6sEDxjn.woff2"},{"revision":null,"url":"_astro/62db972cd6d47902c56153bec79e23b0.W_reqkq3.woff2"},{"revision":null,"url":"_astro/62c086b02bfd861e859eb47f04e83aa6.CwtUu09n.woff2"},{"revision":null,"url":"_astro/6299112ff79802e5f8e8549fe22ce16c.BCuJjNqn.woff2"},{"revision":null,"url":"_astro/62834ea0d492cb5300cbbf44efc5a8e9.BcmgJ2j6.woff2"},{"revision":null,"url":"_astro/6202f0acb1fc24e989b49de80581cd90.BkYufQAq.woff2"},{"revision":null,"url":"_astro/61e09798c8329db8af99de9e48d7b531.R9qNq8bI.woff2"},{"revision":null,"url":"_astro/600074b0221150dd5b0d33bffc32e76d.EYJdzUW0.woff2"},{"revision":null,"url":"_astro/5ee0277db963efad764d7a479662312c.Dy3PX8yX.woff2"},{"revision":null,"url":"_astro/5e2ca114d1ad98793013edaa18552ff2.PSln3fYs.woff2"},{"revision":null,"url":"_astro/5e0f405bd14b183833cbf3546a792f5e.Dx4hbNX-.woff2"},{"revision":null,"url":"_astro/5cf217f562f6723e191b6cb95260ea30.VTn2fWFJ.woff2"},{"revision":null,"url":"_astro/5afd67baa20f3b8cc6c2bd49366ac79a.BceNt_Se.woff2"},{"revision":null,"url":"_astro/5a7c22819e17c2175e1a4bc8770f8c25.BG_A5aFU.woff2"}
2955,{"revision":null,"url":"_astro/59c29ab83d1b862cb747ce7fedfa279e.BS1Qv5ih.woff2"},{"revision":null,"url":"_astro/59b4ad1378d0c0dcbc6c0c6361b78be9.DFcZIYd3.woff2"},{"revision":null,"url":"_astro/57ca409b5982110458b2516b5c4bd6ad.CTh6jHHn.woff2"},{"revision":null,"url":"_astro/56f687dfdac5da0a0aefed1db80d4e58.DXZtdEYA.woff2"},{"revision":null,"url":"_astro/5641f14be9d16d1b9b31597d29891d83.BJwJrr6Z.woff2"},{"revision":null,"url":"_astro/55f1c5bd358f15c04387ff082bce86e8.Crqjepn4.woff2"},{"revision":null,"url":"_astro/54537a6c9342c843f9b85bf05bc2185f.RLRzlbP1.woff2"},{"revision":null,"url":"_astro/5438ed1f05fcaaf0495d861f25671f74.uRTZFTWL.woff2"},{"revision":null,"url":"_astro/53e69d0ea7fc22511afadf84b5c66842.CAJVbwtG.woff2"},{"revision":null,"url":"_astro/5287ad504bd0fa1370c314085b43526c.Bb2c8cn1.woff2"},{"revision":null,"url":"_astro/51d23a1a04b443ae8c4845d4275d8e41.Dc-rpXTc.woff2"},{"revision":null,"url":"_astro/51b07279ab3006929f0e515b737fab4b.DgCGnEjV.woff2"},{"revision":null,"url":"_astro/51117d6dfd5c148863f17547244486c4.D7J7H6SU.woff2"},{"revision":null,"url":"_astro/501ed35cdd38ac05f709eec011022790.B0Yk7LIA.woff2"},{"revision":null,"url":"_astro/4f5286db12432fa6d8f58b0702163346.Dz_tZ1xY.woff2"},{"revision":null,"url":"_astro/4e8028e6c455b85b743792396ca9880c.a38TtmcL.woff2"},{"revision":null,"url":"_astro/4e6248a6570a9123394171f97d9ebd8c.BceGM8Kt.woff2"},{"revision":null,"url":"_astro/4dde70e24c3a64c1192536fee958c9b6.Dyau0_Ns.woff2"},{"revision":null,"url":"_astro/4d903b8f9ed7be68b9b0374e9bbf77c9.BejcBHQ_.woff2"},{"revision":null,"url":"_astro/4d12b96edd37375dba2cea250a4b25e3.CVwyx5gp.woff2"},{"revision":null,"url":"_astro/4c04d7fcb047d23a4cd98ced9d839762.CjDGYgc4.woff2"},{"revision":null,"url":"_astro/4beef87f3c54ab14deeb465f1fa9bd73.Rtvrdd_w.woff2"},{"revision":null,"url":"_astro/4b4b0666000672dee7828b1fb9c27163.BqRyLvZu.woff2"},{"revision":null,"url":"_astro/4a82586d4fb6e211700ac238cb9cd755.B6w-KioT.woff2"},{"revision":null,"url":"_astro/4a7d292ecad080c2bf0d37a0b33b7f23.lJlyhi9g.woff2"},{"revision":null,"url":"_astro/49d4250019e47c31cc5875db0dbaa32b.CuAB22ni.woff2"},{"revision":null,"url":"_astro/4807e17635e955f0ab52ab4e76b7698b.CNUL7-wp.woff2"},{"revision":null,"url":"_astro/473ddd24f07f47016e02154ad18f371b.CfqTXSLD.woff2"},{"revision":null,"url":"_astro/46518d7ddb66462f4b41973b5e17409c.D6In597Q.woff2"},{"revision":null,"url":"_astro/460d619058f131b8ef3b6b382de470bb.SQNK9hP-.woff2"},{"revision":null,"url":"_astro/455b7aed93a79160421f9373d69ea945.DQktKVxy.woff2"},{"revision":null,"url":"_astro/44ab4dcef1e4f4bbea301a7f0105ccce.Ds7dqQvn.woff2"},{"revision":null,"url":"_astro/43a6b96960c64dd86fb8612735d2d0b9.CdJ6qdy5.woff2"},{"revision":null,"url":"_astro/42e2798adff5ad44aacae9f30a4d6c92.BDWNy1k9.woff2"},{"revision":null,"url":"_astro/4291ea01d000c90c18ed23edcd1a4c15.CO84emt4.woff2"},{"revision":null,"url":"_astro/427f0e86064cbe68b914856654da8e8a.D0TPkNgx.woff2"},{"revision":null,"url":"_astro/4274d4eaae4972a019be518ee25a931d.SHRVIUKD.woff2"},{"revision":null,"url":"_astro/426e7c36c0f4e05294e1a69327e0bd2b.CXNgE0v4.woff2"},{"revision":null,"url":"_astro/426c695308ffc39993c1f22772a08664.Dmiv6mVj.woff2"},{"revision":null,"url":"_astro/40f3457e449a018c65d0ac059e48b54f.BaOqRsl-.woff2"},{"revision":null,"url":"_astro/40e6246fbc5d11485fcfb54dc32c0363.DC3yoYfY.woff2"},{"revision":null,"url":"_astro/3f1dbd461b7c1e926231eda7b2aaee1e.DUnu5BGB.woff2"},{"revision":null,"url":"_astro/3e6a0ef3c3dfe8b8fbf9bb48a1495191.B42oHf78.woff2"},{"revision":null,"url":"_astro/3ce8ba2d58210c7c50e09a42c5004e34.OywkoiKB.woff2"},{"revision":null,"url":"_astro/3cab4ba353d75841d369a1349dc82f35.BQeCm8DC.woff2"},{"revision":null,"url":"_astro/3c412aa119fc85931c21df7d91ced9c1.tSA1Cti8.woff2"},{"revision":null,"url":"_astro/3a094b4809c2d00f59eb3f1b29c829bd.BcxgNpGE.woff2"},{"revision":null,"url":"_astro/394d5654057abbe8e789c97920117635.psd9a9aO.woff2"},{"revision":null,"url":"_astro/391462ae7cfe20135546c5924e3ae10a.DM2-L0Up.woff2"},{"revision":null,"url":"_astro/38dc7781102e0e245becfac0f8de8195.B-fapLaO.woff2"},{"revision":null,"url":"_astro/36348738c65453b81b0f1e922d0672c2.DjrA7_qQ.woff2"},{"revision":null,"url":"_astro/35d64fc3622b203e349358027ad7ed26.wvqweQYm.woff2"},{"revision":null,"url":"_astro/35d3d9e65bc9a183c52f94fd05a34298.Cml-JRn8.woff2"},{"revision":null,"url":"_astro/359ee3b1f2acc4f4394bc0dcb860e638.DWmJUyXo.woff2"},{"revision":null,"url":"_astro/329e2ec8d131fa86b4a38eae4400c436.BqJEuUjO.woff2"},{"revision":null,"url":"_astro/326c3c530db1e8c87c3da58205b27384.B0cjo-xW.woff2"},{"revision":null,"url":"_astro/32280a576d21714b6fd1f0fc54877723.BU-Qlo5B.woff2"},{"revision":null,"url":"_astro/31d21fea36802fd26731ba905053b5e1.WHKdftaa.woff2"},{"revision":null,"url":"_astro/31b20bb2b4b4660c5b2f61f0fb878ed2.XUfOrk-x.woff2"}
2955,{"revision":null,"url":"_astro/30ae6efd00b6d50eb170e89d369c5da4.B2JewftU.woff2"},{"revision":null,"url":"_astro/303885cb4dd323dca512a48856087537.BJ9QUTR5.woff2"},{"revision":null,"url":"_astro/2f7ece1fa44eab24788058e5967fadb9.Ddox0joj.woff2"},{"revision":null,"url":"_astro/2f5945165e5fa89b8633e63766d396cc.PPrQFvgR.woff2"},{"revision":null,"url":"_astro/2e953d39337bcf4203644c082d1a0594.8JJVJ8aW.woff2"},{"revision":null,"url":"_astro/2e34e5e187cff69c094779e98909ccbd.Cbs9bSjv.woff2"},{"revision":null,"url":"_astro/2d79daf27dd5262e45dc2b534e076e18.CirQ7_TS.woff2"},{"revision":null,"url":"_astro/2bfbe338209485e03ff6f86782cc2f0d.DQnx94Rd.woff2"},{"revision":null,"url":"_astro/2b9e9f750a3186ac278a5acc47bbf23b.DLiNFfgP.woff2"},{"revision":null,"url":"_astro/2b2e305e9a294bf33766c5a17f0ddd9c.CmvBiA3u.woff2"},{"revision":null,"url":"_astro/2aad45d305edfc63941e4390aafe19a4.GQvdK46J.woff2"},{"revision":null,"url":"_astro/2a8b00bb519456d2bccb05908240e940.CtuHGhOk.woff2"},{"revision":null,"url":"_astro/2a298e831291dd6a598b51168c358083.BU3y2cmr.woff2"},{"revision":null,"url":"_astro/294ac3315e0dc49e3e4a6916ed5d17b0.Cx3UWLja.woff2"},{"revision":null,"url":"_astro/2939ad84c5a30dee36ba8428c2019b7d.DTz4mdPg.woff2"},{"revision":null,"url":"_astro/287b99508d6ff4464137ed12558f8b6b.CjhQIQt7.woff2"},{"revision":null,"url":"_astro/27ce7719282413933ce6686e8f747b1a.W4xwQZ8Q.woff2"},{"revision":null,"url":"_astro/27166528ebc4fb74aeb087820007751c.CZhTzk0D.woff2"},{"revision":null,"url":"_astro/2671a22b21da4c0a39bfdee3ac93d512.DWM22gRC.woff2"},{"revision":null,"url":"_astro/262153698eda6d1677a28e5232378bde.BN8e-HKl.woff2"},{"revision":null,"url":"_astro/260b050a8443134b85bf1f19849158f5.B77Je7a7.woff2"},{"revision":null,"url":"_astro/253b3d53d2fdb063079dbbf8dd7e4f33.k8CKhXiF.woff2"},{"revision":null,"url":"_astro/23d32f88ee46f9f934a2488ec1442c4f.Dtl_tWby.woff2"},{"revision":null,"url":"_astro/2355396cf85e45e2e9e1b21f8517ac4e.CVk4-4z_.woff2"},{"revision":null,"url":"_astro/22d1538b36ff82be8468d166d642a4c4.BHsRsate.woff2"},{"revision":null,"url":"_astro/228df352fc34f2fe54f51a8c72337e87.BB55DhhX.woff2"},{"revision":null,"url":"_astro/21362f29d67479a523bff9a24a58bc92.Cz9Sp4M1.woff2"},{"revision":null,"url":"_astro/20a145fd28e36ff7f4814786e86d7874.DR6OxlxU.woff2"},{"revision":null,"url":"_astro/201853860f51e355ff72f8552c964c96.CCw4wcGK.woff2"},{"revision":null,"url":"_astro/1fd9cda8a04331cdd8d8c554dd855de9.haA1fokS.woff2"},{"revision":null,"url":"_astro/1f9bfc0ca4dde0fa15ba2dbe32c665fe.rAQ3B0Cz.woff2"},{"revision":null,"url":"_astro/1f5b29147c23302cecd34bec87adf23b.C4NcL3wN.woff2"},{"revision":null,"url":"_astro/1ccb869ac8c763adece9ad84e05a150a.vCGhC3BF.woff2"},{"revision":null,"url":"_astro/1ca23775faddd4640fa7c77dcfdf91c3.UpvJXqrQ.woff2"},{"revision":null,"url":"_astro/1c59b3f58d5e7a7bc27f3c575a01efb5.YZ_JdoM3.woff2"},{"revision":null,"url":"_astro/1b31ddf38192066f1aaf2809468cf98b.MVQvthkd.woff2"},{"revision":null,"url":"_astro/1adebf75f69e18f4a7c96470d95da3d5.Di2QzDSc.woff2"},{"revision":null,"url":"_astro/1aaa9111c8184b0cb9762bfcd81a9361.WQlYzs0d.woff2"},{"revision":null,"url":"_astro/196fab94b07f089780db0d63d313da53.u2SFI8-j.woff2"},{"revision":null,"url":"_astro/194d55502bf82379f699fe0d6b9f0ec5.fBarZzvB.woff2"},{"revision":null,"url":"_astro/194729d6094a4724ea62dcd2b99c1a8d.CwAqBYY3.woff2"},{"revision":null,"url":"_astro/18faece5a4fb8df5cc288be50c4f768d.QCo7MIoq.woff2"},{"revision":null,"url":"_astro/1658351b56edef7ce6a6fa9918a2d9f5.EGwXpRjW.woff2"},{"revision":null,"url":"_astro/162079c2ee90ab1639c9e31e3f528595.CGkCqn-n.woff2"},{"revision":null,"url":"_astro/160a7522c18cc9acf51b9050457356e0.DyVKSvwa.woff2"},{"revision":null,"url":"_astro/156f39e70b2579219dbe3cf02957c63a.vx7Ukdtz.woff2"},{"revision":null,"url":"_astro/1482b212487bf8a34c3a2c89088caa63.CnHTcqCB.woff2"},{"revision":null,"url":"_astro/142ad2ddfd9c9e2dcdffa982fbd8d089.Bt1A6DMt.woff2"},{"revision":null,"url":"_astro/14264c10c57a4e8ab8731facff7877a0.DLcW7Q85.woff2"},{"revision":null,"url":"_astro/13fe422cabb86e7fb47533304a1c733b.D50P5GMb.woff2"},{"revision":null,"url":"_astro/1395274a0bc8725e9c9f9527789cb565.Hdkorzws.woff2"},{"revision":null,"url":"_astro/130be03859da4f7562185f51bbaeaf8f.CwUDseZS.woff2"},{"revision":null,"url":"_astro/128dfabba7da1f854ed0e61f74d7a5ff.gsjsmJZX.woff2"},{"revision":null,"url":"_astro/127a7b7251349dc96b1a297dc1b8eac1.RI6vHyYO.woff2"},{"revision":null,"url":"_astro/12783f8265f7fdc08b7e81d1fcf54dd5.D0-164i0.woff2"},{"revision":null,"url":"_astro/121697e6fce00dc08db328eff101db83.BJEc0QJc.woff2"},{"revision":null,"url":"_astro/0f7f64f8c8ed525fc81da46fbe91846e.wl6A-LSm.woff2"},{"revision":null,"url":"_astro/0f6ade4260b39adb23911be392d328fb.DHQL_vLe.woff2"},{"revision":null,"url":"_astro/0e74f0bee002338f20c98a62550ec78a.CGneRNRR.woff2"},{"revision":null,"url":"_astro/0e7441bb24f42a46a293194448a64420.COMl2fWD.woff2"},{"revision":null,"url":"_astro/0e63fc43ea96ad55f00b2e561d3cf45c.D3J
295511xDS.woff2"},{"revision":null,"url":"_astro/0e052d5eb321b5b078f29e26ac9431fd.rxJ2UMa3.woff2"},{"revision":null,"url":"_astro/0deb80682bb502f01147132e61bdc122.BgOHUDpu.woff2"},{"revision":null,"url":"_astro/0c50381020d9590e6891739968e77d3b.Xeq-FnRu.woff2"},{"revision":null,"url":"_astro/0c42ce464f36c87f511779e9b960b8f9.D2_ZWMWL.woff2"},{"revision":null,"url":"_astro/0beae3787db54f1e9ce25c9d1cd8e6ac.B1FG1yFK.woff2"},{"revision":null,"url":"_astro/0bbd3e8edd9cc83168028cc21af34d00.B3RMI-nZ.woff2"},{"revision":null,"url":"_astro/0b84a60dfe1bb98d6d6a27c965cca5a8.Cb-U4HU8.woff2"},{"revision":null,"url":"_astro/0aa95b56f95e3ddc3b328dbf951937f2.DqeJ0Nj7.woff2"},{"revision":null,"url":"_astro/0a6d5dfe13a290d4afc8b69fca5f4590.DgBhvXQV.woff2"},{"revision":null,"url":"_astro/09609802320013e8f69366a19a7d13bb.BtTDEAEg.woff2"},{"revision":null,"url":"_astro/094b3eccf58b71b4105f90860f7b85b1.CMaoD92y.woff2"},{"revision":null,"url":"_astro/0912c393c6f009eec98646766cfc4d27.D4wZ53Qu.woff2"},{"revision":null,"url":"_astro/0697d64297e842068df4e27ee622e52a.NnJDwtIo.woff2"},{"revision":null,"url":"_astro/04a7c2f0d0f5edb15ec92dea84222f4a.1kqigEEN.woff2"},{"revision":null,"url":"_astro/03e3ca3b28326cfe4a95f7067da4447c.CqGX8CHw.woff2"},{"revision":null,"url":"_astro/038493ffe66e4e34a5b3d02b00a5a189.CDy_Mr-a.woff2"},{"revision":null,"url":"_astro/0373e623dbd35b6a425b9eeebce4c54d.C41fY3fx.woff2"},{"revision":null,"url":"_astro/03696db054b35553c1eb56737007c73e.CEBjo5NE.woff2"},{"revision":null,"url":"_astro/03163167e684fc2632d1872370bcc208.B83W5DfL.woff2"},{"revision":null,"url":"_astro/02c858bb77c7d97d857c4919aa664256.BP3f9lrO.woff2"},{"revision":null,"url":"_astro/013133458d8bff752f948ecb6cd05f37.D5oHfPbF.woff2"},{"revision":null,"url":"_astro/00799f84d031710cfa62c7e70bc23a37.E7rK4khI.woff2"},{"revision":null,"url":"_astro/001d7dfc173d83977c289df204ec4eb3.htUeu1rX.woff2"},{"revision":null,"url":"/offline/index.html"},{"revision":null,"url":"/404.html"},{"revision":"6d8609ea51b1cd8ea6452fcb6fc3806a","url":"manifest.webmanifest"},{"revision":"6d8609ea51b1cd8ea6452fcb6fc3806a","url":"manifest.webmanifest"},{"revision":"6d8609ea51b1cd8ea6452fcb6fc3806a","url":"manifest.webmanifest"},{"revision":"6d8609ea51b1cd8ea6452fcb6fc3806a","url":"manifest.webmanifest"},{"revision":"6d8609ea51b1cd8ea6452fcb6fc3806a","url":"manifest.webmanifest"}]);
2956
2957const OFFLINE_PAGE = '/offline/index.html';
2958const PAGE_CACHE = 'pages-cache';
2959
2960const navigationRoute = new NavigationRoute(async ({ event }) => {
2961  const request = event.request;
2962  
2963  try {
2964    const response = await fetch(request);
2965    
2966    if (response.ok) {
2967      const responseClone = response.clone();
2968      const cache = await caches.open(PAGE_CACHE);
2969      await cache.put(request, responseClone);
2970    }
2971    
2972    return response;
2973  } catch (error) {
2974    console.log('Network request failed, serving offline page:', error);
2975    
2976    const cachedResponse = await caches.match(request);
2977    if (cachedResponse) {
2978      return cachedResponse;
2979    }
2980    
2981    const cachedOffline = await matchPrecache(OFFLINE_PAGE);
2982    if (cachedOffline) {
2983      return cachedOffline;
2984    }
2985    
2986    return new Response('Offline', { status: 503 });
2987  }
2988}, {
2989  denylist: [
2990    /^\/.well-known\/host\.txt$/,
2991    /^\/.well-known\//,
2992    /^\/api\//,
2993    /^\/admin\//,
2994  ],
2995});
2996
2997registerRoute(navigationRoute);
2998
2999registerRoute(
3000  /\/blog\/.*/i,
3001  new NetworkFirst({
3002    cacheName: 'blog-posts-cache',
3003    networkTimeoutSeconds: 10,
3004    plugins: [
3005      new CacheableResponsePlugin({
3006        statuses: [0, 200],
3007      }),
3008      new ExpirationPlugin({
3009        maxEntries: 100,
3010        maxAgeSeconds: 60 * 60 * 24 * 30,
3011      }),
3012    ],
3013  })
3014);
3015
3016registerRoute(
3017  /\.(?:png|jpg|jpeg|gif|webp|svg|ico)$/i,
3018  new CacheFirst({
3019    cacheName: 'images-cache',
3020    plugins: [
3021      new CacheableResponsePlugin({
3022        statuses: [0, 200],
3023      }),
3024      new ExpirationPlugin({
3025        maxEntries: 100,
3026        maxAgeSeconds: 60 * 60 * 24 * 30,
3027      }),
3028    ],
3029  })
3030);
3031
3032registerRoute(
3033  /\.(?:js|css)$/i,
3034  new NetworkFirst({
3035    cacheName: 'static-resources-cache',
3036    networkTimeoutSeconds: 10,
3037    plugins: [
3038      new CacheableResponsePlugin({
3039        statuses: [0, 200],
3040      }),
3041      new ExpirationPlugin({
3042        maxEntries: 100,
3043        maxAgeSeconds: 60 * 60 * 24 * 30,
3044      }),
3045    ],
3046  })
3047);
3048
3049registerRoute(
3050  /\/(rss\.xml|sitemap-index\.xml|sitemap-\d+\.xml)$/i,
3051  new NetworkFirst({
3052    cacheName: 'seo-files-cache',
3053    networkTimeoutSeconds: 10,
3054    plugins: [
3055      new CacheableResponsePlugin({
3056        statuses: [0, 200],
3057      }),
3058      new ExpirationPlugin({
3059        maxEntries: 10,
3060        maxAgeSeconds: 60 * 60 * 24,
3061      }),
3062    ],
3063  })
3064);
3065
3066self.addEventListener('install', () => {
3067  console.log('Service Worker installed');
3068  self.skipWaiting();
3069});
3070
3071self.addEventListener('activate', (event) => {
3072  console.log('Service Worker activated');
3073  event.waitUntil(self.clients.claim());
3074});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.