2023-12-09 11:43:51 +03:00
try {
self [ "workbox:core:7.0.0" ] && _ ( ) ;
} catch {
}
const G = ( s , ... e ) => {
let t = s ;
return e . length > 0 && ( t += ` :: ${ JSON . stringify ( e ) } ` ) , t ;
} , Q = G ;
class h extends Error {
/ * *
*
* @ param { string } errorCode The error code that
* identifies this particular error .
* @ param { Object = } details Any relevant arguments
* that will help developers identify issues should
* be added as a key on the context object .
* /
constructor ( e , t ) {
const n = Q ( e , t ) ;
super ( n ) , this . name = e , this . details = t ;
}
}
const B = /* @__PURE__ */ new Set ( ) ;
function z ( s ) {
B . add ( s ) ;
}
const d = {
googleAnalytics : "googleAnalytics" ,
precache : "precache-v2" ,
prefix : "workbox" ,
runtime : "runtime" ,
suffix : typeof registration < "u" ? registration . scope : ""
} , k = ( s ) => [ d . prefix , s , d . suffix ] . filter ( ( e ) => e && e . length > 0 ) . join ( "-" ) , J = ( s ) => {
for ( const e of Object . keys ( d ) )
s ( e ) ;
} , x = {
updateDetails : ( s ) => {
J ( ( e ) => {
typeof s [ e ] == "string" && ( d [ e ] = s [ e ] ) ;
} ) ;
} ,
getGoogleAnalyticsName : ( s ) => s || k ( d . googleAnalytics ) ,
getPrecacheName : ( s ) => s || k ( d . precache ) ,
getPrefix : ( ) => d . prefix ,
getRuntimeName : ( s ) => s || k ( d . runtime ) ,
getSuffix : ( ) => d . suffix
} ;
function K ( s , e ) {
const t = new URL ( s ) ;
for ( const n of e )
t . searchParams . delete ( n ) ;
return t . href ;
}
async function X ( s , e , t , n ) {
const a = K ( e . url , t ) ;
if ( e . url === a )
return s . match ( e , n ) ;
const r = Object . assign ( Object . assign ( { } , n ) , { ignoreSearch : ! 0 } ) , i = await s . keys ( e , r ) ;
for ( const c of i ) {
const o = K ( c . url , t ) ;
if ( a === o )
return s . match ( c , n ) ;
}
}
let m ;
function Y ( ) {
if ( m === void 0 ) {
const s = new Response ( "" ) ;
if ( "body" in s )
try {
new Response ( s . body ) , m = ! 0 ;
} catch {
m = ! 1 ;
}
m = ! 1 ;
}
return m ;
}
function q ( s ) {
s . then ( ( ) => {
} ) ;
}
class Z {
/ * *
* Creates a promise and exposes its resolve and reject functions as methods .
* /
constructor ( ) {
this . promise = new Promise ( ( e , t ) => {
this . resolve = e , this . reject = t ;
} ) ;
}
}
async function ee ( ) {
for ( const s of B )
await s ( ) ;
}
const te = ( s ) => new URL ( String ( s ) , location . href ) . href . replace ( new RegExp ( ` ^ ${ location . origin } ` ) , "" ) ;
function se ( s ) {
return new Promise ( ( e ) => setTimeout ( e , s ) ) ;
}
function A ( s , e ) {
const t = e ( ) ;
return s . waitUntil ( t ) , t ;
}
async function ne ( s , e ) {
let t = null ;
if ( s . url && ( t = new URL ( s . url ) . origin ) , t !== self . location . origin )
throw new h ( "cross-origin-copy-response" , { origin : t } ) ;
const n = s . clone ( ) , a = {
headers : new Headers ( n . headers ) ,
status : n . status ,
statusText : n . statusText
} , r = e ? e ( a ) : a , i = Y ( ) ? n . body : await n . blob ( ) ;
return new Response ( i , r ) ;
}
function ae ( ) {
self . addEventListener ( "activate" , ( ) => self . clients . claim ( ) ) ;
}
const re = ( s , e ) => e . some ( ( t ) => s instanceof t ) ;
let j , O ;
function ie ( ) {
return j || ( j = [
IDBDatabase ,
IDBObjectStore ,
IDBIndex ,
IDBCursor ,
IDBTransaction
] ) ;
}
function ce ( ) {
return O || ( O = [
IDBCursor . prototype . advance ,
IDBCursor . prototype . continue ,
IDBCursor . prototype . continuePrimaryKey
] ) ;
}
const F = /* @__PURE__ */ new WeakMap ( ) , U = /* @__PURE__ */ new WeakMap ( ) , H = /* @__PURE__ */ new WeakMap ( ) , v = /* @__PURE__ */ new WeakMap ( ) , P = /* @__PURE__ */ new WeakMap ( ) ;
function oe ( s ) {
const e = new Promise ( ( t , n ) => {
const a = ( ) => {
s . removeEventListener ( "success" , r ) , s . removeEventListener ( "error" , i ) ;
} , r = ( ) => {
t ( f ( s . result ) ) , a ( ) ;
} , i = ( ) => {
n ( s . error ) , a ( ) ;
} ;
s . addEventListener ( "success" , r ) , s . addEventListener ( "error" , i ) ;
} ) ;
return e . then ( ( t ) => {
t instanceof IDBCursor && F . set ( t , s ) ;
} ) . catch ( ( ) => {
} ) , P . set ( e , s ) , e ;
}
function le ( s ) {
if ( U . has ( s ) )
return ;
const e = new Promise ( ( t , n ) => {
const a = ( ) => {
s . removeEventListener ( "complete" , r ) , s . removeEventListener ( "error" , i ) , s . removeEventListener ( "abort" , i ) ;
} , r = ( ) => {
t ( ) , a ( ) ;
} , i = ( ) => {
n ( s . error || new DOMException ( "AbortError" , "AbortError" ) ) , a ( ) ;
} ;
s . addEventListener ( "complete" , r ) , s . addEventListener ( "error" , i ) , s . addEventListener ( "abort" , i ) ;
} ) ;
U . set ( s , e ) ;
}
let T = {
get ( s , e , t ) {
if ( s instanceof IDBTransaction ) {
if ( e === "done" )
return U . get ( s ) ;
if ( e === "objectStoreNames" )
return s . objectStoreNames || H . get ( s ) ;
if ( e === "store" )
return t . objectStoreNames [ 1 ] ? void 0 : t . objectStore ( t . objectStoreNames [ 0 ] ) ;
}
return f ( s [ e ] ) ;
} ,
set ( s , e , t ) {
return s [ e ] = t , ! 0 ;
} ,
has ( s , e ) {
return s instanceof IDBTransaction && ( e === "done" || e === "store" ) ? ! 0 : e in s ;
}
} ;
function he ( s ) {
T = s ( T ) ;
}
function ue ( s ) {
return s === IDBDatabase . prototype . transaction && ! ( "objectStoreNames" in IDBTransaction . prototype ) ? function ( e , ... t ) {
const n = s . call ( E ( this ) , e , ... t ) ;
return H . set ( n , e . sort ? e . sort ( ) : [ e ] ) , f ( n ) ;
} : ce ( ) . includes ( s ) ? function ( ... e ) {
return s . apply ( E ( this ) , e ) , f ( F . get ( this ) ) ;
} : function ( ... e ) {
return f ( s . apply ( E ( this ) , e ) ) ;
} ;
}
function de ( s ) {
return typeof s == "function" ? ue ( s ) : ( s instanceof IDBTransaction && le ( s ) , re ( s , ie ( ) ) ? new Proxy ( s , T ) : s ) ;
}
function f ( s ) {
if ( s instanceof IDBRequest )
return oe ( s ) ;
if ( v . has ( s ) )
return v . get ( s ) ;
const e = de ( s ) ;
return e !== s && ( v . set ( s , e ) , P . set ( e , s ) ) , e ;
}
const E = ( s ) => P . get ( s ) ;
function fe ( s , e , { blocked : t , upgrade : n , blocking : a , terminated : r } = { } ) {
const i = indexedDB . open ( s , e ) , c = f ( i ) ;
return n && i . addEventListener ( "upgradeneeded" , ( o ) => {
n ( f ( i . result ) , o . oldVersion , o . newVersion , f ( i . transaction ) , o ) ;
} ) , t && i . addEventListener ( "blocked" , ( o ) => t (
// Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
o . oldVersion ,
o . newVersion ,
o
) ) , c . then ( ( o ) => {
r && o . addEventListener ( "close" , ( ) => r ( ) ) , a && o . addEventListener ( "versionchange" , ( l ) => a ( l . oldVersion , l . newVersion , l ) ) ;
} ) . catch ( ( ) => {
} ) , c ;
}
function pe ( s , { blocked : e } = { } ) {
const t = indexedDB . deleteDatabase ( s ) ;
return e && t . addEventListener ( "blocked" , ( n ) => e (
// Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
n . oldVersion ,
n
) ) , f ( t ) . then ( ( ) => {
} ) ;
}
const ge = [ "get" , "getKey" , "getAll" , "getAllKeys" , "count" ] , me = [ "put" , "add" , "delete" , "clear" ] , D = /* @__PURE__ */ new Map ( ) ;
function S ( s , e ) {
if ( ! ( s instanceof IDBDatabase && ! ( e in s ) && typeof e == "string" ) )
return ;
if ( D . get ( e ) )
return D . get ( e ) ;
const t = e . replace ( /FromIndex$/ , "" ) , n = e !== t , a = me . includes ( t ) ;
if (
// Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
! ( t in ( n ? IDBIndex : IDBObjectStore ) . prototype ) || ! ( a || ge . includes ( t ) )
)
return ;
const r = async function ( i , ... c ) {
const o = this . transaction ( i , a ? "readwrite" : "readonly" ) ;
let l = o . store ;
return n && ( l = l . index ( c . shift ( ) ) ) , ( await Promise . all ( [
l [ t ] ( ... c ) ,
a && o . done
] ) ) [ 0 ] ;
} ;
return D . set ( e , r ) , r ;
}
he ( ( s ) => ( {
... s ,
get : ( e , t , n ) => S ( e , t ) || s . get ( e , t , n ) ,
has : ( e , t ) => ! ! S ( e , t ) || s . has ( e , t )
} ) ) ;
try {
self [ "workbox:expiration:7.0.0" ] && _ ( ) ;
} catch {
}
const we = "workbox-expiration" , w = "cache-entries" , W = ( s ) => {
const e = new URL ( s , location . href ) ;
return e . hash = "" , e . href ;
} ;
class ye {
/ * *
*
* @ param { string } cacheName
*
* @ private
* /
constructor ( e ) {
this . _db = null , this . _cacheName = e ;
}
/ * *
* Performs an upgrade of indexedDB .
*
* @ param { IDBPDatabase < CacheDbSchema > } db
*
* @ private
* /
_upgradeDb ( e ) {
const t = e . createObjectStore ( w , { keyPath : "id" } ) ;
t . createIndex ( "cacheName" , "cacheName" , { unique : ! 1 } ) , t . createIndex ( "timestamp" , "timestamp" , { unique : ! 1 } ) ;
}
/ * *
* Performs an upgrade of indexedDB and deletes deprecated DBs .
*
* @ param { IDBPDatabase < CacheDbSchema > } db
*
* @ private
* /
_upgradeDbAndDeleteOldDbs ( e ) {
this . _upgradeDb ( e ) , this . _cacheName && pe ( this . _cacheName ) ;
}
/ * *
* @ param { string } url
* @ param { number } timestamp
*
* @ private
* /
async setTimestamp ( e , t ) {
e = W ( e ) ;
const n = {
url : e ,
timestamp : t ,
cacheName : this . _cacheName ,
// Creating an ID from the URL and cache name won't be necessary once
// Edge switches to Chromium and all browsers we support work with
// array keyPaths.
id : this . _getId ( e )
} , r = ( await this . getDb ( ) ) . transaction ( w , "readwrite" , {
durability : "relaxed"
} ) ;
await r . store . put ( n ) , await r . done ;
}
/ * *
* Returns the timestamp stored for a given URL .
*
* @ param { string } url
* @ return { number | undefined }
*
* @ private
* /
async getTimestamp ( e ) {
const n = await ( await this . getDb ( ) ) . get ( w , this . _getId ( e ) ) ;
return n == null ? void 0 : n . timestamp ;
}
/ * *
* Iterates through all the entries in the object store ( from newest to
* oldest ) and removes entries once either ` maxCount ` is reached or the
* entry ' s timestamp is less than ` minTimestamp ` .
*
* @ param { number } minTimestamp
* @ param { number } maxCount
* @ return { Array < string > }
*
* @ private
* /
async expireEntries ( e , t ) {
const n = await this . getDb ( ) ;
let a = await n . transaction ( w ) . store . index ( "timestamp" ) . openCursor ( null , "prev" ) ;
const r = [ ] ;
let i = 0 ;
for ( ; a ; ) {
const o = a . value ;
o . cacheName === this . _cacheName && ( e && o . timestamp < e || t && i >= t ? r . push ( a . value ) : i ++ ) , a = await a . continue ( ) ;
}
const c = [ ] ;
for ( const o of r )
await n . delete ( w , o . id ) , c . push ( o . url ) ;
return c ;
}
/ * *
* Takes a URL and returns an ID that will be unique in the object store .
*
* @ param { string } url
* @ return { string }
*
* @ private
* /
_getId ( e ) {
return this . _cacheName + "|" + W ( e ) ;
}
/ * *
* Returns an open connection to the database .
*
* @ private
* /
async getDb ( ) {
return this . _db || ( this . _db = await fe ( we , 1 , {
upgrade : this . _upgradeDbAndDeleteOldDbs . bind ( this )
} ) ) , this . _db ;
}
}
class _e {
/ * *
* To construct a new CacheExpiration instance you must provide at least
* one of the ` config ` properties .
*
* @ param { string } cacheName Name of the cache to apply restrictions to .
* @ param { Object } config
* @ param { number } [ config . maxEntries ] The maximum number of entries to cache .
* Entries used the least will be removed as the maximum is reached .
* @ param { number } [ config . maxAgeSeconds ] The maximum age of an entry before
* it ' s treated as stale and removed .
* @ param { Object } [ config . matchOptions ] The [ ` CacheQueryOptions ` ] ( https : //developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)
* that will be used when calling ` delete() ` on the cache .
* /
constructor ( e , t = { } ) {
this . _isRunning = ! 1 , this . _rerunRequested = ! 1 , this . _maxEntries = t . maxEntries , this . _maxAgeSeconds = t . maxAgeSeconds , this . _matchOptions = t . matchOptions , this . _cacheName = e , this . _timestampModel = new ye ( e ) ;
}
/ * *
* Expires entries for the given cache and given criteria .
* /
async expireEntries ( ) {
if ( this . _isRunning ) {
this . _rerunRequested = ! 0 ;
return ;
}
this . _isRunning = ! 0 ;
const e = this . _maxAgeSeconds ? Date . now ( ) - this . _maxAgeSeconds * 1e3 : 0 , t = await this . _timestampModel . expireEntries ( e , this . _maxEntries ) , n = await self . caches . open ( this . _cacheName ) ;
for ( const a of t )
await n . delete ( a , this . _matchOptions ) ;
this . _isRunning = ! 1 , this . _rerunRequested && ( this . _rerunRequested = ! 1 , q ( this . expireEntries ( ) ) ) ;
}
/ * *
* Update the timestamp for the given URL . This ensures the when
* removing entries based on maximum entries , most recently used
* is accurate or when expiring , the timestamp is up - to - date .
*
* @ param { string } url
* /
async updateTimestamp ( e ) {
await this . _timestampModel . setTimestamp ( e , Date . now ( ) ) ;
}
/ * *
* Can be used to check if a URL has expired or not before it ' s used .
*
* This requires a look up from IndexedDB , so can be slow .
*
* Note : This method will not remove the cached entry , call
* ` expireEntries() ` to remove indexedDB and Cache entries .
*
* @ param { string } url
* @ return { boolean }
* /
async isURLExpired ( e ) {
if ( this . _maxAgeSeconds ) {
const t = await this . _timestampModel . getTimestamp ( e ) , n = Date . now ( ) - this . _maxAgeSeconds * 1e3 ;
return t !== void 0 ? t < n : ! 0 ;
} else
return ! 1 ;
}
/ * *
* Removes the IndexedDB object store used to keep track of cache expiration
* metadata .
* /
async delete ( ) {
this . _rerunRequested = ! 1 , await this . _timestampModel . expireEntries ( 1 / 0 ) ;
}
}
class be {
/ * *
* @ param { ExpirationPluginOptions } config
* @ param { number } [ config . maxEntries ] The maximum number of entries to cache .
* Entries used the least will be removed as the maximum is reached .
* @ param { number } [ config . maxAgeSeconds ] The maximum age of an entry before
* it ' s treated as stale and removed .
* @ param { Object } [ config . matchOptions ] The [ ` CacheQueryOptions ` ] ( https : //developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)
* that will be used when calling ` delete() ` on the cache .
* @ param { boolean } [ config . purgeOnQuotaError ] Whether to opt this cache in to
* automatic deletion if the available storage quota has been exceeded .
* /
constructor ( e = { } ) {
this . cachedResponseWillBeUsed = async ( { event : t , request : n , cacheName : a , cachedResponse : r } ) => {
if ( ! r )
return null ;
const i = this . _isResponseDateFresh ( r ) , c = this . _getCacheExpiration ( a ) ;
q ( c . expireEntries ( ) ) ;
const o = c . updateTimestamp ( n . url ) ;
if ( t )
try {
t . waitUntil ( o ) ;
} catch {
}
return i ? r : null ;
} , this . cacheDidUpdate = async ( { cacheName : t , request : n } ) => {
const a = this . _getCacheExpiration ( t ) ;
await a . updateTimestamp ( n . url ) , await a . expireEntries ( ) ;
} , this . _config = e , this . _maxAgeSeconds = e . maxAgeSeconds , this . _cacheExpirations = /* @__PURE__ */ new Map ( ) , e . purgeOnQuotaError && z ( ( ) => this . deleteCacheAndMetadata ( ) ) ;
}
/ * *
* A simple helper method to return a CacheExpiration instance for a given
* cache name .
*
* @ param { string } cacheName
* @ return { CacheExpiration }
*
* @ private
* /
_getCacheExpiration ( e ) {
if ( e === x . getRuntimeName ( ) )
throw new h ( "expire-custom-caches-only" ) ;
let t = this . _cacheExpirations . get ( e ) ;
return t || ( t = new _e ( e , this . _config ) , this . _cacheExpirations . set ( e , t ) ) , t ;
}
/ * *
* @ param { Response } cachedResponse
* @ return { boolean }
*
* @ private
* /
_isResponseDateFresh ( e ) {
if ( ! this . _maxAgeSeconds )
return ! 0 ;
const t = this . _getDateHeaderTimestamp ( e ) ;
if ( t === null )
return ! 0 ;
const n = Date . now ( ) ;
return t >= n - this . _maxAgeSeconds * 1e3 ;
}
/ * *
* This method will extract the data header and parse it into a useful
* value .
*
* @ param { Response } cachedResponse
* @ return { number | null }
*
* @ private
* /
_getDateHeaderTimestamp ( e ) {
if ( ! e . headers . has ( "date" ) )
return null ;
const t = e . headers . get ( "date" ) , a = new Date ( t ) . getTime ( ) ;
return isNaN ( a ) ? null : a ;
}
/ * *
* This is a helper method that performs two operations :
*
* - Deletes * all * the underlying Cache instances associated with this plugin
* instance , by calling caches . delete ( ) on your behalf .
* - Deletes the metadata from IndexedDB used to keep track of expiration
* details for each Cache instance .
*
* When using cache expiration , calling this method is preferable to calling
* ` caches.delete() ` directly , since this will ensure that the IndexedDB
* metadata is also cleanly removed and open IndexedDB instances are deleted .
*
* Note that if you ' re * not * using cache expiration for a given cache , calling
* ` caches.delete() ` and passing in the cache ' s name should be sufficient .
* There is no Workbox - specific method needed for cleanup in that case .
* /
async deleteCacheAndMetadata ( ) {
for ( const [ e , t ] of this . _cacheExpirations )
await self . caches . delete ( e ) , await t . delete ( ) ;
this . _cacheExpirations = /* @__PURE__ */ new Map ( ) ;
}
}
try {
self [ "workbox:precaching:7.0.0" ] && _ ( ) ;
} catch {
}
const Re = "__WB_REVISION__" ;
function Ce ( s ) {
if ( ! s )
throw new h ( "add-to-cache-list-unexpected-type" , { entry : s } ) ;
if ( typeof s == "string" ) {
const r = new URL ( s , location . href ) ;
return {
cacheKey : r . href ,
url : r . href
} ;
}
const { revision : e , url : t } = s ;
if ( ! t )
throw new h ( "add-to-cache-list-unexpected-type" , { entry : s } ) ;
if ( ! e ) {
const r = new URL ( t , location . href ) ;
return {
cacheKey : r . href ,
url : r . href
} ;
}
const n = new URL ( t , location . href ) , a = new URL ( t , location . href ) ;
return n . searchParams . set ( Re , e ) , {
cacheKey : n . href ,
url : a . href
} ;
}
class xe {
constructor ( ) {
this . updatedURLs = [ ] , this . notUpdatedURLs = [ ] , this . handlerWillStart = async ( { request : e , state : t } ) => {
t && ( t . originalRequest = e ) ;
} , this . cachedResponseWillBeUsed = async ( { event : e , state : t , cachedResponse : n } ) => {
if ( e . type === "install" && t && t . originalRequest && t . originalRequest instanceof Request ) {
const a = t . originalRequest . url ;
n ? this . notUpdatedURLs . push ( a ) : this . updatedURLs . push ( a ) ;
}
return n ;
} ;
}
}
class ke {
constructor ( { precacheController : e } ) {
this . cacheKeyWillBeUsed = async ( { request : t , params : n } ) => {
const a = ( n == null ? void 0 : n . cacheKey ) || this . _precacheController . getCacheKeyForURL ( t . url ) ;
return a ? new Request ( a , { headers : t . headers } ) : t ;
} , this . _precacheController = e ;
}
}
try {
self [ "workbox:strategies:7.0.0" ] && _ ( ) ;
} catch {
}
function R ( s ) {
return typeof s == "string" ? new Request ( s ) : s ;
}
class ve {
/ * *
* Creates a new instance associated with the passed strategy and event
* that ' s handling the request .
*
* The constructor also initializes the state that will be passed to each of
* the plugins handling this request .
*
* @ param { workbox - strategies . Strategy } strategy
* @ param { Object } options
* @ param { Request | string } options . request A request to run this strategy for .
* @ param { ExtendableEvent } options . event The event associated with the
* request .
* @ param { URL } [ options . url ]
* @ param { * } [ options . params ] The return value from the
* { @ link workbox - routing ~ matchCallback } ( if applicable ) .
* /
constructor ( e , t ) {
this . _cacheKeys = { } , Object . assign ( this , t ) , this . event = t . event , this . _strategy = e , this . _handlerDeferred = new Z ( ) , this . _extendLifetimePromises = [ ] , this . _plugins = [ ... e . plugins ] , this . _pluginStateMap = /* @__PURE__ */ new Map ( ) ;
for ( const n of this . _plugins )
this . _pluginStateMap . set ( n , { } ) ;
this . event . waitUntil ( this . _handlerDeferred . promise ) ;
}
/ * *
* Fetches a given request ( and invokes any applicable plugin callback
* methods ) using the ` fetchOptions ` ( for non - navigation requests ) and
* ` plugins ` defined on the ` Strategy ` object .
*
* The following plugin lifecycle methods are invoked when using this method :
* - ` requestWillFetch() `
* - ` fetchDidSucceed() `
* - ` fetchDidFail() `
*
* @ param { Request | string } input The URL or request to fetch .
* @ return { Promise < Response > }
* /
async fetch ( e ) {
const { event : t } = this ;
let n = R ( e ) ;
if ( n . mode === "navigate" && t instanceof FetchEvent && t . preloadResponse ) {
const i = await t . preloadResponse ;
if ( i )
return i ;
}
const a = this . hasCallback ( "fetchDidFail" ) ? n . clone ( ) : null ;
try {
for ( const i of this . iterateCallbacks ( "requestWillFetch" ) )
n = await i ( { request : n . clone ( ) , event : t } ) ;
} catch ( i ) {
if ( i instanceof Error )
throw new h ( "plugin-error-request-will-fetch" , {
thrownErrorMessage : i . message
} ) ;
}
const r = n . clone ( ) ;
try {
let i ;
i = await fetch ( n , n . mode === "navigate" ? void 0 : this . _strategy . fetchOptions ) ;
for ( const c of this . iterateCallbacks ( "fetchDidSucceed" ) )
i = await c ( {
event : t ,
request : r ,
response : i
} ) ;
return i ;
} catch ( i ) {
throw a && await this . runCallbacks ( "fetchDidFail" , {
error : i ,
event : t ,
originalRequest : a . clone ( ) ,
request : r . clone ( )
} ) , i ;
}
}
/ * *
* Calls ` this.fetch() ` and ( in the background ) runs ` this.cachePut() ` on
* the response generated by ` this.fetch() ` .
*
* The call to ` this.cachePut() ` automatically invokes ` this.waitUntil() ` ,
* so you do not have to manually call ` waitUntil() ` on the event .
*
* @ param { Request | string } input The request or URL to fetch and cache .
* @ return { Promise < Response > }
* /
async fetchAndCachePut ( e ) {
const t = await this . fetch ( e ) , n = t . clone ( ) ;
return this . waitUntil ( this . cachePut ( e , n ) ) , t ;
}
/ * *
* Matches a request from the cache ( and invokes any applicable plugin
* callback methods ) using the ` cacheName ` , ` matchOptions ` , and ` plugins `
* defined on the strategy object .
*
* The following plugin lifecycle methods are invoked when using this method :
* - cacheKeyWillByUsed ( )
* - cachedResponseWillByUsed ( )
*
* @ param { Request | string } key The Request or URL to use as the cache key .
* @ return { Promise < Response | undefined > } A matching response , if found .
* /
async cacheMatch ( e ) {
const t = R ( e ) ;
let n ;
const { cacheName : a , matchOptions : r } = this . _strategy , i = await this . getCacheKey ( t , "read" ) , c = Object . assign ( Object . assign ( { } , r ) , { cacheName : a } ) ;
n = await caches . match ( i , c ) ;
for ( const o of this . iterateCallbacks ( "cachedResponseWillBeUsed" ) )
n = await o ( {
cacheName : a ,
matchOptions : r ,
cachedResponse : n ,
request : i ,
event : this . event
} ) || void 0 ;
return n ;
}
/ * *
* Puts a request / response pair in the cache ( and invokes any applicable
* plugin callback methods ) using the ` cacheName ` and ` plugins ` defined on
* the strategy object .
*
* The following plugin lifecycle methods are invoked when using this method :
* - cacheKeyWillByUsed ( )
* - cacheWillUpdate ( )
* - cacheDidUpdate ( )
*
* @ param { Request | string } key The request or URL to use as the cache key .
* @ param { Response } response The response to cache .
* @ return { Promise < boolean > } ` false ` if a cacheWillUpdate caused the response
* not be cached , and ` true ` otherwise .
* /
async cachePut ( e , t ) {
const n = R ( e ) ;
await se ( 0 ) ;
const a = await this . getCacheKey ( n , "write" ) ;
if ( ! t )
throw new h ( "cache-put-with-no-response" , {
url : te ( a . url )
} ) ;
const r = await this . _ensureResponseSafeToCache ( t ) ;
if ( ! r )
return ! 1 ;
const { cacheName : i , matchOptions : c } = this . _strategy , o = await self . caches . open ( i ) , l = this . hasCallback ( "cacheDidUpdate" ) , g = l ? await X (
// TODO(philipwalton): the `__WB_REVISION__` param is a precaching
// feature. Consider into ways to only add this behavior if using
// precaching.
o ,
a . clone ( ) ,
[ "__WB_REVISION__" ] ,
c
) : null ;
try {
await o . put ( a , l ? r . clone ( ) : r ) ;
} catch ( u ) {
if ( u instanceof Error )
throw u . name === "QuotaExceededError" && await ee ( ) , u ;
}
for ( const u of this . iterateCallbacks ( "cacheDidUpdate" ) )
await u ( {
cacheName : i ,
oldResponse : g ,
newResponse : r . clone ( ) ,
request : a ,
event : this . event
} ) ;
return ! 0 ;
}
/ * *
* Checks the list of plugins for the ` cacheKeyWillBeUsed ` callback , and
* executes any of those callbacks found in sequence . The final ` Request `
* object returned by the last plugin is treated as the cache key for cache
* reads and / or writes . If no ` cacheKeyWillBeUsed ` plugin callbacks have
* been registered , the passed request is returned unmodified
*
* @ param { Request } request
* @ param { string } mode
* @ return { Promise < Request > }
* /
async getCacheKey ( e , t ) {
const n = ` ${ e . url } | ${ t } ` ;
if ( ! this . _cacheKeys [ n ] ) {
let a = e ;
for ( const r of this . iterateCallbacks ( "cacheKeyWillBeUsed" ) )
a = R ( await r ( {
mode : t ,
request : a ,
event : this . event ,
// params has a type any can't change right now.
params : this . params
// eslint-disable-line
} ) ) ;
this . _cacheKeys [ n ] = a ;
}
return this . _cacheKeys [ n ] ;
}
/ * *
* Returns true if the strategy has at least one plugin with the given
* callback .
*
* @ param { string } name The name of the callback to check for .
* @ return { boolean }
* /
hasCallback ( e ) {
for ( const t of this . _strategy . plugins )
if ( e in t )
return ! 0 ;
return ! 1 ;
}
/ * *
* Runs all plugin callbacks matching the given name , in order , passing the
* given param object ( merged ith the current plugin state ) as the only
* argument .
*
* Note : since this method runs all plugins , it ' s not suitable for cases
* where the return value of a callback needs to be applied prior to calling
* the next callback . See
* { @ link workbox - strategies . StrategyHandler # iterateCallbacks }
* below for how to handle that case .
*
* @ param { string } name The name of the callback to run within each plugin .
* @ param { Object } param The object to pass as the first ( and only ) param
* when executing each callback . This object will be merged with the
* current plugin state prior to callback execution .
* /
async runCallbacks ( e , t ) {
for ( const n of this . iterateCallbacks ( e ) )
await n ( t ) ;
}
/ * *
* Accepts a callback and returns an iterable of matching plugin callbacks ,
* where each callback is wrapped with the current handler state ( i . e . when
* you call each callback , whatever object parameter you pass it will
* be merged with the plugin ' s current state ) .
*
* @ param { string } name The name fo the callback to run
* @ return { Array < Function > }
* /
* iterateCallbacks ( e ) {
for ( const t of this . _strategy . plugins )
if ( typeof t [ e ] == "function" ) {
const n = this . _pluginStateMap . get ( t ) ;
yield ( r ) => {
const i = Object . assign ( Object . assign ( { } , r ) , { state : n } ) ;
return t [ e ] ( i ) ;
} ;
}
}
/ * *
* Adds a promise to the
* [ extend lifetime promises ] { @ link https : //w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises}
* of the event event associated with the request being handled ( usually a
* ` FetchEvent ` ) .
*
* Note : you can await
* { @ link workbox - strategies . StrategyHandler ~ doneWaiting }
* to know when all added promises have settled .
*
* @ param { Promise } promise A promise to add to the extend lifetime promises
* of the event that triggered the request .
* /
waitUntil ( e ) {
return this . _extendLifetimePromises . push ( e ) , e ;
}
/ * *
* Returns a promise that resolves once all promises passed to
* { @ link workbox - strategies . StrategyHandler ~ waitUntil }
* have settled .
*
* Note : any work done after ` doneWaiting() ` settles should be manually
* passed to an event 's `waitUntil()` method (not this handler' s
* ` waitUntil() ` method ) , otherwise the service worker thread my be killed
* prior to your work completing .
* /
async doneWaiting ( ) {
let e ;
for ( ; e = this . _extendLifetimePromises . shift ( ) ; )
await e ;
}
/ * *
* Stops running the strategy and immediately resolves any pending
* ` waitUntil() ` promises .
* /
destroy ( ) {
this . _handlerDeferred . resolve ( null ) ;
}
/ * *
* This method will call cacheWillUpdate on the available plugins ( or use
* status === 200 ) to determine if the Response is safe and valid to cache .
*
* @ param { Request } options . request
* @ param { Response } options . response
* @ return { Promise < Response | undefined > }
*
* @ private
* /
async _ensureResponseSafeToCache ( e ) {
let t = e , n = ! 1 ;
for ( const a of this . iterateCallbacks ( "cacheWillUpdate" ) )
if ( t = await a ( {
request : this . request ,
response : t ,
event : this . event
} ) || void 0 , n = ! 0 , ! t )
break ;
return n || t && t . status !== 200 && ( t = void 0 ) , t ;
}
}
class V {
/ * *
* Creates a new instance of the strategy and sets all documented option
* properties as public instance properties .
*
* Note : if a custom strategy class extends the base Strategy class and does
* not need more than these properties , it does not need to define its own
* constructor .
*
* @ param { Object } [ options ]
* @ param { string } [ options . cacheName ] Cache name to store and retrieve
* requests . Defaults to the cache names provided by
* { @ link workbox - core . cacheNames } .
* @ param { Array < Object > } [ options . plugins ] [ Plugins ] { @ link https : //developers.google.com/web/tools/workbox/guides/using-plugins}
* to use in conjunction with this caching strategy .
* @ param { Object } [ options . fetchOptions ] Values passed along to the
* [ ` init ` ] ( https : //developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
* of [ non - navigation ] ( https : //github.com/GoogleChrome/workbox/issues/1796)
* ` fetch() ` requests made by this strategy .
* @ param { Object } [ options . matchOptions ] The
* [ ` CacheQueryOptions ` ] { @ link https : //w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions}
* for any ` cache.match() ` or ` cache.put() ` calls made by this strategy .
* /
constructor ( e = { } ) {
this . cacheName = x . getRuntimeName ( e . cacheName ) , this . plugins = e . plugins || [ ] , this . fetchOptions = e . fetchOptions , this . matchOptions = e . matchOptions ;
}
/ * *
* Perform a request strategy and returns a ` Promise ` that will resolve with
* a ` Response ` , invoking all relevant plugin callbacks .
*
* When a strategy instance is registered with a Workbox
* { @ link workbox - routing . Route } , this method is automatically
* called when the route matches .
*
* Alternatively , this method can be used in a standalone ` FetchEvent `
* listener by passing it to ` event.respondWith() ` .
*
* @ param { FetchEvent | Object } options A ` FetchEvent ` or an object with the
* properties listed below .
* @ param { Request | string } options . request A request to run this strategy for .
* @ param { ExtendableEvent } options . event The event associated with the
* request .
* @ param { URL } [ options . url ]
* @ param { * } [ options . params ]
* /
handle ( e ) {
const [ t ] = this . handleAll ( e ) ;
return t ;
}
/ * *
* Similar to { @ link workbox - strategies . Strategy ~ handle } , but
* instead of just returning a ` Promise ` that resolves to a ` Response ` it
* it will return an tuple of ` [response, done] ` promises , where the former
* ( ` response ` ) is equivalent to what ` handle() ` returns , and the latter is a
* Promise that will resolve once any promises that were added to
* ` event.waitUntil() ` as part of performing the strategy have completed .
*
* You can await the ` done ` promise to ensure any extra work performed by
* the strategy ( usually caching responses ) completes successfully .
*
* @ param { FetchEvent | Object } options A ` FetchEvent ` or an object with the
* properties listed below .
* @ param { Request | string } options . request A request to run this strategy for .
* @ param { ExtendableEvent } options . event The event associated with the
* request .
* @ param { URL } [ options . url ]
* @ param { * } [ options . params ]
* @ return { Array < Promise > } A tuple of [ response , done ]
* promises that can be used to determine when the response resolves as
* well as when the handler has completed all its work .
* /
handleAll ( e ) {
e instanceof FetchEvent && ( e = {
event : e ,
request : e . request
} ) ;
const t = e . event , n = typeof e . request == "string" ? new Request ( e . request ) : e . request , a = "params" in e ? e . params : void 0 , r = new ve ( this , { event : t , request : n , params : a } ) , i = this . _getResponse ( r , n , t ) , c = this . _awaitComplete ( i , r , n , t ) ;
return [ i , c ] ;
}
async _getResponse ( e , t , n ) {
await e . runCallbacks ( "handlerWillStart" , { event : n , request : t } ) ;
let a ;
try {
if ( a = await this . _handle ( t , e ) , ! a || a . type === "error" )
throw new h ( "no-response" , { url : t . url } ) ;
} catch ( r ) {
if ( r instanceof Error ) {
for ( const i of e . iterateCallbacks ( "handlerDidError" ) )
if ( a = await i ( { error : r , event : n , request : t } ) , a )
break ;
}
if ( ! a )
throw r ;
}
for ( const r of e . iterateCallbacks ( "handlerWillRespond" ) )
a = await r ( { event : n , request : t , response : a } ) ;
return a ;
}
async _awaitComplete ( e , t , n , a ) {
let r , i ;
try {
r = await e ;
} catch {
}
try {
await t . runCallbacks ( "handlerDidRespond" , {
event : a ,
request : n ,
response : r
} ) , await t . doneWaiting ( ) ;
} catch ( c ) {
c instanceof Error && ( i = c ) ;
}
if ( await t . runCallbacks ( "handlerDidComplete" , {
event : a ,
request : n ,
response : r ,
error : i
} ) , t . destroy ( ) , i )
throw i ;
}
}
class p extends V {
/ * *
*
* @ param { Object } [ options ]
* @ param { string } [ options . cacheName ] Cache name to store and retrieve
* requests . Defaults to the cache names provided by
* { @ link workbox - core . cacheNames } .
* @ param { Array < Object > } [ options . plugins ] { @ link https : //developers.google.com/web/tools/workbox/guides/using-plugins|Plugins}
* to use in conjunction with this caching strategy .
* @ param { Object } [ options . fetchOptions ] Values passed along to the
* { @ link https : //developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init}
* of all fetch ( ) requests made by this strategy .
* @ param { Object } [ options . matchOptions ] The
* { @ link https : //w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions|CacheQueryOptions}
* for any ` cache.match() ` or ` cache.put() ` calls made by this strategy .
* @ param { boolean } [ options . fallbackToNetwork = true ] Whether to attempt to
* get the response from the network if there ' s a precache miss .
* /
constructor ( e = { } ) {
e . cacheName = x . getPrecacheName ( e . cacheName ) , super ( e ) , this . _fallbackToNetwork = e . fallbackToNetwork !== ! 1 , this . plugins . push ( p . copyRedirectedCacheableResponsesPlugin ) ;
}
/ * *
* @ private
* @ param { Request | string } request A request to run this strategy for .
* @ param { workbox - strategies . StrategyHandler } handler The event that
* triggered the request .
* @ return { Promise < Response > }
* /
async _handle ( e , t ) {
const n = await t . cacheMatch ( e ) ;
return n || ( t . event && t . event . type === "install" ? await this . _handleInstall ( e , t ) : await this . _handleFetch ( e , t ) ) ;
}
async _handleFetch ( e , t ) {
let n ;
const a = t . params || { } ;
if ( this . _fallbackToNetwork ) {
const r = a . integrity , i = e . integrity , c = ! i || i === r ;
n = await t . fetch ( new Request ( e , {
integrity : e . mode !== "no-cors" ? i || r : void 0
} ) ) , r && c && e . mode !== "no-cors" && ( this . _useDefaultCacheabilityPluginIfNeeded ( ) , await t . cachePut ( e , n . clone ( ) ) ) ;
} else
throw new h ( "missing-precache-entry" , {
cacheName : this . cacheName ,
url : e . url
} ) ;
return n ;
}
async _handleInstall ( e , t ) {
this . _useDefaultCacheabilityPluginIfNeeded ( ) ;
const n = await t . fetch ( e ) ;
if ( ! await t . cachePut ( e , n . clone ( ) ) )
throw new h ( "bad-precaching-response" , {
url : e . url ,
status : n . status
} ) ;
return n ;
}
/ * *
* This method is complex , as there a number of things to account for :
*
* The ` plugins ` array can be set at construction , and / or it might be added to
* to at any time before the strategy is used .
*
* At the time the strategy is used ( i . e . during an ` install ` event ) , there
* needs to be at least one plugin that implements ` cacheWillUpdate ` in the
* array , other than ` copyRedirectedCacheableResponsesPlugin ` .
*
* - If this method is called and there are no suitable ` cacheWillUpdate `
* plugins , we need to add ` defaultPrecacheCacheabilityPlugin ` .
*
* - If this method is called and there is exactly one ` cacheWillUpdate ` , then
* we don ' t have to do anything ( this might be a previously added
* ` defaultPrecacheCacheabilityPlugin ` , or it might be a custom plugin ) .
*
* - If this method is called and there is more than one ` cacheWillUpdate ` ,
* then we need to check if one is ` defaultPrecacheCacheabilityPlugin ` . If so ,
* we need to remove it . ( This situation is unlikely , but it could happen if
* the strategy is used multiple times , the first without a ` cacheWillUpdate ` ,
* and then later on after manually adding a custom ` cacheWillUpdate ` . )
*
* See https : //github.com/GoogleChrome/workbox/issues/2737 for more context.
*
* @ private
* /
_useDefaultCacheabilityPluginIfNeeded ( ) {
let e = null , t = 0 ;
for ( const [ n , a ] of this . plugins . entries ( ) )
a !== p . copyRedirectedCacheableResponsesPlugin && ( a === p . defaultPrecacheCacheabilityPlugin && ( e = n ) , a . cacheWillUpdate && t ++ ) ;
t === 0 ? this . plugins . push ( p . defaultPrecacheCacheabilityPlugin ) : t > 1 && e !== null && this . plugins . splice ( e , 1 ) ;
}
}
p . defaultPrecacheCacheabilityPlugin = {
async cacheWillUpdate ( { response : s } ) {
return ! s || s . status >= 400 ? null : s ;
}
} ;
p . copyRedirectedCacheableResponsesPlugin = {
async cacheWillUpdate ( { response : s } ) {
return s . redirected ? await ne ( s ) : s ;
}
} ;
class Ee {
/ * *
* Create a new PrecacheController .
*
* @ param { Object } [ options ]
* @ param { string } [ options . cacheName ] The cache to use for precaching .
* @ param { string } [ options . plugins ] Plugins to use when precaching as well
* as responding to fetch events for precached assets .
* @ param { boolean } [ options . fallbackToNetwork = true ] Whether to attempt to
* get the response from the network if there ' s a precache miss .
* /
constructor ( { cacheName : e , plugins : t = [ ] , fallbackToNetwork : n = ! 0 } = { } ) {
this . _urlsToCacheKeys = /* @__PURE__ */ new Map ( ) , this . _urlsToCacheModes = /* @__PURE__ */ new Map ( ) , this . _cacheKeysToIntegrities = /* @__PURE__ */ new Map ( ) , this . _strategy = new p ( {
cacheName : x . getPrecacheName ( e ) ,
plugins : [
... t ,
new ke ( { precacheController : this } )
] ,
fallbackToNetwork : n
} ) , this . install = this . install . bind ( this ) , this . activate = this . activate . bind ( this ) ;
}
/ * *
* @ type { workbox - precaching . PrecacheStrategy } The strategy created by this controller and
* used to cache assets and respond to fetch events .
* /
get strategy ( ) {
return this . _strategy ;
}
/ * *
* Adds items to the precache list , removing any duplicates and
* stores the files in the
* { @ link workbox - core . cacheNames | "precache cache" } when the service
* worker installs .
*
* This method can be called multiple times .
*
* @ param { Array < Object | string > } [ entries = [ ] ] Array of entries to precache .
* /
precache ( e ) {
this . addToCacheList ( e ) , this . _installAndActiveListenersAdded || ( self . addEventListener ( "install" , this . install ) , self . addEventListener ( "activate" , this . activate ) , this . _installAndActiveListenersAdded = ! 0 ) ;
}
/ * *
* This method will add items to the precache list , removing duplicates
* and ensuring the information is valid .
*
* @ param { Array < workbox - precaching . PrecacheController . PrecacheEntry | string > } entries
* Array of entries to precache .
* /
addToCacheList ( e ) {
const t = [ ] ;
for ( const n of e ) {
typeof n == "string" ? t . push ( n ) : n && n . revision === void 0 && t . push ( n . url ) ;
const { cacheKey : a , url : r } = Ce ( n ) , i = typeof n != "string" && n . revision ? "reload" : "default" ;
if ( this . _urlsToCacheKeys . has ( r ) && this . _urlsToCacheKeys . get ( r ) !== a )
throw new h ( "add-to-cache-list-conflicting-entries" , {
firstEntry : this . _urlsToCacheKeys . get ( r ) ,
secondEntry : a
} ) ;
if ( typeof n != "string" && n . integrity ) {
if ( this . _cacheKeysToIntegrities . has ( a ) && this . _cacheKeysToIntegrities . get ( a ) !== n . integrity )
throw new h ( "add-to-cache-list-conflicting-integrities" , {
url : r
} ) ;
this . _cacheKeysToIntegrities . set ( a , n . integrity ) ;
}
if ( this . _urlsToCacheKeys . set ( r , a ) , this . _urlsToCacheModes . set ( r , i ) , t . length > 0 ) {
const c = ` Workbox is precaching URLs without revision info: ${ t . join ( ", " ) }
This is generally NOT safe . Learn more at https : //bit.ly/wb-precache`;
console . warn ( c ) ;
}
}
}
/ * *
* Precaches new and updated assets . Call this method from the service worker
* install event .
*
* Note : this method calls ` event.waitUntil() ` for you , so you do not need
* to call it yourself in your event handlers .
*
* @ param { ExtendableEvent } event
* @ return { Promise < workbox - precaching . InstallResult > }
* /
install ( e ) {
return A ( e , async ( ) => {
const t = new xe ( ) ;
this . strategy . plugins . push ( t ) ;
for ( const [ r , i ] of this . _urlsToCacheKeys ) {
const c = this . _cacheKeysToIntegrities . get ( i ) , o = this . _urlsToCacheModes . get ( r ) , l = new Request ( r , {
integrity : c ,
cache : o ,
credentials : "same-origin"
} ) ;
await Promise . all ( this . strategy . handleAll ( {
params : { cacheKey : i } ,
request : l ,
event : e
} ) ) ;
}
const { updatedURLs : n , notUpdatedURLs : a } = t ;
return { updatedURLs : n , notUpdatedURLs : a } ;
} ) ;
}
/ * *
* Deletes assets that are no longer present in the current precache manifest .
* Call this method from the service worker activate event .
*
* Note : this method calls ` event.waitUntil() ` for you , so you do not need
* to call it yourself in your event handlers .
*
* @ param { ExtendableEvent } event
* @ return { Promise < workbox - precaching . CleanupResult > }
* /
activate ( e ) {
return A ( e , async ( ) => {
const t = await self . caches . open ( this . strategy . cacheName ) , n = await t . keys ( ) , a = new Set ( this . _urlsToCacheKeys . values ( ) ) , r = [ ] ;
for ( const i of n )
a . has ( i . url ) || ( await t . delete ( i ) , r . push ( i . url ) ) ;
return { deletedURLs : r } ;
} ) ;
}
/ * *
* Returns a mapping of a precached URL to the corresponding cache key , taking
* into account the revision information for the URL .
*
* @ return { Map < string , string > } A URL to cache key mapping .
* /
getURLsToCacheKeys ( ) {
return this . _urlsToCacheKeys ;
}
/ * *
* Returns a list of all the URLs that have been precached by the current
* service worker .
*
* @ return { Array < string > } The precached URLs .
* /
getCachedURLs ( ) {
return [ ... this . _urlsToCacheKeys . keys ( ) ] ;
}
/ * *
* Returns the cache key used for storing a given URL . If that URL is
* unversioned , like ` /index.html', then the cache key will be the original
* URL with a search parameter appended to it .
*
* @ param { string } url A URL whose cache key you want to look up .
* @ return { string } The versioned URL that corresponds to a cache key
* for the original URL , or undefined if that URL isn ' t precached .
* /
getCacheKeyForURL ( e ) {
const t = new URL ( e , location . href ) ;
return this . _urlsToCacheKeys . get ( t . href ) ;
}
/ * *
* @ param { string } url A cache key whose SRI you want to look up .
* @ return { string } The subresource integrity associated with the cache key ,
* or undefined if it ' s not set .
* /
getIntegrityForCacheKey ( e ) {
return this . _cacheKeysToIntegrities . get ( e ) ;
}
/ * *
* This acts as a drop - in replacement for
* [ ` cache.match() ` ] ( https : //developer.mozilla.org/en-US/docs/Web/API/Cache/match)
* with the following differences :
*
* - It knows what the name of the precache is , and only checks in that cache .
* - It allows you to pass in an "original" URL without versioning parameters ,
* and it will automatically look up the correct cache key for the currently
* active revision of that URL .
*
* E . g . , ` matchPrecache('index.html') ` will find the correct precached
* response for the currently active service worker , even if the actual cache
* key is ` '/index.html?__WB_REVISION__=1234abcd' ` .
*
* @ param { string | Request } request The key ( without revisioning parameters )
* to look up in the precache .
* @ return { Promise < Response | undefined > }
* /
async matchPrecache ( e ) {
const t = e instanceof Request ? e . url : e , n = this . getCacheKeyForURL ( t ) ;
if ( n )
return ( await self . caches . open ( this . strategy . cacheName ) ) . match ( n ) ;
}
/ * *
* Returns a function that looks up ` url ` in the precache ( taking into
* account revision information ) , and returns the corresponding ` Response ` .
*
* @ param { string } url The precached URL which will be used to lookup the
* ` Response ` .
* @ return { workbox - routing ~ handlerCallback }
* /
createHandlerBoundToURL ( e ) {
const t = this . getCacheKeyForURL ( e ) ;
if ( ! t )
throw new h ( "non-precached-url" , { url : e } ) ;
return ( n ) => ( n . request = new Request ( e ) , n . params = Object . assign ( { cacheKey : t } , n . params ) , this . strategy . handle ( n ) ) ;
}
}
let L ;
const I = ( ) => ( L || ( L = new Ee ( ) ) , L ) ;
try {
self [ "workbox:routing:7.0.0" ] && _ ( ) ;
} catch {
}
const $ = "GET" , C = ( s ) => s && typeof s == "object" ? s : { handle : s } ;
class b {
/ * *
* Constructor for Route class .
*
* @ param { workbox - routing ~ matchCallback } match
* A callback function that determines whether the route matches a given
* ` fetch ` event by returning a non - falsy value .
* @ param { workbox - routing ~ handlerCallback } handler A callback
* function that returns a Promise resolving to a Response .
* @ param { string } [ method = 'GET' ] The HTTP method to match the Route
* against .
* /
constructor ( e , t , n = $ ) {
this . handler = C ( t ) , this . match = e , this . method = n ;
}
/ * *
*
* @ param { workbox - routing - handlerCallback } handler A callback
* function that returns a Promise resolving to a Response
* /
setCatchHandler ( e ) {
this . catchHandler = C ( e ) ;
}
}
class De extends b {
/ * *
* If the regular expression contains
* [ capture groups ] { @ link https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references},
* the captured values will be passed to the
* { @ link workbox - routing ~ handlerCallback } ` params `
* argument .
*
* @ param { RegExp } regExp The regular expression to match against URLs .
* @ param { workbox - routing ~ handlerCallback } handler A callback
* function that returns a Promise resulting in a Response .
* @ param { string } [ method = 'GET' ] The HTTP method to match the Route
* against .
* /
constructor ( e , t , n ) {
const a = ( { url : r } ) => {
const i = e . exec ( r . href ) ;
if ( i && ! ( r . origin !== location . origin && i . index !== 0 ) )
return i . slice ( 1 ) ;
} ;
super ( a , t , n ) ;
}
}
class Le {
/ * *
* Initializes a new Router .
* /
constructor ( ) {
this . _routes = /* @__PURE__ */ new Map ( ) , this . _defaultHandlerMap = /* @__PURE__ */ new Map ( ) ;
}
/ * *
* @ return { Map < string , Array < workbox - routing . Route >> } routes A ` Map ` of HTTP
* method name ( 'GET' , etc . ) to an array of all the corresponding ` Route `
* instances that are registered .
* /
get routes ( ) {
return this . _routes ;
}
/ * *
* Adds a fetch event listener to respond to events when a route matches
* the event ' s request .
* /
addFetchListener ( ) {
self . addEventListener ( "fetch" , ( e ) => {
const { request : t } = e , n = this . handleRequest ( { request : t , event : e } ) ;
n && e . respondWith ( n ) ;
} ) ;
}
/ * *
* Adds a message event listener for URLs to cache from the window .
* This is useful to cache resources loaded on the page prior to when the
* service worker started controlling it .
*
* The format of the message data sent from the window should be as follows .
* Where the ` urlsToCache ` array may consist of URL strings or an array of
* URL string + ` requestInit ` object ( the same as you ' d pass to ` fetch() ` ) .
*
* ` ` `
* {
* type : 'CACHE_URLS' ,
* payload : {
* urlsToCache : [
* './script1.js' ,
* './script2.js' ,
* [ './script3.js' , { mode : 'no-cors' } ] ,
* ] ,
* } ,
* }
* ` ` `
* /
addCacheListener ( ) {
self . addEventListener ( "message" , ( e ) => {
if ( e . data && e . data . type === "CACHE_URLS" ) {
const { payload : t } = e . data , n = Promise . all ( t . urlsToCache . map ( ( a ) => {
typeof a == "string" && ( a = [ a ] ) ;
const r = new Request ( ... a ) ;
return this . handleRequest ( { request : r , event : e } ) ;
} ) ) ;
e . waitUntil ( n ) , e . ports && e . ports [ 0 ] && n . then ( ( ) => e . ports [ 0 ] . postMessage ( ! 0 ) ) ;
}
} ) ;
}
/ * *
* Apply the routing rules to a FetchEvent object to get a Response from an
* appropriate Route ' s handler .
*
* @ param { Object } options
* @ param { Request } options . request The request to handle .
* @ param { ExtendableEvent } options . event The event that triggered the
* request .
* @ return { Promise < Response > | undefined } A promise is returned if a
* registered route can handle the request . If there is no matching
* route and there ' s no ` defaultHandler ` , ` undefined ` is returned .
* /
handleRequest ( { request : e , event : t } ) {
const n = new URL ( e . url , location . href ) ;
if ( ! n . protocol . startsWith ( "http" ) )
return ;
const a = n . origin === location . origin , { params : r , route : i } = this . findMatchingRoute ( {
event : t ,
request : e ,
sameOrigin : a ,
url : n
} ) ;
let c = i && i . handler ;
const o = e . method ;
if ( ! c && this . _defaultHandlerMap . has ( o ) && ( c = this . _defaultHandlerMap . get ( o ) ) , ! c )
return ;
let l ;
try {
l = c . handle ( { url : n , request : e , event : t , params : r } ) ;
} catch ( u ) {
l = Promise . reject ( u ) ;
}
const g = i && i . catchHandler ;
return l instanceof Promise && ( this . _catchHandler || g ) && ( l = l . catch ( async ( u ) => {
if ( g )
try {
return await g . handle ( { url : n , request : e , event : t , params : r } ) ;
} catch ( N ) {
N instanceof Error && ( u = N ) ;
}
if ( this . _catchHandler )
return this . _catchHandler . handle ( { url : n , request : e , event : t } ) ;
throw u ;
} ) ) , l ;
}
/ * *
* Checks a request and URL ( and optionally an event ) against the list of
* registered routes , and if there ' s a match , returns the corresponding
* route along with any params generated by the match .
*
* @ param { Object } options
* @ param { URL } options . url
* @ param { boolean } options . sameOrigin The result of comparing ` url.origin `
* against the current origin .
* @ param { Request } options . request The request to match .
* @ param { Event } options . event The corresponding event .
* @ return { Object } An object with ` route ` and ` params ` properties .
* They are populated if a matching route was found or ` undefined `
* otherwise .
* /
findMatchingRoute ( { url : e , sameOrigin : t , request : n , event : a } ) {
const r = this . _routes . get ( n . method ) || [ ] ;
for ( const i of r ) {
let c ;
const o = i . match ( { url : e , sameOrigin : t , request : n , event : a } ) ;
if ( o )
return c = o , ( Array . isArray ( c ) && c . length === 0 || o . constructor === Object && // eslint-disable-line
Object . keys ( o ) . length === 0 || typeof o == "boolean" ) && ( c = void 0 ) , { route : i , params : c } ;
}
return { } ;
}
/ * *
* Define a default ` handler ` that ' s called when no routes explicitly
* match the incoming request .
*
* Each HTTP method ( 'GET' , 'POST' , etc . ) gets its own default handler .
*
* Without a default handler , unmatched requests will go against the
* network as if there were no service worker present .
*
* @ param { workbox - routing ~ handlerCallback } handler A callback
* function that returns a Promise resulting in a Response .
* @ param { string } [ method = 'GET' ] The HTTP method to associate with this
* default handler . Each method has its own default .
* /
setDefaultHandler ( e , t = $ ) {
this . _defaultHandlerMap . set ( t , C ( e ) ) ;
}
/ * *
* If a Route throws an error while handling a request , this ` handler `
* will be called and given a chance to provide a response .
*
* @ param { workbox - routing ~ handlerCallback } handler A callback
* function that returns a Promise resulting in a Response .
* /
setCatchHandler ( e ) {
this . _catchHandler = C ( e ) ;
}
/ * *
* Registers a route with the router .
*
* @ param { workbox - routing . Route } route The route to register .
* /
registerRoute ( e ) {
this . _routes . has ( e . method ) || this . _routes . set ( e . method , [ ] ) , this . _routes . get ( e . method ) . push ( e ) ;
}
/ * *
* Unregisters a route with the router .
*
* @ param { workbox - routing . Route } route The route to unregister .
* /
unregisterRoute ( e ) {
if ( ! this . _routes . has ( e . method ) )
throw new h ( "unregister-route-but-not-found-with-method" , {
method : e . method
} ) ;
const t = this . _routes . get ( e . method ) . indexOf ( e ) ;
if ( t > - 1 )
this . _routes . get ( e . method ) . splice ( t , 1 ) ;
else
throw new h ( "unregister-route-route-not-registered" ) ;
}
}
let y ;
const Ue = ( ) => ( y || ( y = new Le ( ) , y . addFetchListener ( ) , y . addCacheListener ( ) ) , y ) ;
function M ( s , e , t ) {
let n ;
if ( typeof s == "string" ) {
const r = new URL ( s , location . href ) , i = ( { url : c } ) => c . href === r . href ;
n = new b ( i , e , t ) ;
} else if ( s instanceof RegExp )
n = new De ( s , e , t ) ;
else if ( typeof s == "function" )
n = new b ( s , e , t ) ;
else if ( s instanceof b )
n = s ;
else
throw new h ( "unsupported-route-type" , {
moduleName : "workbox-routing" ,
funcName : "registerRoute" ,
paramName : "capture"
} ) ;
return Ue ( ) . registerRoute ( n ) , n ;
}
function Te ( s , e = [ ] ) {
for ( const t of [ ... s . searchParams . keys ( ) ] )
e . some ( ( n ) => n . test ( t ) ) && s . searchParams . delete ( t ) ;
return s ;
}
function * Pe ( s , { ignoreURLParametersMatching : e = [ /^utm_/ , /^fbclid$/ ] , directoryIndex : t = "index.html" , cleanURLs : n = ! 0 , urlManipulation : a } = { } ) {
const r = new URL ( s , location . href ) ;
r . hash = "" , yield r . href ;
const i = Te ( r , e ) ;
if ( yield i . href , t && i . pathname . endsWith ( "/" ) ) {
const c = new URL ( i . href ) ;
c . pathname += t , yield c . href ;
}
if ( n ) {
const c = new URL ( i . href ) ;
c . pathname += ".html" , yield c . href ;
}
if ( a ) {
const c = a ( { url : r } ) ;
for ( const o of c )
yield o . href ;
}
}
class Ie extends b {
/ * *
* @ param { PrecacheController } precacheController A ` PrecacheController `
* instance used to both match requests and respond to fetch events .
* @ param { Object } [ options ] Options to control how requests are matched
* against the list of precached URLs .
* @ param { string } [ options . directoryIndex = index . html ] The ` directoryIndex ` will
* check cache entries for a URLs ending with '/' to see if there is a hit when
* appending the ` directoryIndex ` value .
* @ param { Array < RegExp > } [ options . ignoreURLParametersMatching = [ /^utm_/ , /^fbclid$/ ] ] An
* array of regex ' s to remove search params when looking for a cache match .
* @ param { boolean } [ options . cleanURLs = true ] The ` cleanURLs ` option will
* check the cache for the URL with a ` .html ` added to the end of the end .
* @ param { workbox - precaching ~ urlManipulation } [ options . urlManipulation ]
* This is a function that should take a URL and return an array of
* alternative URLs that should be checked for precache matches .
* /
constructor ( e , t ) {
const n = ( { request : a } ) => {
const r = e . getURLsToCacheKeys ( ) ;
for ( const i of Pe ( a . url , t ) ) {
const c = r . get ( i ) ;
if ( c ) {
const o = e . getIntegrityForCacheKey ( c ) ;
return { cacheKey : c , integrity : o } ;
}
}
} ;
super ( n , e . strategy ) ;
}
}
function Me ( s ) {
const e = I ( ) , t = new Ie ( e , s ) ;
M ( t ) ;
}
function Ne ( s ) {
return I ( ) . createHandlerBoundToURL ( s ) ;
}
function Ke ( s ) {
I ( ) . precache ( s ) ;
}
function Ae ( s , e ) {
Ke ( s ) , Me ( e ) ;
}
const je = {
/ * *
* Returns a valid response ( to allow caching ) if the status is 200 ( OK ) or
* 0 ( opaque ) .
*
* @ param { Object } options
* @ param { Response } options . response
* @ return { Response | null }
*
* @ private
* /
cacheWillUpdate : async ( { response : s } ) => s . status === 200 || s . status === 0 ? s : null
} ;
class Oe extends V {
/ * *
* @ param { Object } [ options ]
* @ param { string } [ options . cacheName ] Cache name to store and retrieve
* requests . Defaults to cache names provided by
* { @ link workbox - core . cacheNames } .
* @ param { Array < Object > } [ options . plugins ] [ Plugins ] { @ link https : //developers.google.com/web/tools/workbox/guides/using-plugins}
* to use in conjunction with this caching strategy .
* @ param { Object } [ options . fetchOptions ] Values passed along to the
* [ ` init ` ] ( https : //developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
* of [ non - navigation ] ( https : //github.com/GoogleChrome/workbox/issues/1796)
* ` fetch() ` requests made by this strategy .
* @ param { Object } [ options . matchOptions ] [ ` CacheQueryOptions ` ] ( https : //w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)
* /
constructor ( e = { } ) {
super ( e ) , this . plugins . some ( ( t ) => "cacheWillUpdate" in t ) || this . plugins . unshift ( je ) ;
}
/ * *
* @ private
* @ param { Request | string } request A request to run this strategy for .
* @ param { workbox - strategies . StrategyHandler } handler The event that
* triggered the request .
* @ return { Promise < Response > }
* /
async _handle ( e , t ) {
const n = t . fetchAndCachePut ( e ) . catch ( ( ) => {
} ) ;
t . waitUntil ( n ) ;
let a = await t . cacheMatch ( e ) , r ;
if ( ! a )
try {
a = await n ;
} catch ( i ) {
i instanceof Error && ( r = i ) ;
}
if ( ! a )
throw new h ( "no-response" , { url : e . url , error : r } ) ;
return a ;
}
}
const Se = "shlink-web-client" , We = "A React-based progressive web application for shlink" , Be = "/shlink-web-client/dependabot/npm_and_yarn/vite-plugin-pwa-0.17.4" , qe = "https://github.com/shlinkio/shlink-web-client" , Fe = "MIT" , He = {
lint : "npm run lint:css && npm run lint:js" ,
"lint:css" : "stylelint src/*.scss src/**/*.scss" ,
"lint:js" : "eslint --ext .js,.ts,.tsx src test" ,
"lint:fix" : "npm run lint:css:fix && npm run lint:js:fix" ,
"lint:css:fix" : "npm run lint:css -- --fix" ,
"lint:js:fix" : "npm run lint:js -- --fix" ,
types : "tsc" ,
start : "vite serve --host=0.0.0.0" ,
preview : "vite preview --host=0.0.0.0" ,
build : "npm run types && vite build && node scripts/replace-version.mjs" ,
"build:dist" : "npm run build && node scripts/create-dist-file.mjs" ,
test : "vitest run --run" ,
"test:watch" : "vitest --watch" ,
"test:ci" : "npm run test -- --coverage" ,
"test:verbose" : "npm run test -- --verbose"
} , Ve = {
"@fortawesome/fontawesome-free" : "^6.5.1" ,
"@fortawesome/fontawesome-svg-core" : "^6.5.1" ,
"@fortawesome/free-brands-svg-icons" : "^6.5.1" ,
"@fortawesome/free-regular-svg-icons" : "^6.5.1" ,
"@fortawesome/free-solid-svg-icons" : "^6.5.1" ,
"@fortawesome/react-fontawesome" : "^0.2.0" ,
"@json2csv/plainjs" : "^7.0.3" ,
2023-12-10 21:39:08 +03:00
"@reduxjs/toolkit" : "^2.0.1" ,
2023-12-09 11:43:51 +03:00
"@shlinkio/data-manipulation" : "^1.0.2" ,
"@shlinkio/shlink-frontend-kit" : "^0.4.0" ,
"@shlinkio/shlink-js-sdk" : "^0.2.0" ,
2023-12-10 21:39:08 +03:00
"@shlinkio/shlink-web-component" : "^0.4.1" ,
2023-12-09 11:43:51 +03:00
bootstrap : "5.2.3" ,
bottlejs : "^2.0.1" ,
clsx : "^2.0.0" ,
"compare-versions" : "^6.1.0" ,
csvtojson : "^2.0.10" ,
"date-fns" : "^2.30.0" ,
react : "^18.2.0" ,
"react-dom" : "^18.2.0" ,
"react-external-link" : "^2.2.0" ,
2023-12-10 21:39:08 +03:00
"react-redux" : "^9.0.2" ,
"react-router-dom" : "^6.20.1" ,
2023-12-09 11:43:51 +03:00
reactstrap : "^9.2.1" ,
"redux-localstorage-simple" : "^2.5.1" ,
uuid : "^9.0.1" ,
"workbox-core" : "^7.0.0" ,
"workbox-expiration" : "^7.0.0" ,
"workbox-precaching" : "^7.0.0" ,
"workbox-routing" : "^7.0.0" ,
"workbox-strategies" : "^7.0.0"
} , $e = {
"@shlinkio/eslint-config-js-coding-standard" : "~2.3.0" ,
"@shlinkio/stylelint-config-css-coding-standard" : "~1.1.1" ,
2023-12-10 21:39:40 +03:00
"@testing-library/jest-dom" : "^6.1.5" ,
2023-12-09 11:43:51 +03:00
"@testing-library/react" : "^14.1.2" ,
"@testing-library/user-event" : "^14.5.1" ,
"@total-typescript/shoehorn" : "^0.1.1" ,
2023-12-10 21:42:12 +03:00
"@types/react" : "^18.2.43" ,
2023-12-09 11:43:51 +03:00
"@types/react-dom" : "^18.2.17" ,
"@types/uuid" : "^9.0.7" ,
2023-12-10 21:42:12 +03:00
"@vitejs/plugin-react" : "^4.2.1" ,
2023-12-10 21:39:08 +03:00
"@vitest/coverage-v8" : "^1.0.4" ,
2023-12-09 11:43:51 +03:00
"adm-zip" : "^0.5.10" ,
"axe-core" : "^4.8.2" ,
chalk : "^5.3.0" ,
2023-12-10 21:39:40 +03:00
eslint : "^8.55.0" ,
2023-12-09 11:43:51 +03:00
history : "^5.3.0" ,
2023-12-10 21:39:08 +03:00
jsdom : "^23.0.1" ,
2023-12-09 11:43:51 +03:00
sass : "^1.69.5" ,
stylelint : "^15.11.0" ,
2023-12-10 21:39:08 +03:00
typescript : "^5.3.3" ,
2023-12-10 21:42:12 +03:00
vite : "^5.0.7" ,
2023-12-09 11:43:51 +03:00
"vite-plugin-pwa" : "^0.17.4" ,
2023-12-10 21:39:08 +03:00
vitest : "^1.0.4"
2023-12-09 11:43:51 +03:00
} , Ge = [
">0.2%" ,
"not dead" ,
"not ie <= 11" ,
"not op_mini all"
] , Qe = {
name : Se ,
description : We ,
private : ! 1 ,
homepage : Be ,
repository : qe ,
license : Fe ,
scripts : He ,
dependencies : Ve ,
devDependencies : $e ,
browserslist : Ge
} ;
ae ( ) ;
2023-12-10 21:42:12 +03:00
Ae ( [ { "revision" : null , "url" : "assets/index-AwN06v9-.js" } , { "revision" : null , "url" : "assets/index-oITpymb_.css" } , { "revision" : "8359343bdc61cc4e9795d12fa09fd026" , "url" : "index.html" } , { "revision" : "3e8169a112865ef0d76bba4e2dfd3a89" , "url" : "./icons/icon-16x16.png" } , { "revision" : "20f0b51945ae3c973420e31d6b4d43c1" , "url" : "./icons/icon-24x24.png" } , { "revision" : "4c9695cfb4cea403c1b66bbb7b4f7420" , "url" : "./icons/icon-32x32.png" } , { "revision" : "f74edb9cc54ac938c1589876f8da9f21" , "url" : "./icons/icon-40x40.png" } , { "revision" : "52933970fac8498311687de13549b014" , "url" : "./icons/icon-48x48.png" } , { "revision" : "40209a194f29b21882571c77bd2bd906" , "url" : "./icons/icon-60x60.png" } , { "revision" : "c8ba5a8c1da76d74c7bb21827fcf975c" , "url" : "./icons/icon-64x64.png" } , { "revision" : "ae3435baceb494f9c966e2c2c736ea35" , "url" : "./icons/icon-72x72.png" } , { "revision" : "850aa5b026fd1452af6c1ddd9d71850f" , "url" : "./icons/icon-76x76.png" } , { "revision" : "8c62535e6b7a498ece1f6c6ae62ede59" , "url" : "./icons/icon-96x96.png" } , { "revision" : "2dff586aaefa4c8d17f4c0bcbdef8b53" , "url" : "./icons/icon-114x114.png" } , { "revision" : "8e28257a68ef1c55bc68bfff80e1a310" , "url" : "./icons/icon-120x120.png" } , { "revision" : "0059b6f0c97fa871a5c29643b2857585" , "url" : "./icons/icon-128x128.png" } , { "revision" : "41478c2456281f61e54d714718743ecc" , "url" : "./icons/icon-144x144.png" } , { "revision" : "625251910295f33a578ae6d8117711c9" , "url" : "./icons/icon-150x150.png" } , { "revision" : "19b71508b1d05defe32cf16a7d453001" , "url" : "./icons/icon-152x152.png" } , { "revision" : "9d029a32a54ba3084c67acd5d74f8ac4" , "url" : "./icons/icon-160x160.png" } , { "revision" : "6ec104aeaf745f003ecdaef2edddce97" , "url" : "./icons/icon-167x167.png" } , { "revision" : "871d67907434ed0ddf5d2a6c220e09af" , "url" : "./icons/icon-180x180.png" } , { "revision" : "cee2529402074d73b2135e2ddee25f6b" , "url" : "./icons/icon-192x192.png" } , { "revision" : "85055b452284c0193142936dee7d2cd1" , "url" : "./icons/icon-196x196.png" } , { "revision" : "f471155dd70b99924422dd9dd87ea94d" , "url" : "./icons/icon-228x228.png" } , { "revision" : "4d896c5c7025582605de31fb74f0316b" , "url" : "./icons/icon-256x256.png" } , { "revision" : "d99b49e5bcad41968313c3e132e7c661" , "url" : "./icons/icon-310x310.png" } , { "revision" : "f9597636bef677327c3abc0fd1a743c4" , "url" : "./icons/icon-384x384.png" } , { "revision" : "de22c0eb9e08d3576df5cedb568ca56b" , "url" : "./icons/icon-512x512.png" } , { "revision" : "583b223ad8e20f05aaa64923d7db2e46" , "url" : "./icons/icon-1024x1024.png" } , { "revision" : "3b59bde722ca304fb1fd76129ece0be8" , "url" : "manifest.json" } ] ) ;
2023-12-09 11:43:51 +03:00
const ze = new RegExp ( "/[^/?]+\\.[^/]+$" ) ;
M (
// Return false to exempt requests from being fulfilled by index.html.
( { request : s , url : e } ) => ! ( s . mode !== "navigate" || e . pathname . startsWith ( "/_" ) || e . pathname . match ( ze ) ) ,
Ne ( ` ${ Qe . homepage } /index.html ` )
) ;
M (
// Add in any other file extensions or routing criteria as needed.
( { url : s } ) => s . origin === self . location . origin && s . pathname . endsWith ( ".png" ) ,
// Customize this strategy as needed, e.g., by changing to CacheFirst.
new Oe ( {
cacheName : "images" ,
plugins : [
// Ensure that once this runtime cache reaches a maximum size the
// least-recently used images are removed.
new be ( { maxEntries : 50 } )
]
} )
) ;
self . addEventListener ( "message" , ( s ) => {
s . data && s . data . type === "SKIP_WAITING" && self . skipWaiting ( ) ;
} ) ;