mirror of
https://github.com/twbs/bootstrap.git
synced 2024-12-12 00:08:59 +01:00
1 line
276 KiB
Plaintext
1 line
276 KiB
Plaintext
{"version":3,"file":"workbox-sw.prod.v2.1.0.js","sources":["../../../../lib/error-factory.js","../../src/lib/error-factory.js","../../../workbox-routing/src/lib/error-factory.js","../../../../lib/error-stack-parser-no-op.js","../../../../lib/assert.js","../../../workbox-routing/src/lib/normalize-handler.js","../../../workbox-routing/src/lib/constants.js","../../../workbox-routing/src/lib/route.js","../../../../node_modules/path-to-regexp/node_modules/isarray/index.js","../../../../node_modules/path-to-regexp/index.js","../../../workbox-routing/src/lib/express-route.js","../../../../lib/log-group.js","../../../../lib/environment.js","../../../../lib/log-helper.js","../../../workbox-routing/src/lib/navigation-route.js","../../../workbox-routing/src/lib/regexp-route.js","../../../workbox-routing/src/lib/router.js","../../src/lib/router.js","../../../workbox-runtime-caching/src/lib/error-factory.js","../../../workbox-cacheable-response/src/lib/cacheable-response.js","../../../workbox-cacheable-response/src/lib/cacheable-response-plugin.js","../../../workbox-runtime-caching/src/lib/constants.js","../../../workbox-runtime-caching/src/lib/clean-response-copy.js","../../../workbox-runtime-caching/src/lib/request-wrapper.js","../../../workbox-runtime-caching/src/lib/handler.js","../../../workbox-runtime-caching/src/lib/cache-first.js","../../../workbox-runtime-caching/src/lib/cache-only.js","../../../workbox-runtime-caching/src/lib/network-first.js","../../../workbox-runtime-caching/src/lib/network-only.js","../../../workbox-runtime-caching/src/lib/stale-while-revalidate.js","../../../workbox-cache-expiration/src/lib/constants.js","../../../../node_modules/idb/lib/idb.js","../../../workbox-cache-expiration/src/lib/error-factory.js","../../../workbox-cache-expiration/src/lib/cache-expiration.js","../../../workbox-cache-expiration/src/lib/cache-expiration-plugin.js","../../../workbox-broadcast-cache-update/src/lib/error-factory.js","../../../workbox-broadcast-cache-update/src/lib/constants.js","../../../workbox-broadcast-cache-update/src/lib/broadcast-update.js","../../../workbox-broadcast-cache-update/src/lib/responses-are-same.js","../../../workbox-broadcast-cache-update/src/lib/broadcast-cache-update.js","../../../workbox-broadcast-cache-update/src/lib/broadcast-cache-update-plugin.js","../../src/lib/strategies.js","../../../../lib/error-message-factory-no-op.js","../../../../lib/workbox-error.js","../../../workbox-precaching/src/lib/controllers/base-cache-manager.js","../../../../lib/idb-helper.js","../../../workbox-precaching/src/lib/constants.js","../../../workbox-precaching/src/lib/models/revision-details-model.js","../../../workbox-precaching/src/lib/models/precache-entries/base-precache-entry.js","../../../workbox-precaching/src/lib/models/precache-entries/string-cache-entry.js","../../../workbox-precaching/src/lib/models/precache-entries/object-precache-entry.js","../../../workbox-precaching/src/lib/controllers/revisioned-cache-manager.js","../../../workbox-precaching/src/index.js","../../src/lib/workbox-sw.js"],"sourcesContent":["/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n'use strict';\n\n/**\n * A simple class to make errors and to help with testing.\n */\nclass ErrorFactory {\n /**\n * @param {Object} errors A object containing key value pairs where the key\n * is the error name / ID and the value is the error message.\n */\n constructor(errors) {\n this._errors = errors;\n }\n /**\n * @param {string} name The error name to be generated.\n * @param {Error} [thrownError] The thrown error that resulted in this\n * message.\n * @return {Error} The generated error.\n */\n createError(name, thrownError) {\n if (!(name in this._errors)) {\n throw new Error(`Unable to generate error '${name}'.`);\n }\n\n let message = this._errors[name].replace(/\\s+/g, ' ');\n let stack = null;\n if (thrownError) {\n message += ` [${thrownError.message}]`;\n stack = thrownError.stack;\n }\n\n const generatedError = new Error();\n generatedError.name = name;\n generatedError.message = message;\n generatedError.stack = stack;\n return generatedError;\n }\n}\n\nexport default ErrorFactory;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport ErrorFactory from '../../../../lib/error-factory';\n\nconst errors = {\n 'not-in-sw': 'workbox-sw must be loaded in your service worker file.',\n 'unsupported-route-type': 'The first parameter to registerRoute() should be' +\n ' either an Express-style path string, a RegExp, or a function.',\n 'empty-express-string': 'The Express style route string must have some ' +\n 'characters, an empty string is invalid.',\n 'bad-revisioned-cache-list': `The 'precache()' method expects` +\n `an array of revisioned urls like so: ['/example/hello.1234.txt', ` +\n `{path: 'hello.txt', revision: '1234'}]`,\n 'navigation-route-url-string': `The registerNavigationRoute() method ` +\n `expects a URL string as its first parameter.`,\n 'bad-cache-id': `The 'cacheId' parameter must be a string with at least ` +\n `one character`,\n 'bad-skip-waiting': `The 'skipWaiting' parameter must be a boolean.`,\n 'bad-clients-claim': `The 'clientsClaim' parameter must be a boolean.`,\n 'bad-directory-index': `The 'directoryIndex' parameter must be a boolean.`,\n};\n\nexport default new ErrorFactory(errors);\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport ErrorFactory from '../../../../lib/error-factory';\n\nconst errors = {\n 'express-route-invalid-path': `When using ExpressRoute, you must\n provide a path that starts with a '/' character (to match same-origin\n requests) or that starts with 'http' (to match cross-origin requests)`,\n};\n\nexport default new ErrorFactory(errors);\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/**\n * A no-op export matching the ErrorStackParser interface, to be included in\n * production, minified builds.\n */\nexport default {\n parse: () => [],\n};\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/* eslint-disable require-jsdoc */\n\nimport ErrorStackParser from 'error-stack-parser';\n\nexport function atLeastOne(object) {\n const parameters = Object.keys(object);\n if (!parameters.some((parameter) => object[parameter] !== undefined)) {\n throwError('Please set at least one of the following parameters: ' +\n parameters.map((p) => `'${p}'`).join(', '));\n }\n}\n\nexport function hasMethod(object, expectedMethod) {\n const parameter = Object.keys(object).pop();\n const type = typeof object[parameter][expectedMethod];\n if (type !== 'function') {\n throwError(`The '${parameter}' parameter must be an object that exposes a\n '${expectedMethod}' method.`);\n }\n}\n\nexport function isInstance(object, expectedClass) {\n const parameter = Object.keys(object).pop();\n if (!(object[parameter] instanceof expectedClass)) {\n throwError(`The '${parameter}' parameter must be an instance of\n '${expectedClass.name}'`);\n }\n}\n\nexport function isOneOf(object, values) {\n const parameter = Object.keys(object).pop();\n if (!values.includes(object[parameter])) {\n throwError(`The '${parameter}' parameter must be set to one of the\n following: ${values}`);\n }\n}\n\nexport function isType(object, expectedType) {\n const parameter = Object.keys(object).pop();\n const actualType = typeof object[parameter];\n if (actualType !== expectedType) {\n throwError(`The '${parameter}' parameter has the wrong type. (Expected:\n ${expectedType}, actual: ${actualType})`);\n }\n}\n\nexport function isArrayOfType(object, expectedType) {\n const parameter = Object.keys(object).pop();\n const message = `The '${parameter}' parameter should be an array containing\n one or more '${expectedType}' elements.`;\n\n if (!Array.isArray(object[parameter])) {\n throwError(message);\n }\n\n for (let item of object[parameter]) {\n if (typeof item !== expectedType) {\n throwError(message);\n }\n }\n}\n\nexport function isArrayOfClass(object, expectedClass) {\n const parameter = Object.keys(object).pop();\n const message = `The '${parameter}' parameter should be an array containing\n one or more '${expectedClass.name}' instances.`;\n\n if (!Array.isArray(object[parameter])) {\n throwError(message);\n }\n\n for (let item of object[parameter]) {\n if (!(item instanceof expectedClass)) {\n throwError(message);\n }\n }\n}\n\nexport function isValue(object, expectedValue) {\n const parameter = Object.keys(object).pop();\n const actualValue = object[parameter];\n if (actualValue !== expectedValue) {\n throwError(`The '${parameter}' parameter has the wrong value. (Expected:\n ${expectedValue}, actual: ${actualValue})`);\n }\n}\n\nfunction throwError(message) {\n // Collapse any newlines or whitespace into a single space.\n message = message.replace(/\\s+/g, ' ');\n\n const error = new Error(message);\n error.name = 'assertion-failed';\n\n const stackFrames = ErrorStackParser.parse(error);\n\n // If, for some reason, we don't have all the stack information we need,\n // we'll just end up throwing a basic Error.\n if (stackFrames.length >= 3) {\n // Assuming we have the stack frames, set the message to include info\n // about what the underlying method was, and set the name to reflect\n // the assertion type that failed.\n error.message = `Invalid call to ${stackFrames[2].functionName}() — ` +\n message;\n }\n\n throw error;\n}\n","import {hasMethod, isType} from '../../../../lib/assert';\n\n/**\n * @param {function|module:workbox-runtime-caching.Handler} handler The\n * handler to normalize.\n * @return {Object} An object with a `handle` property representing the handler\n * function.\n *\n * @private\n */\nexport default function normalizeHandler(handler) {\n if (typeof handler === 'object') {\n hasMethod({handler}, 'handle');\n return handler;\n } else {\n isType({handler}, 'function');\n return {handle: handler};\n }\n}\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/**\n * The default HTTP method, 'GET', used when there's no specific method\n * configured for a route.\n *\n * @private\n * @type {string}\n * @memberof module:workbox-routing\n */\nexport const defaultMethod = 'GET';\n\n/**\n * The list of valid HTTP methods associated with requests that could be routed.\n *\n * @private\n * @type {Array.<string>}\n * @memberof module:workbox-routing\n */\nexport const validMethods = [\n 'DELETE',\n 'GET',\n 'HEAD',\n 'POST',\n 'PUT',\n];\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport {isType, isOneOf} from '../../../../lib/assert';\nimport normalizeHandler from './normalize-handler';\nimport {defaultMethod, validMethods} from './constants';\n\n/**\n * This is the definition of the `match` callback passed into the\n * `Route` constructor.\n *\n * This callback is used to determine if a new `fetch` event can be served\n * by this `Route`. Returning a truthy value indicates that this `Route` can\n * handle this `fetch` event. Return `null` if this shouldn't match against\n * the `fetch` event.\n *\n * If you do return a truthy value, the object will be passed to the\n * Route's `handler` (see the\n * [Route Constructor]{@link module:workbox-routing.Route}).\n *\n * @callback Route~matchCallback\n * @param {Object} input\n * @param {URL} input.url The request's URL.\n * @param {FetchEvent} input.event The event that triggered the `fetch` handler.\n * @return {Object|null} To signify a match, return a truthy value, otherwise\n * return null if the route shouldn't match. If you return an Object with\n * contents it will be passed to the `handler` in the `Route` constructor.\n * @memberof module:workbox-routing\n */\n\n/**\n * This is the definition of the `handler` callback that can be passed into the\n * `Route` constructor.\n *\n * The `handler` callback is called when a request has been matched by\n * a `Route` and should return a Promise that resolves with a `Response`.\n *\n * @callback Route~handlerCallback\n * @param {Object} input\n * @param {URL} input.url The request's URL.\n * @param {FetchEvent} input.event The event that triggered the `fetch` handler.\n * @param {Object} [input.params] Parameters returned\n * the Route's [match callback]{@link\n * module:workbox-routing.Route~matchCallback} function. This will be\n * undefined if nothing was returned.\n * @return {Promise<Response>} The response that will fulfill the request.\n * @memberof module:workbox-routing\n */\n\n/**\n * A `Route` allows you to tell a service worker that it should handle\n * certain network requests using a specific response strategy.\n *\n * A consists or a matcher and a handler. A matcher needs to determine if a\n * route should be used for a request. A handler should handle the request\n * if it does match a Router.\n *\n * Instead of implementing your own handlers, you can use one of the\n * pre-defined runtime caching strategies from the\n * {@link module:workbox-runtime-caching|workbox-runtime-caching} module.\n *\n * There are also pre-defined Route's provided by this library:\n * {@link module:workbox-routing.RegExpRoute|RegExpRoute}\n * and {@link module:workbox-routing.ExpressRoute|ExpressRoute} subclasses\n * which provide a convenient wrapper with a nicer interface for using regular\n * expressions or Express-style routes as the `match` criteria.\n *\n * @example\n * // Any navigate requests for URLs that start with /path/to/ will match.\n * const route = new workbox.routing.Route({\n * match: ({url, event}) => {\n * return event.request.mode === 'navigate' &&\n * url.pathname.startsWith('/path/to/');\n * },\n * handler: ({event}) => {\n * // Do something that returns a Promise.<Response>, like:\n * return caches.match(event.request);\n * },\n * });\n *\n * const router = new workbox.routing.Router();\n * router.registerRoute({route});\n *\n * @memberof module:workbox-routing\n */\nclass Route {\n /**\n * Constructor for Route class.\n * @param {Object} input\n * @param {function} input.match The function that determines whether the\n * route matches a given `fetch` event.\n *\n * See [matchCallback]{@link module:workbox-routing.Route~matchCallback} for\n * full details on this function.\n * @param {function|module:workbox-runtime-caching.Handler} input.handler\n * This parameter can be either a function or an object which is a subclass\n * of `Handler`.\n *\n * Either option should result in a `Response` that the `Route` can use to\n * handle the `fetch` event.\n *\n * See [handlerCallback]{@link module:workbox-routing.Route~handlerCallback}\n * for full details on using a callback function as the `handler`.\n * @param {string} [input.method] Only match requests that use this\n * HTTP method.\n *\n * Defaults to `'GET'`.\n */\n constructor({match, handler, method} = {}) {\n this.handler = normalizeHandler(handler);\n\n isType({match}, 'function');\n this.match = match;\n\n if (method) {\n isOneOf({method}, validMethods);\n this.method = method;\n } else {\n this.method = defaultMethod;\n }\n }\n}\n\nexport default Route;\n","module.exports = Array.isArray || function (arr) {\n return Object.prototype.toString.call(arr) == '[object Array]';\n};\n","var isarray = require('isarray')\n\n/**\n * Expose `pathToRegexp`.\n */\nmodule.exports = pathToRegexp\nmodule.exports.parse = parse\nmodule.exports.compile = compile\nmodule.exports.tokensToFunction = tokensToFunction\nmodule.exports.tokensToRegExp = tokensToRegExp\n\n/**\n * The main path matching regexp utility.\n *\n * @type {RegExp}\n */\nvar PATH_REGEXP = new RegExp([\n // Match escaped characters that would otherwise appear in future matches.\n // This allows the user to escape special characters that won't transform.\n '(\\\\\\\\.)',\n // Match Express-style parameters and un-named parameters with a prefix\n // and optional suffixes. Matches appear as:\n //\n // \"/:test(\\\\d+)?\" => [\"/\", \"test\", \"\\d+\", undefined, \"?\", undefined]\n // \"/route(\\\\d+)\" => [undefined, undefined, undefined, \"\\d+\", undefined, undefined]\n // \"/*\" => [\"/\", undefined, undefined, undefined, undefined, \"*\"]\n '([\\\\/.])?(?:(?:\\\\:(\\\\w+)(?:\\\\(((?:\\\\\\\\.|[^\\\\\\\\()])+)\\\\))?|\\\\(((?:\\\\\\\\.|[^\\\\\\\\()])+)\\\\))([+*?])?|(\\\\*))'\n].join('|'), 'g')\n\n/**\n * Parse a string for the raw tokens.\n *\n * @param {string} str\n * @param {Object=} options\n * @return {!Array}\n */\nfunction parse (str, options) {\n var tokens = []\n var key = 0\n var index = 0\n var path = ''\n var defaultDelimiter = options && options.delimiter || '/'\n var res\n\n while ((res = PATH_REGEXP.exec(str)) != null) {\n var m = res[0]\n var escaped = res[1]\n var offset = res.index\n path += str.slice(index, offset)\n index = offset + m.length\n\n // Ignore already escaped sequences.\n if (escaped) {\n path += escaped[1]\n continue\n }\n\n var next = str[index]\n var prefix = res[2]\n var name = res[3]\n var capture = res[4]\n var group = res[5]\n var modifier = res[6]\n var asterisk = res[7]\n\n // Push the current path onto the tokens.\n if (path) {\n tokens.push(path)\n path = ''\n }\n\n var partial = prefix != null && next != null && next !== prefix\n var repeat = modifier === '+' || modifier === '*'\n var optional = modifier === '?' || modifier === '*'\n var delimiter = res[2] || defaultDelimiter\n var pattern = capture || group\n\n tokens.push({\n name: name || key++,\n prefix: prefix || '',\n delimiter: delimiter,\n optional: optional,\n repeat: repeat,\n partial: partial,\n asterisk: !!asterisk,\n pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')\n })\n }\n\n // Match any characters still remaining.\n if (index < str.length) {\n path += str.substr(index)\n }\n\n // If the path exists, push it onto the end.\n if (path) {\n tokens.push(path)\n }\n\n return tokens\n}\n\n/**\n * Compile a string to a template function for the path.\n *\n * @param {string} str\n * @param {Object=} options\n * @return {!function(Object=, Object=)}\n */\nfunction compile (str, options) {\n return tokensToFunction(parse(str, options))\n}\n\n/**\n * Prettier encoding of URI path segments.\n *\n * @param {string}\n * @return {string}\n */\nfunction encodeURIComponentPretty (str) {\n return encodeURI(str).replace(/[\\/?#]/g, function (c) {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase()\n })\n}\n\n/**\n * Encode the asterisk parameter. Similar to `pretty`, but allows slashes.\n *\n * @param {string}\n * @return {string}\n */\nfunction encodeAsterisk (str) {\n return encodeURI(str).replace(/[?#]/g, function (c) {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase()\n })\n}\n\n/**\n * Expose a method for transforming tokens into the path function.\n */\nfunction tokensToFunction (tokens) {\n // Compile all the tokens into regexps.\n var matches = new Array(tokens.length)\n\n // Compile all the patterns before compilation.\n for (var i = 0; i < tokens.length; i++) {\n if (typeof tokens[i] === 'object') {\n matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$')\n }\n }\n\n return function (obj, opts) {\n var path = ''\n var data = obj || {}\n var options = opts || {}\n var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent\n\n for (var i = 0; i < tokens.length; i++) {\n var token = tokens[i]\n\n if (typeof token === 'string') {\n path += token\n\n continue\n }\n\n var value = data[token.name]\n var segment\n\n if (value == null) {\n if (token.optional) {\n // Prepend partial segment prefixes.\n if (token.partial) {\n path += token.prefix\n }\n\n continue\n } else {\n throw new TypeError('Expected \"' + token.name + '\" to be defined')\n }\n }\n\n if (isarray(value)) {\n if (!token.repeat) {\n throw new TypeError('Expected \"' + token.name + '\" to not repeat, but received `' + JSON.stringify(value) + '`')\n }\n\n if (value.length === 0) {\n if (token.optional) {\n continue\n } else {\n throw new TypeError('Expected \"' + token.name + '\" to not be empty')\n }\n }\n\n for (var j = 0; j < value.length; j++) {\n segment = encode(value[j])\n\n if (!matches[i].test(segment)) {\n throw new TypeError('Expected all \"' + token.name + '\" to match \"' + token.pattern + '\", but received `' + JSON.stringify(segment) + '`')\n }\n\n path += (j === 0 ? token.prefix : token.delimiter) + segment\n }\n\n continue\n }\n\n segment = token.asterisk ? encodeAsterisk(value) : encode(value)\n\n if (!matches[i].test(segment)) {\n throw new TypeError('Expected \"' + token.name + '\" to match \"' + token.pattern + '\", but received \"' + segment + '\"')\n }\n\n path += token.prefix + segment\n }\n\n return path\n }\n}\n\n/**\n * Escape a regular expression string.\n *\n * @param {string} str\n * @return {string}\n */\nfunction escapeString (str) {\n return str.replace(/([.+*?=^!:${}()[\\]|\\/\\\\])/g, '\\\\$1')\n}\n\n/**\n * Escape the capturing group by escaping special characters and meaning.\n *\n * @param {string} group\n * @return {string}\n */\nfunction escapeGroup (group) {\n return group.replace(/([=!:$\\/()])/g, '\\\\$1')\n}\n\n/**\n * Attach the keys as a property of the regexp.\n *\n * @param {!RegExp} re\n * @param {Array} keys\n * @return {!RegExp}\n */\nfunction attachKeys (re, keys) {\n re.keys = keys\n return re\n}\n\n/**\n * Get the flags for a regexp from the options.\n *\n * @param {Object} options\n * @return {string}\n */\nfunction flags (options) {\n return options.sensitive ? '' : 'i'\n}\n\n/**\n * Pull out keys from a regexp.\n *\n * @param {!RegExp} path\n * @param {!Array} keys\n * @return {!RegExp}\n */\nfunction regexpToRegexp (path, keys) {\n // Use a negative lookahead to match only capturing groups.\n var groups = path.source.match(/\\((?!\\?)/g)\n\n if (groups) {\n for (var i = 0; i < groups.length; i++) {\n keys.push({\n name: i,\n prefix: null,\n delimiter: null,\n optional: false,\n repeat: false,\n partial: false,\n asterisk: false,\n pattern: null\n })\n }\n }\n\n return attachKeys(path, keys)\n}\n\n/**\n * Transform an array into a regexp.\n *\n * @param {!Array} path\n * @param {Array} keys\n * @param {!Object} options\n * @return {!RegExp}\n */\nfunction arrayToRegexp (path, keys, options) {\n var parts = []\n\n for (var i = 0; i < path.length; i++) {\n parts.push(pathToRegexp(path[i], keys, options).source)\n }\n\n var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))\n\n return attachKeys(regexp, keys)\n}\n\n/**\n * Create a path regexp from string input.\n *\n * @param {string} path\n * @param {!Array} keys\n * @param {!Object} options\n * @return {!RegExp}\n */\nfunction stringToRegexp (path, keys, options) {\n return tokensToRegExp(parse(path, options), keys, options)\n}\n\n/**\n * Expose a function for taking tokens and returning a RegExp.\n *\n * @param {!Array} tokens\n * @param {(Array|Object)=} keys\n * @param {Object=} options\n * @return {!RegExp}\n */\nfunction tokensToRegExp (tokens, keys, options) {\n if (!isarray(keys)) {\n options = /** @type {!Object} */ (keys || options)\n keys = []\n }\n\n options = options || {}\n\n var strict = options.strict\n var end = options.end !== false\n var route = ''\n\n // Iterate over the tokens and create our regexp string.\n for (var i = 0; i < tokens.length; i++) {\n var token = tokens[i]\n\n if (typeof token === 'string') {\n route += escapeString(token)\n } else {\n var prefix = escapeString(token.prefix)\n var capture = '(?:' + token.pattern + ')'\n\n keys.push(token)\n\n if (token.repeat) {\n capture += '(?:' + prefix + capture + ')*'\n }\n\n if (token.optional) {\n if (!token.partial) {\n capture = '(?:' + prefix + '(' + capture + '))?'\n } else {\n capture = prefix + '(' + capture + ')?'\n }\n } else {\n capture = prefix + '(' + capture + ')'\n }\n\n route += capture\n }\n }\n\n var delimiter = escapeString(options.delimiter || '/')\n var endsWithDelimiter = route.slice(-delimiter.length) === delimiter\n\n // In non-strict mode we allow a slash at the end of match. If the path to\n // match already ends with a slash, we remove it for consistency. The slash\n // is valid at the end of a path match, not in the middle. This is important\n // in non-ending mode, where \"/test/\" shouldn't match \"/test//route\".\n if (!strict) {\n route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?'\n }\n\n if (end) {\n route += '$'\n } else {\n // In non-ending mode, we need the capturing groups to match as much as\n // possible by using a positive lookahead to the end or next path segment.\n route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)'\n }\n\n return attachKeys(new RegExp('^' + route, flags(options)), keys)\n}\n\n/**\n * Normalize the given path string, returning a regular expression.\n *\n * An empty array can be passed in for the keys, which will hold the\n * placeholder key descriptions. For example, using `/user/:id`, `keys` will\n * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.\n *\n * @param {(string|RegExp|Array)} path\n * @param {(Array|Object)=} keys\n * @param {Object=} options\n * @return {!RegExp}\n */\nfunction pathToRegexp (path, keys, options) {\n if (!isarray(keys)) {\n options = /** @type {!Object} */ (keys || options)\n keys = []\n }\n\n options = options || {}\n\n if (path instanceof RegExp) {\n return regexpToRegexp(path, /** @type {!Array} */ (keys))\n }\n\n if (isarray(path)) {\n return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)\n }\n\n return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)\n}\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport ErrorFactory from './error-factory';\nimport Route from './route';\nimport pathToRegExp from 'path-to-regexp';\n\n/**\n * `ExpressRoute` is a helper class to make defining Express-style\n * [Routes]{@link module:workbox-routing.Route} easy.\n *\n * Under the hood, it uses the [`path-to-regexp`](https://www.npmjs.com/package/path-to-regexp)\n * library to transform the `path` parameter into a regular expression, which is\n * then matched against the URL's path.\n *\n * Please note that `ExpressRoute` can match either same-origin or cross-origin\n * requests.\n *\n * To match same-origin requests, use a `path` value that begins with\n * `'/'`, e.g. `'/path/to/:file'`.\n *\n * To match cross-origin requests, use a `path` value that includes the origin,\n * e.g. `'https://example.com/path/to/:file'`.\n *\n * @example\n * // Any same-origin requests that start with /path/to and end with one\n * // additional path segment will match this route, with the last path\n * // segment passed along to the handler via params.file.\n * const route = new workbox.routing.ExpressRoute({\n * path: '/path/to/:file',\n * handler: ({event, params}) => {\n * // params.file will be set based on the request URL that matched.\n * return caches.match(params.file);\n * },\n * });\n *\n * const router = new workbox.routing.Router();\n * router.registerRoute({route});\n *\n * @example\n * // Any cross-origin requests for https://example.com will match this route.\n * const route = new workbox.routing.ExpressRoute({\n * path: 'https://example.com/path/to/:file',\n * handler: ({event}) => return caches.match(event.request),\n * });\n *\n * const router = new workbox.routing.Router();\n * router.registerRoute({route});\n *\n * @memberof module:workbox-routing\n * @extends Route\n */\nclass ExpressRoute extends Route {\n /**\n * Constructor for ExpressRoute.\n *\n * @param {Object} input\n * @param {String} input.path The path to use for routing.\n * If the path contains [named parameters](https://github.com/pillarjs/path-to-regexp#named-parameters),\n * then an Object that maps parameter names to their corresponding value\n * will be passed to the handler via `params`.\n * @param {function|module:workbox-runtime-caching.Handler} input.handler The\n * handler to use to provide a response if the route matches.\n *\n * If you wish to use a callback function [see handlerCallback]{@link\n * module:workbox-routing.Route~handlerCallback} for the callback\n * definition.\n * @param {string} [input.method] Only match requests that use this\n * HTTP method.\n *\n * Defaults to `'GET'`.\n */\n constructor({path, handler, method}) {\n if (!(path.startsWith('/') || path.startsWith('http'))) {\n throw ErrorFactory.createError('express-route-invalid-path');\n }\n\n let keys = [];\n // keys is populated as a side effect of pathToRegExp. This isn't the nicest\n // API, but so it goes.\n // https://github.com/pillarjs/path-to-regexp#usage\n const regExp = pathToRegExp(path, keys);\n const match = ({url}) => {\n // A path starting with '/' is a signal that we only want to match\n // same-origin. Bail out early if needed.\n if (path.startsWith('/') && url.origin !== location.origin) {\n return null;\n }\n\n // We need to match on either just the pathname or the full URL, depending\n // on whether the path parameter starts with '/' or 'http'.\n const pathNameOrHref = path.startsWith('/') ? url.pathname : url.href;\n const regexpMatches = pathNameOrHref.match(regExp);\n // Return null immediately if this route doesn't match.\n if (!regexpMatches) {\n return null;\n }\n\n // If the route does match, then collect values for all the named\n // parameters that were returned in keys.\n // If there are no named parameters then this will end up returning {},\n // which is truthy, and therefore a sufficient return value.\n const namedParamsToValues = {};\n keys.forEach((key, index) => {\n namedParamsToValues[key.name] = regexpMatches[index + 1];\n });\n\n return namedParamsToValues;\n };\n\n super({match, handler, method});\n }\n}\n\nexport default ExpressRoute;\n","/* eslint-disable no-console */\n\n/**\n * A simple helper to manage the print of a set of logs\n */\nclass LogGroup {\n /**\n * @param {object} input\n */\n constructor() {\n this._logs = [];\n this._childGroups = [];\n\n this._isFallbackMode = false;\n const ffRegex = /Firefox\\/(\\d*)\\.\\d*/.exec(navigator.userAgent);\n if (ffRegex) {\n try {\n const ffVersion = parseInt(ffRegex[1], 10);\n if (ffVersion < 55) {\n this._isFallbackMode = true;\n }\n } catch (err) {\n this._isFallbackMode = true;\n }\n }\n\n if (/Edge\\/\\d*\\.\\d*/.exec(navigator.userAgent)) {\n this._isFallbackMode = true;\n }\n }\n\n /**\n *@param {object} logDetails\n */\n addPrimaryLog(logDetails) {\n this._primaryLog = logDetails;\n }\n\n /**\n *@param {object} logDetails\n */\n addLog(logDetails) {\n this._logs.push(logDetails);\n }\n\n /**\n * @param {object} group\n */\n addChildGroup(group) {\n if (group._logs.length === 0) {\n return;\n }\n\n this._childGroups.push(group);\n }\n\n /**\n * prints out this log group to the console.\n */\n print() {\n if (this._logs.length === 0 && this._childGroups.length === 0) {\n this._printLogDetails(this._primaryLog);\n return;\n }\n\n if (this._primaryLog) {\n if (!this._isFallbackMode) {\n console.groupCollapsed(...this._getLogContent(this._primaryLog));\n } else {\n this._printLogDetails(this._primaryLog);\n }\n }\n\n this._logs.forEach((logDetails) => {\n this._printLogDetails(logDetails);\n });\n\n this._childGroups.forEach((group) => {\n group.print();\n });\n\n if (this._primaryLog && !this._isFallbackMode) {\n console.groupEnd();\n }\n }\n\n /**\n * Prints the specific logDetails object.\n * @param {object} logDetails\n */\n _printLogDetails(logDetails) {\n const logFunc = logDetails.logFunc ? logDetails.logFunc : console.log;\n logFunc(...this._getLogContent(logDetails));\n }\n\n /**\n * Returns a flattened array of message with colors and args.\n * @param {object} logDetails\n * @return {Array} Returns an array of arguments to pass to a console\n * function.\n */\n _getLogContent(logDetails) {\n let message = logDetails.message;\n if (this._isFallbackMode && typeof message === 'string') {\n // Replace the %c value with an empty string.\n message = message.replace(/%c/g, '');\n }\n\n let allArguments = [message];\n\n if (!this._isFallbackMode && logDetails.colors) {\n allArguments = allArguments.concat(logDetails.colors);\n }\n\n if (logDetails.args) {\n allArguments = allArguments.concat(logDetails.args);\n }\n return allArguments;\n }\n}\n\nexport default LogGroup;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/**\n * @private\n * @return {boolean} True, if we're running in the service worker global scope.\n * False otherwise.\n */\nexport function isServiceWorkerGlobalScope() {\n return ('ServiceWorkerGlobalScope' in self &&\n self instanceof ServiceWorkerGlobalScope);\n}\n\n/**\n * @private\n * @return {boolean} True, if we're running a development bundle.\n * False otherwise.\n */\nexport function isDevBuild() {\n // `BUILD_PROCESS_REPLACE::BUILD_TARGET` is replaced during the build process.\n return `BUILD_PROCESS_REPLACE::BUILD_TARGET` === `dev`;\n}\n\n/**\n * @private\n * @return {boolean} True, if we're running on localhost or the equivalent IP\n * address. False otherwise.\n */\nexport function isLocalhost() {\n return Boolean(\n location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n location.hostname === '[::1]' ||\n // 127.0.0.1/8 is considered localhost for IPv4.\n location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n );\n}\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/* eslint-disable no-console */\n\nimport LogGroup from './log-group';\nimport {isDevBuild} from './environment';\n\nself.workbox = self.workbox || {};\nself.workbox.LOG_LEVEL = self.workbox.LOG_LEVEL || {\n none: -1,\n verbose: 0,\n debug: 1,\n warn: 2,\n error: 3,\n};\n\nconst LIGHT_GREY = `#bdc3c7`;\nconst DARK_GREY = `#7f8c8d`;\nconst LIGHT_GREEN = `#2ecc71`;\nconst LIGHT_YELLOW = `#f1c40f`;\nconst LIGHT_RED = `#e74c3c`;\nconst LIGHT_BLUE = `#3498db`;\n\n/**\n * A class that will only log given the current log level\n * defined by the developer.\n *\n * Define custom log level by setting `self.workbox.logLevel`.\n *\n * @example\n *\n * self.workbox.logLevel = self.workbox.LOG_LEVEL.verbose;\n *\n * @private\n */\nclass LogHelper {\n /**\n * LogHelper constructor.\n */\n constructor() {\n this._defaultLogLevel = isDevBuild() ?\n self.workbox.LOG_LEVEL.debug :\n self.workbox.LOG_LEVEL.warn;\n }\n\n /**\n * The most verbose log level.\n *\n * @param {Object} options The options of the log.\n */\n log(options) {\n this._printMessage(self.workbox.LOG_LEVEL.verbose, options);\n }\n\n /**\n * Useful for logs that are more exceptional that log()\n * but not severe.\n *\n * @param {Object} options The options of the log.\n */\n debug(options) {\n this._printMessage(self.workbox.LOG_LEVEL.debug, options);\n }\n\n /**\n * Warning messages.\n *\n * @param {Object} options The options of the log.\n */\n warn(options) {\n this._printMessage(self.workbox.LOG_LEVEL.warn, options);\n }\n\n /**\n * Error logs.\n *\n * @param {Object} options The options of the log.\n */\n error(options) {\n this._printMessage(self.workbox.LOG_LEVEL.error, options);\n }\n\n /**\n * Method to print to the console.\n * @param {number} logLevel\n * @param {Object} logOptions\n */\n _printMessage(logLevel, logOptions) {\n if (!this._shouldLogMessage(logLevel, logOptions)) {\n return;\n }\n\n const logGroups = this._getAllLogGroups(logLevel, logOptions);\n logGroups.print();\n }\n\n /**\n * Print a user friendly log to the console.\n * @param {numer} logLevel A number from self.workbox.LOG_LEVEL\n * @param {Object} logOptions Arguments to print to the console\n * @return {LogGroup} Returns a log group to print to the console.\n */\n _getAllLogGroups(logLevel, logOptions) {\n const topLogGroup = new LogGroup();\n\n const primaryMessage = this._getPrimaryMessageDetails(logLevel, logOptions);\n topLogGroup.addPrimaryLog(primaryMessage);\n\n if (logOptions.error) {\n const errorMessage = {\n message: logOptions.error,\n logFunc: console.error,\n };\n topLogGroup.addLog(errorMessage);\n }\n\n const extraInfoGroup = new LogGroup();\n if (logOptions.that && logOptions.that.constructor &&\n logOptions.that.constructor.name) {\n const className = logOptions.that.constructor.name;\n extraInfoGroup.addLog(\n this._getKeyValueDetails('class', className)\n );\n }\n\n if (logOptions.data) {\n if (typeof logOptions.data === 'object' &&\n !(logOptions.data instanceof Array)) {\n Object.keys(logOptions.data).forEach((keyName) => {\n extraInfoGroup.addLog(\n this._getKeyValueDetails(keyName, logOptions.data[keyName])\n );\n });\n } else {\n extraInfoGroup.addLog(\n this._getKeyValueDetails('additionalData', logOptions.data)\n );\n }\n }\n\n topLogGroup.addChildGroup(extraInfoGroup);\n\n return topLogGroup;\n }\n\n /**\n * This is a helper function to wrap key value pairss to a colored key\n * value string.\n * @param {string} key\n * @param {string} value\n * @return {Object} The object containing a message, color and Arguments\n * for the console.\n */\n _getKeyValueDetails(key, value) {\n return {\n message: `%c${key}: `,\n colors: [`color: ${LIGHT_BLUE}`],\n args: value,\n };\n }\n\n /**\n * Helper method to color the primary message for the log\n * @param {number} logLevel One of self.workbox.LOG_LEVEL\n * @param {Object} logOptions Arguments to print to the console\n * @return {Object} Object containing the message and color info to print.\n */\n _getPrimaryMessageDetails(logLevel, logOptions) {\n let logLevelName;\n let logLevelColor;\n switch (logLevel) {\n case self.workbox.LOG_LEVEL.verbose:\n logLevelName = 'Info';\n logLevelColor = LIGHT_GREY;\n break;\n case self.workbox.LOG_LEVEL.debug:\n logLevelName = 'Debug';\n logLevelColor = LIGHT_GREEN;\n break;\n case self.workbox.LOG_LEVEL.warn:\n logLevelName = 'Warn';\n logLevelColor = LIGHT_YELLOW;\n break;\n case self.workbox.LOG_LEVEL.error:\n logLevelName = 'Error';\n logLevelColor = LIGHT_RED;\n break;\n }\n\n let primaryLogMessage = `%c🔧 %c[${logLevelName}]`;\n const primaryLogColors = [\n `color: ${LIGHT_GREY}`,\n `color: ${logLevelColor}`,\n ];\n\n let message;\n if (typeof logOptions === 'string') {\n message = logOptions;\n } else if (logOptions.message) {\n message = logOptions.message;\n }\n\n if (message) {\n message = message.replace(/\\s+/g, ' ');\n primaryLogMessage += `%c ${message}`;\n primaryLogColors.push(`color: ${DARK_GREY}; font-weight: normal`);\n }\n\n return {\n message: primaryLogMessage,\n colors: primaryLogColors,\n };\n }\n\n /**\n * Test if the message should actually be logged.\n * @param {number} logLevel The level of the current log to be printed.\n * @param {Object|String} logOptions The options to log.\n * @return {boolean} Returns true of the message should be printed.\n */\n _shouldLogMessage(logLevel, logOptions) {\n if (!logOptions) {\n return false;\n }\n\n let minValidLogLevel = this._defaultLogLevel;\n if (self && self.workbox && typeof self.workbox.logLevel === 'number') {\n minValidLogLevel = self.workbox.logLevel;\n }\n\n if (minValidLogLevel === self.workbox.LOG_LEVEL.none ||\n logLevel < minValidLogLevel) {\n return false;\n }\n\n return true;\n }\n}\n\nexport default new LogHelper();\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\nimport Route from './route';\nimport {isArrayOfClass} from '../../../../lib/assert';\nimport logHelper from '../../../../lib/log-helper';\n\n/**\n * NavigationRoute is a helper class to create a [Route]{@link\n * module:workbox-routing.Route} that matches for browser navigation requests,\n * i.e. requests for HTML pages.\n *\n * It will only match incoming requests whose [`mode`](https://fetch.spec.whatwg.org/#concept-request-mode)\n * is set to `navigate`.\n *\n * You can optionally only apply this route to a subset of navigation requests\n * by using one or both of the `blacklist` and `whitelist` parameters. If\n * both lists are provided, and there's a navigation to a URL which matches\n * both, then the blacklist will take precedence and the request will not be\n * matched by this route. The regular expressions in `whitelist` and `blacklist`\n * are matched against the concatenated\n * [`pathname`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname)\n * and [`search`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search)\n * portions of the requested URL.\n *\n * To match all navigations, use a `whitelist` array containing a RegExp that\n * matches everything, i.e. `[/./]`.\n *\n * @memberof module:workbox-routing\n * @extends Route\n *\n * @example\n * // Any navigation requests that match the whitelist (i.e. URLs whose path\n * // starts with /article/) will be handled with the cache entry for\n * // app-shell.html.\n * const route = new workbox.routing.NavigationRoute({\n * whitelist: [new RegExp('^/article/')],\n * handler: {handle: () => caches.match('app-shell.html')},\n * });\n *\n * const router = new workbox.routing.Router();\n * router.registerRoute({route});\n */\nclass NavigationRoute extends Route {\n /**\n * Constructor for NavigationRoute.\n *\n * @param {Object} input\n * @param {Array<RegExp>} input.whitelist If any of these patterns match,\n * the route will handle the request (assuming the blacklist doesn't match).\n * @param {Array<RegExp>} [input.blacklist] If any of these patterns match,\n * the route will not handle the request (even if a whitelist entry matches).\n * @param {function|module:workbox-runtime-caching.Handler} input.handler The\n * handler to use to provide a response if the route matches.\n *\n * If you wish to use a callback function [see handlerCallback]{@link\n * module:workbox-routing.Route~handlerCallback} for the callback\n * definition.\n */\n constructor({whitelist, blacklist, handler} = {}) {\n isArrayOfClass({whitelist}, RegExp);\n if (blacklist) {\n isArrayOfClass({blacklist}, RegExp);\n } else {\n blacklist = [];\n }\n\n const match = ({event, url}) => {\n let matched = false;\n let message;\n\n if (event.request.mode === 'navigate') {\n const pathnameAndSearch = url.pathname + url.search;\n if (whitelist.some((regExp) => regExp.test(pathnameAndSearch))) {\n if (blacklist.some((regExp) => regExp.test(pathnameAndSearch))) {\n message = `The navigation route is not being used, since the ` +\n `request URL matches both the whitelist and blacklist.`;\n } else {\n message = `The navigation route is being used.`;\n matched = true;\n }\n } else {\n message = `The navigation route is not being used, since the ` +\n `URL being navigated to doesn't match the whitelist.`;\n }\n\n logHelper.debug({\n that: this,\n message,\n data: {'request-url': url.href, whitelist, blacklist, handler},\n });\n }\n\n return matched;\n };\n\n super({match, handler, method: 'GET'});\n }\n}\n\nexport default NavigationRoute;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport Route from './route';\nimport {isInstance} from '../../../../lib/assert';\nimport logHelper from '../../../../lib/log-helper.js';\n\n/**\n * RegExpRoute is a helper class to make defining regular expression based\n * [Routes]{@link module:workbox-routing.Route} easy.\n *\n * The matching for regular expressioned are slightly different between\n * same-origin requests and cross-origin requests.\n *\n * A common pattern is to use a regex pattern similar to `/styles/.*` to capture\n * all stylesheets on your site.\n *\n * If we used this on `https://workboxjs.org`,\n * this regular expression would match for the end of\n * <code>https://workboxjs.org<strong>/styles/main.css</strong></code>.\n *\n * However, it's unlikely that we'd intend for this to match against:\n * <code>https://third-party-origin.com<strong>/styles/example.css</strong></code>.\n *\n * To overcome this common issue, regular expressions will only match against\n * cross-origin requests if the regular expression matches from the start.\n *\n * For example, matching the cross-origin example, we could change the\n * regular expression to: `https://third-party-origin.com/styles/.*`, meaning\n * we would now match <code><strong>https://third-party-origin.com/styles/example.css</strong></code>.\n *\n * If you wish your regular expression to match both, you just need to ensure\n * you account for the full URL.\n *\n * @memberof module:workbox-routing\n * @extends Route\n *\n * @example\n * // Any requests that match the regular expression will match this route, with\n * // the capture groups passed along to the handler as an array via params.\n * const route = new workbox.routing.RegExpRoute({\n * regExp: new RegExp('^https://example.com/path/to/(\\\\w+)'),\n * handler: {\n * handle: ({event, params}) => {\n * // params[0], etc. will be set based on the regexp capture groups.\n * // Do something that returns a Promise.<Response>, like:\n * return caches.match(event.request);\n * },\n * },\n * });\n *\n * const router = new workbox.routing.Router();\n * router.registerRoute({route});\n */\nclass RegExpRoute extends Route {\n /**\n * Constructor for RegExpRoute.\n *\n * @param {Object} input\n * @param {RegExp} input.regExp The regular expression to match against URLs.\n * If the `RegExp` contains [capture groups](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references),\n * then the array of captured values will be passed to the `handler` as\n * `params`.\n * @param {function|module:workbox-runtime-caching.Handler} input.handler The\n * handler to use to provide a response if the route matches.\n *\n * If you wish to use a callback function [see handlerCallback]{@link\n * module:workbox-routing.Route~handlerCallback} for the callback\n * definition.\n * @param {string} [input.method] Only match requests that use this\n * HTTP method. Defaults to `'GET'` if not specified.\n */\n constructor({regExp, handler, method}) {\n isInstance({regExp}, RegExp);\n\n const match = ({url}) => {\n const result = regExp.exec(url.href);\n\n // Return null immediately if this route doesn't match.\n if (!result) {\n return null;\n }\n\n // If this is a cross-origin request, then confirm that the match included\n // the start of the URL. This means that regular expressions like\n // /styles.+/ will only match same-origin requests.\n // See https://github.com/GoogleChrome/workbox/issues/281#issuecomment-285130355\n if ((url.origin !== location.origin) && (result.index !== 0)) {\n logHelper.debug({\n that: this,\n message: `Skipping route, because the RegExp match didn't occur ` +\n `at the start of the URL.`,\n data: {url: url.href, regExp},\n });\n\n return null;\n }\n\n // If the route matches, but there aren't any capture groups defined, then\n // this will return [], which is truthy and therefore sufficient to\n // indicate a match.\n // If there are capture groups, then it will return their values.\n return result.slice(1);\n };\n\n super({match, handler, method});\n }\n}\n\nexport default RegExpRoute;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport Route from './route';\nimport {isArrayOfClass, isInstance} from '../../../../lib/assert';\nimport logHelper from '../../../../lib/log-helper.js';\nimport normalizeHandler from './normalize-handler';\n\n/**\n * The Router takes one or more [Routes]{@link Route} and allows you to apply\n * that routing logic to determine the appropriate way of handling requests\n * inside of a service worker.\n *\n * It also allows you to define a \"default\" handler that applies to any requests\n * that don't explicitly match a `Route`, and a \"catch\" handler that responds\n * to any requests that throw an exception while being routed.\n *\n * You can use the `handleRequest()` method to pass a `FetchEvent` through the\n * router and ultimately get a \"routed response\" back.\n * If you'd like this to be handled automatically for you, calling\n * `addFetchListener()` will cause the `Router` to respond to `fetch` events.\n *\n * If a request matches multiple routes, precedence will be given to the \n * last-registered route.\n *\n * @memberof module:workbox-routing\n *\n * @example\n * // The following example sets up two routes, one to match requests with\n * // \"assets\" in their URL, and the other for requests with \"images\", along\n * // different runtime caching handlers for each.\n * // Both the routes are registered with the router, and any requests that\n * // don't match either route will be handled using the default NetworkFirst\n * // strategy.\n * // \"If a request matches both routes, the last route will be used to handle \n * // the request, in this case, the \"images\" handler would take precedence.\n * const assetRoute = new RegExpRoute({\n * regExp: /assets/,\n * handler: new workbox.runtimeCaching.StaleWhileRevalidate(),\n * });\n * const imageRoute = new RegExpRoute({\n * regExp: /images/,\n * handler: new workbox.runtimeCaching.CacheFirst(),\n * });\n *\n * const router = new workbox.routing.Router();\n * router.addFetchListener();\n * router.registerRoutes({routes: [assetRoute, imageRoute]});\n * router.setDefaultHandler({\n * handler: new workbox.runtimeCaching.NetworkFirst(),\n * });\n */\nclass Router {\n /**\n * Constructs a new `Router` instance, without any registered routes.\n */\n constructor() {\n // _routes will contain a mapping of HTTP method name ('GET', etc.) to an\n // array of all the corresponding Route instances that are registered.\n this._routes = new Map();\n this._isListenerRegistered = false;\n }\n\n /**\n * This will register a `fetch` event listener on your behalf which will check\n * the incoming request to see if there's a matching route, and only respond\n * if there is a match.\n *\n * @example\n * const imageRoute = new RegExpRoute({\n * regExp: /images/,\n * handler: new CacheFirst(),\n * });\n *\n * const router = new Router();\n * router.registerRoute({route: imageRoute});\n * router.addFetchListener();\n *\n * @return {boolean} Returns `true` if this is the first time the method is\n * called and the listener was registered. Returns `false` if called again,\n * as the listener will only be registered once.\n */\n addFetchListener() {\n if (!this._isListenerRegistered) {\n this._isListenerRegistered = true;\n self.addEventListener('fetch', (event) => {\n const responsePromise = this.handleRequest({event});\n if (responsePromise) {\n event.respondWith(responsePromise);\n }\n });\n return true;\n } else {\n logHelper.warn({\n that: this,\n message: `addFetchListener() has already been called for this Router.`,\n });\n return false;\n }\n }\n\n /**\n * This can be used to apply the routing rules to generate a response for a\n * given request inside your own `fetch` event handler.\n *\n * @example\n * const imageRoute = new RegExpRoute({\n * regExp: /images/,\n * handler: new CacheFirst(),\n * });\n *\n * const router = new Router();\n * router.registerRoute({route: imageRoute});\n *\n * self.addEventListener('fetch', (event) => {\n * event.waitUntil((async () => {\n * let response = await router.handleRequest({event});\n * // Do something with response, and then eventually respond with it.\n * event.respondWith(response);\n * })());\n * });\n *\n * @param {Object} input\n * @param {FetchEvent} input.event The event passed in to a `fetch` handler.\n * @return {Promise<Response>|undefined} Returns a promise for a response,\n * taking the registered routes into account. If there was no matching route\n * and there's no `defaultHandler`, then returns undefined.\n */\n handleRequest({event}) {\n isInstance({event}, FetchEvent);\n const url = new URL(event.request.url);\n if (!url.protocol.startsWith('http')) {\n logHelper.log({\n that: this,\n message: `The URL does not start with HTTP, so it can't be handled.`,\n data: {\n request: event.request,\n },\n });\n return;\n }\n\n let {handler, params} = this._findHandlerAndParams({event, url});\n\n // If we don't have a handler because there was no matching route, then\n // fall back to defaultHandler if that's defined.\n if (!handler && this.defaultHandler) {\n handler = this.defaultHandler;\n }\n\n if (handler) {\n let responsePromise = handler.handle({url, event, params});\n if (this.catchHandler) {\n responsePromise = responsePromise.catch((error) => {\n return this.catchHandler.handle({url, event, error});\n });\n }\n return responsePromise;\n }\n }\n\n /**\n * Checks the incoming event.request against the registered routes, and if\n * there's a match, returns the corresponding handler along with any params\n * generated by the match.\n *\n * @param {FetchEvent} input.event\n * @param {URL} input.url\n * @return {Object} Returns an object with `handler` and `params` properties.\n * They are populated if a matching route was found or `undefined` otherwise.\n * @private\n */\n _findHandlerAndParams({event, url}) {\n const routes = this._routes.get(event.request.method) || [];\n for (const route of routes) {\n let matchResult = route.match({url, event});\n if (matchResult) {\n logHelper.log({\n that: this,\n message: 'The router found a matching route.',\n data: {\n route,\n request: event.request,\n },\n });\n\n if (Array.isArray(matchResult) && matchResult.length === 0) {\n // Instead of passing an empty array in as params, use undefined.\n matchResult = undefined;\n } else if (matchResult.constructor === Object &&\n Object.keys(matchResult).length === 0) {\n // Instead of passing an empty object in as params, use undefined.\n matchResult = undefined;\n }\n\n // Break out of the loop and return the appropriate values as soon as\n // we have a match.\n return {\n params: matchResult,\n handler: route.handler,\n };\n }\n }\n\n // If we didn't have a match, then return undefined values.\n return {handler: undefined, params: undefined};\n }\n\n /**\n * An optional `handler` that's called by default when no routes\n * explicitly match the incoming request.\n *\n * If the default is not provided, unmatched requests will go against the\n * network as if there were no service worker present.\n *\n * @example\n * router.setDefaultHandler({\n * handler: new workbox.runtimeCaching.NetworkFirst()\n * });\n *\n * @param {Object} input\n * @param {function|module:workbox-runtime-caching.Handler} input.handler\n * This parameter can be either a function or an object which is a subclass\n * of `Handler`.\n *\n * Either option should result in a `Response` that the `Route` can use to\n * handle the `fetch` event.\n *\n * See [handlerCallback]{@link module:workbox-routing.Route~handlerCallback}\n * for full details on using a callback function as the `handler`.\n */\n setDefaultHandler({handler} = {}) {\n this.defaultHandler = normalizeHandler(handler);\n }\n\n /**\n * If a Route throws an error while handling a request, this `handler`\n * will be called and given a chance to provide a response.\n *\n * @example\n * router.setCatchHandler(({event}) => {\n * if (event.request.mode === 'navigate') {\n * return caches.match('/error-page.html');\n * }\n * return Response.error();\n * });\n *\n * @param {Object} input\n * @param {function|module:workbox-runtime-caching.Handler} input.handler\n * This parameter can be either a function or an object which is a subclass\n * of `Handler`.\n *\n * Either option should result in a `Response` that the `Route` can use to\n * handle the `fetch` event.\n *\n * See [handlerCallback]{@link module:workbox-routing.Route~handlerCallback}\n * for full details on using a callback function as the `handler`.\n */\n setCatchHandler({handler} = {}) {\n this.catchHandler = normalizeHandler(handler);\n }\n\n /**\n * Registers an array of routes with the router.\n *\n * @example\n * router.registerRoutes({\n * routes: [\n * new RegExpRoute({ ... }),\n * new ExpressRoute({ ... }),\n * new Route({ ... }),\n * ]\n * });\n *\n * @param {Object} input\n * @param {Array<module:workbox-routing.Route>} input.routes An array of\n * routes to register.\n */\n registerRoutes({routes} = {}) {\n isArrayOfClass({routes}, Route);\n\n for (let route of routes) {\n if (!this._routes.has(route.method)) {\n this._routes.set(route.method, []);\n }\n\n // Give precedence to the most recent route by listing it first.\n this._routes.get(route.method).unshift(route);\n }\n }\n\n /**\n * Registers a single route with the router.\n *\n * @example\n * router.registerRoute({\n * route: new Route({ ... })\n * });\n *\n * @param {Object} input\n * @param {module:workbox-routing.Route} input.route The route to register.\n */\n registerRoute({route} = {}) {\n isInstance({route}, Route);\n\n this.registerRoutes({routes: [route]});\n }\n\n /**\n * Unregisters an array of routes with the router.\n *\n * @example\n * const firstRoute = new RegExpRoute({ ... });\n * const secondRoute = new RegExpRoute({ ... });\n * router.registerRoutes({routes: [firstRoute, secondRoute]});\n *\n * // Later, if you no longer want the routes to be used:\n * router.unregisterRoutes({routes: [firstRoute, secondRoute]});\n *\n * @param {Object} input\n * @param {Array<module:workbox-routing.Route>} input.routes An array of\n * routes to unregister.\n */\n unregisterRoutes({routes} = {}) {\n isArrayOfClass({routes}, Route);\n\n for (let route of routes) {\n if (!this._routes.has(route.method)) {\n logHelper.error({\n that: this,\n message: `Can't unregister route; there are no ${route.method}\n routes registered.`,\n data: {route},\n });\n }\n\n const routeIndex = this._routes.get(route.method).indexOf(route);\n if (routeIndex > -1) {\n this._routes.get(route.method).splice(routeIndex, 1);\n } else {\n logHelper.error({\n that: this,\n message: `Can't unregister route; the route wasn't previously\n registered.`,\n data: {route},\n });\n }\n }\n }\n\n /**\n * Unregisters a single route with the router.\n *\n * @example\n * const route = new RegExpRoute({ ... });\n * router.registerRoute({route});\n *\n * // Later, if you no longer want the route to be used:\n * router.unregisterRoute({route});\n *\n * @param {Object} input\n * @param {module:workbox-routing.Route} input.route The route to unregister.\n */\n unregisterRoute({route} = {}) {\n isInstance({route}, Route);\n\n this.unregisterRoutes({routes: [route]});\n }\n}\n\nexport default Router;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/* eslint-env browser, serviceworker */\n\nimport {\n Router as SWRoutingRouter,\n ExpressRoute,\n RegExpRoute,\n Route,\n NavigationRoute,\n} from '../../../workbox-routing/src/index.js';\nimport ErrorFactory from './error-factory.js';\n\n/**\n * Adds a friendly API on top of the router from the\n * {@link module:workbox-routing|workbox-routing module}.\n *\n * @example <caption>How to define a simple route with caching\n * strategy.</caption>\n *\n * const workboxSW = new WorkboxSW();\n * workboxSW.router.registerRoute('/about',\n * workboxSW.strategies.cacheFirst());\n *\n * @example <caption>How to define a simple route with custom caching\n * strategy.</caption>\n *\n * const workboxSW = new WorkboxSW();\n * workboxSW.router.registerRoute('/about', (args) => {\n * // The requested URL\n * console.log(args.url);\n *\n * // The FetchEvent to handle\n * console.log(args.event);\n *\n * // The parameters from the matching route (Commonly\n * // used with Regex / Express routes).\n * console.log(args.params);\n *\n * // Return a promise that resolves with a Response.\n * return fetch(args.url);\n * }));\n *\n * @memberof module:workbox-sw\n */\nclass Router extends SWRoutingRouter {\n /**\n * Constructs a light wrapper on top of the underlying `Router`.\n * @param {String} revisionedCacheName The cache name used for entries cached\n * via precache().\n * @param {boolean} handleFetch Determines if the router should handle fetch\n * events.\n */\n constructor(revisionedCacheName, handleFetch) {\n super({handleFetch});\n this._revisionedCacheName = revisionedCacheName;\n }\n\n /**\n * @param {String|RegExp|module:workbox-routing.matchCallback} capture\n * The capture for a route can be one of three types:\n * 1. An Express-style route, like `'/path/to/:anything'` for\n * same-origin or `'https://cross-origin.com/path/to/:anything'` for\n * cross-origin routes.\n * 1. A regular expression that will be tested against request URLs. For\n * cross-origin routes, you must use a RegExp that matches the start of the\n * full URL, like `new RegExp('https://cross-origin\\.com/')`.\n * 1. A [function]{@link module:workbox-routing.matchCallback} which is\n * passed the URL and `FetchEvent`, and should returns a truthy value if\n * the route matches.\n * @param {function|module:workbox-runtime-caching.Handler} handler The\n * handler to use to provide a response if the route matches. The handler\n * argument is ignored if you pass in a Route object, otherwise it's required.\n * @param {String} [method] Only match requests that use this HTTP method.\n + Defaults to `'GET'`.\n * @return {module:workbox-routing.Route} The Route object that was\n * registered.\n */\n registerRoute(capture, handler, method = 'GET') {\n if (typeof handler === 'function') {\n handler = {\n handle: handler,\n };\n }\n\n let route;\n if (typeof capture === 'string') {\n if (capture.length === 0) {\n throw ErrorFactory.createError('empty-express-string');\n }\n route = new ExpressRoute({path: capture, handler, method});\n } else if (capture instanceof RegExp) {\n route = new RegExpRoute({regExp: capture, handler, method});\n } else if (typeof capture === 'function') {\n route = new Route({match: capture, handler, method});\n } else {\n throw ErrorFactory.createError('unsupported-route-type');\n }\n\n super.registerRoute({route});\n return route;\n }\n\n /**\n * A shortcut used to register a\n * [NavigationRoute]{@link module:workbox-routing.NavigationRoute} instance\n * that will respond to navigation requests using a cache entry for `url`.\n *\n * This is useful when following the [App Shell pattern](https://developers.google.com/web/fundamentals/architecture/app-shell#example-html-for-appshell),\n * in which the previously cached shell is returned for all navigations.\n *\n * The `url` value should correspond to an entry that's already in the cache,\n * perhaps a URL that is managed by\n * [precache()]{@link module:workbox-sw.WorkboxSW#precache}. Using a URL that\n * isn't already cached will lead to failed navigations.\n *\n * @param {String} url The URL of the already cached HTML resource.\n * @param {Object} [options]\n * @param {Array<RegExp>} [options.blacklist] Defaults to an empty blacklist.\n * @param {Array<RegExp>} [options.whitelist] Defaults to `[/./]`, which will\n * match all request URLs.\n * @param {String} [options.cacheName] The name of the cache which contains\n * the cached response for `url`. Defaults to the name of the cache\n * used by precache().\n */\n registerNavigationRoute(url, options = {}) {\n if (typeof url !== 'string') {\n throw ErrorFactory.createError('navigation-route-url-string');\n }\n\n // Allow folks to explicitly pass in a null/undefined cacheName option if\n // they want that behavior.\n const cacheName = 'cacheName' in options ?\n options.cacheName :\n this._revisionedCacheName;\n\n super.registerRoute({route: new NavigationRoute({\n handler: () => caches.match(url, {cacheName}),\n whitelist: options.whitelist || [/./],\n blacklist: options.blacklist || [],\n })});\n }\n}\n\nexport default Router;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport ErrorFactory from '../../../../lib/error-factory';\n\nconst errors = {\n 'multiple-cache-will-update-plugins': 'You cannot register more than one ' +\n 'plugin that implements cacheWillUpdate.',\n 'multiple-cached-response-will-be-used-plugins': 'You cannot register more ' +\n 'than one plugin that implements cachedResponseWillBeUsed.',\n 'invalid-response-for-caching': 'The fetched response could not be cached ' +\n 'due to an invalid response code.',\n 'no-response-received': 'No response received; falling back to cache.',\n 'bad-cache-id': `The 'cacheId' parameter must be a string with at least ` +\n `one character.`,\n};\n\nexport default new ErrorFactory(errors);\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport {atLeastOne, isArrayOfType, isType, isInstance} from\n '../../../../lib/assert';\nimport logHelper from '../../../../lib/log-helper.js';\n\n/**\n * Use this plugin to cache responses with certain HTTP status codes or\n * header values.\n *\n * Defining both status codes and headers will cache requests with a matching\n * status code and a matching header.\n *\n * @example\n * new workbox.cacheableResponse.CacheableResponse({\n * statuses: [0, 200, 404],\n * headers: {\n * 'Example-Header-1': 'Header-Value-1'\n * 'Example-Header-2': 'Header-Value-2'\n * }\n * })\n *\n * @memberof module:workbox-cacheable-response\n */\nclass CacheableResponse {\n /**\n * Creates a new `Plugin` instance, which stores configuration and logic\n * to determine whether a `Response` object is cacheable or not.\n *\n * If multiple criteria are present (e.g. both `statuses` and `headers`), then\n * the `Response` needs to meet all of the criteria to be cacheable.\n *\n * @param {Object} input\n * @param {Array<Number>} [input.statuses] The status codes that are\n * checked when determining whether a `Response` is cacheable.\n * @param {Object<String,String>} [input.headers] The header values that are\n * checked when determining whether a `Response` is cacheable.\n */\n constructor({statuses, headers} = {}) {\n atLeastOne({statuses, headers});\n if (statuses !== undefined) {\n isArrayOfType({statuses}, 'number');\n }\n if (headers !== undefined) {\n isType({headers}, 'object');\n }\n\n this.statuses = statuses;\n this.headers = headers;\n }\n\n /**\n * Checks a response to see whether it's cacheable or not, based on the\n * configuration of this object.\n *\n * @param {Object} input\n * @param {Response} input.response The response that might be cached.\n * @param {Request} [input.request] Optionally, the request that led to the\n * response.\n * @return {boolean} `true` if the `Response` is cacheable, based on the\n * configuration of this object, and `false` otherwise.\n */\n isResponseCacheable({request, response} = {}) {\n isInstance({response}, Response);\n\n let cacheable = true;\n\n if (this.statuses) {\n cacheable = this.statuses.includes(response.status);\n }\n\n if (this.headers && cacheable) {\n cacheable = Object.keys(this.headers).some((headerName) => {\n return response.headers.get(headerName) === this.headers[headerName];\n });\n }\n\n if (!cacheable) {\n const data = {response};\n if (this.statuses) {\n data['valid-status-codes'] = JSON.stringify(this.statuses);\n }\n if (this.headers) {\n data['valid-headers'] = JSON.stringify(this.headers);\n }\n if (request) {\n data['request'] = request;\n }\n\n logHelper.debug({\n message: `The response does not meet the criteria for being added to the\n cache.`,\n data,\n });\n }\n\n return cacheable;\n }\n}\n\nexport default CacheableResponse;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport CacheableResponse from './cacheable-response';\n\n/**\n * Use this plugin to cache responses with certain HTTP status codes or\n * header values.\n *\n * Defining both status codes and headers will cache requests with a matching\n * status code and a matching header.\n *\n * This class is meant to be automatically invoked as a plugin to a\n * {@link module:workbox-runtime-caching.RequestWrapper|RequestWrapper}, which\n * is used by the `workbox-sw` and `workbox-runtime-caching` modules.\n *\n * If you would like to use this functionality outside of the `RequestWrapper`\n * context, please use the `CacheableResponse` class directly.\n *\n * @example\n * new workbox.cacheableResponse.CacheableResponsePlugin({\n * statuses: [0, 200, 404],\n * headers: {\n * 'Example-Header-1': 'Header-Value-1'\n * 'Example-Header-2': 'Header-Value-2'\n * }\n * });\n *\n * @memberof module:workbox-cacheable-response\n */\nclass CacheableResponsePlugin extends CacheableResponse {\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox.runtimeCaching` handlers prior to an entry being added to a cache.\n *\n * @private\n * @param {Object} input\n * @param {Request} input.request The request that led to the response.\n * @param {Response} input.response The response that might be cached.\n * @return {boolean} `true` if the `Response` is cacheable, based on the\n * configuration of this object, and `false` otherwise.\n */\n cacheWillUpdate({request, response} = {}) {\n return this.isResponseCacheable({request, response});\n }\n}\n\nexport default CacheableResponsePlugin;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/**\n * The default cache name, used by\n * {@link module:workbox-runtime-caching.RequestWrapper|RequestWrapper} when\n * there's no name provided.\n *\n * It combines a constant prefix with the service worker `scope`, ensuring\n * that multiple service workers used on the same origin will have\n * different default caches.\n *\n * Calling this method without any parameters will return\n * `workbox-runtime-caching-<service worker scope>`.\n *\n * If you pass in a cacheId, it will be prepended, returning:\n * `<cacheid>-workbox-runtime-caching-<service worker scope>`.\n *\n * @param {Object} input\n * @param {string} [input.cacheId] This will be prepended to the default cache\n * name.\n * @return {string} Returns the default cache name used based on optional\n * inputs.\n *\n * @memberof module:workbox-runtime-caching\n */\nconst getDefaultCacheName = ({cacheId} = {}) => {\n let cacheName = `workbox-runtime-caching`;\n if (cacheId) {\n cacheName = `${cacheId}-${cacheName}`;\n }\n\n if (self && self.registration) {\n cacheName += `-${self.registration.scope}`;\n }\n\n return cacheName;\n};\n\n/**\n * A list of the callback method names that the RequestWrapper might trigger.\n *\n * @private\n * @type {Array.<string>}\n * @memberof module:workbox-runtime-caching\n */\nconst pluginCallbacks = [\n 'cacheDidUpdate',\n 'cachedResponseWillBeUsed',\n 'cacheWillUpdate',\n 'fetchDidFail',\n 'requestWillFetch',\n];\n\n\nexport {\n getDefaultCacheName,\n pluginCallbacks,\n};\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport {isInstance} from '../../../../lib/assert';\n\n/**\n * Helper method to \"clean\" a redirected response, so that it could be used\n * to fulfill a navigation request.\n * See https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1\n *\n * @private\n * @param {Object} input\n * @param {Response} input.response The original response. The body will not\n * be consumed.\n * @return {Promise<Response>} A clone of the response, with `redirected` false.\n */\nexport default ({response}) => {\n isInstance({response}, Response);\n\n const clonedResponse = response.clone();\n\n // Not all browsers support the Response.body stream, so fall back to reading\n // the entire body into memory as a blob.\n const bodyPromise = 'body' in clonedResponse ?\n Promise.resolve(clonedResponse.body) :\n clonedResponse.blob();\n\n return bodyPromise.then((body) => {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: clonedResponse.headers,\n status: clonedResponse.status,\n statusText: clonedResponse.statusText,\n });\n });\n};\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport ErrorFactory from './error-factory';\nimport {isArrayOfType, isType, atLeastOne, isInstance} from\n '../../../../lib/assert';\nimport {CacheableResponsePlugin} from\n '../../../workbox-cacheable-response/src/index';\nimport {pluginCallbacks, getDefaultCacheName} from './constants';\nimport cleanResponseCopy from './clean-response-copy';\n\n/**\n * Called prior to a response being written to the cache. This allows you to\n * prevent the cache from being updated if the response doesn't meet your\n * custom criteria.\n *\n * @example <caption>Determines whether a response is cacheable based on\n * whether its Cache-Control header contains the string 'no-cache'.</caption>\n *\n * async function cacheWillUpdate({response}) {\n * return !response.headers.get('cache-control').includes('no-cache');\n * }\n *\n * @callback cacheWillUpdate\n * @param {Object} input\n * @param {Request} input.request The original request.\n * @param {Response} input.response The response to the request, based on the\n * configured strategy.\n * @return {Promise<Boolean>} `true` if the response meets your criteria for\n * being added to the appropriate cache, and `false` if it doesn't.\n *\n * @memberof module:workbox-runtime-caching.RequestWrapper\n */\n\n/**\n * Called after a response has been written to the cache.\n *\n * @example <caption>Logs a message when the cache has been updated.</caption>\n *\n * async function cacheDidUpdate({cacheName, url}) {\n * console.log(`The entry for ${url} in cache ${cacheName} was updated.`);\n * }\n *\n * @callback cacheDidUpdate\n * @param {Object} input\n * @param {String} input.cacheName The name of the cache that was updated.\n * @param {String} input.url The URL used as a key for the cache.\n * @param {Response|null} input.oldResponse The response that was previously in\n * the cache, prior to the update, or `null` if the cache didn't previously\n * contain an entry for `url`.\n * @param {Response|null} input.newResponse The response that was written to\n * the cache.\n *\n * @memberof module:workbox-runtime-caching.RequestWrapper\n */\n\n/**\n * Called before a previously cached response that has been read from the cache\n * is used. This allows you to modify it or return `null` if it's not valid.\n *\n * @example <caption>Returns `null` to indicate that a cached response shouldn't\n * be used if its Date header is too far in the past.</caption>\n *\n * async function cachedResponseWillBeUsed({cachedResponse}) {\n * if (cachedResponse) {\n * const dateHeader = cachedResponse.headers.get('date');\n * const date = new Date(dateHeader);\n * if (dateHeader && (Date.now() - date.getTime()) < 1000) {\n * return cachedResponse;\n * }\n * }\n *\n * return null;\n * }\n *\n * @callback cachedResponseWillBeUsed\n * @param {Object} input\n * @param {Request} input.request The original request.\n * @param {Cache} input.cache An open instance of the cache.\n * @param {String} input.cacheName The name corresponding to `cache`.\n * @param {Response|null} input.cachedResponse The response for `request` that's\n * currently in `cache`, or `null` if there isn't currently a response cached.\n * @param {Object} input.matchOptions The\n * [cache match options](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match#Parameters)\n * that were configured when the current `RequestWrapper` was constructed.\n * @return {Promise<Response|null>} The response to be used as the effective\n * cache match. This might be the same response as `cachedResponse`, if it was\n * valid, a modified version of the response, or `null` if there's no valid\n * match.\n *\n * @memberof module:workbox-runtime-caching.RequestWrapper\n */\n\n/**\n * Called prior to a network request being made. This allows you to update the\n * request's URL or headers as appropriate, or just return the original request\n * if there are no modifications needed.\n *\n * @example <caption>Appends a URL parameter to all outgoing requests.</caption>\n *\n * async function requestWillFetch({request}) {\n * const url = new URL(request.url);\n * url.searchParams.set('from-workbox', 'true');\n * return new Request(url.href, {headers: request.headers});\n * }\n *\n * @callback requestWillFetch\n * @param {Object} input\n * @param {Request} input.request The request that would otherwise have been\n * made against the network.\n * @return {Promise<Request>} The request that will be used against the network\n * instead.\n *\n * @memberof module:workbox-runtime-caching.RequestWrapper\n */\n\n/**\n * Called after a network request has failed. This allows you to report the\n * failure, or save a copy of the failed request to be retried later.\n *\n * @example <caption>Logs a message when a network request fails.</caption>\n *\n * async function fetchDidFail({request}) {\n * const body = await request.text();\n * console.log(`A request for ${request.url} with body ${body} failed.`);\n * }\n *\n * @callback fetchDidFail\n * @param {Object} input\n * @param {Request} input.request A clone of the request that failed. You can\n * consume the request's body if needed.\n *\n * @memberof module:workbox-runtime-caching.RequestWrapper\n */\n\n/**\n * This class is used by the various subclasses of\n * [Handler]{@link module:workbox-runtime-caching.Handler} to configure the\n * cache name and any desired plugins, which is to say classes that implement\n * request lifecycle callbacks.\n *\n * It automatically triggers any registered callbacks at the appropriate time.\n *\n * @memberof module:workbox-runtime-caching\n */\nclass RequestWrapper {\n /**\n * Constructor for RequestWrapper.\n * @param {Object} input\n * @param {string} [input.cacheName] The name of the cache to use for Handlers\n * that involve caching. If none is provided, a default name that\n * includes the current service worker scope will be used.\n * @param {Array.<Object>} [input.plugins] Any plugins that should be\n * invoked.\n * @param {Object} [input.fetchOptions] Values passed along to the\n * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch#Parameters)\n * of all `fetch()` requests made by this wrapper.\n * @param {Object} [input.matchOptions] Values passed along to the\n * [`options`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match#Parameters)\n * of all cache `match()` requests made by this wrapper.\n */\n constructor({cacheName, cacheId, plugins, fetchOptions, matchOptions} = {}) {\n if (cacheId && (typeof cacheId !== 'string' || cacheId.length === 0)) {\n throw ErrorFactory.createError('bad-cache-id');\n }\n\n if (cacheName) {\n isType({cacheName}, 'string');\n this.cacheName = cacheName;\n if (cacheId) {\n this.cacheName = `${cacheId}-${this.cacheName}`;\n }\n } else {\n this.cacheName = getDefaultCacheName({cacheId});\n }\n\n if (fetchOptions) {\n isType({fetchOptions}, 'object');\n this.fetchOptions = fetchOptions;\n }\n\n if (matchOptions) {\n isType({matchOptions}, 'object');\n this.matchOptions = matchOptions;\n }\n\n this.plugins = new Map();\n\n if (plugins) {\n isArrayOfType({plugins}, 'object');\n\n plugins.forEach((plugin) => {\n for (let callbackName of pluginCallbacks) {\n if (typeof plugin[callbackName] === 'function') {\n if (!this.plugins.has(callbackName)) {\n this.plugins.set(callbackName, []);\n } else if (callbackName === 'cacheWillUpdate') {\n throw ErrorFactory.createError(\n 'multiple-cache-will-update-plugins');\n } else if (callbackName === 'cachedResponseWillBeUsed') {\n throw ErrorFactory.createError(\n 'multiple-cached-response-will-be-used-plugins');\n }\n this.plugins.get(callbackName).push(plugin);\n }\n }\n });\n }\n\n if (this.plugins.has('cacheWillUpdate')) {\n this._userSpecifiedCachableResponsePlugin =\n this.plugins.get('cacheWillUpdate')[0];\n }\n }\n\n\n /**\n * @private\n * @return {function} The default plugin used to determine whether a\n * response is cacheable.\n */\n getDefaultCacheableResponsePlugin() {\n // Lazy-construct the CacheableResponsePlugin instance.\n if (!this._defaultCacheableResponsePlugin) {\n this._defaultCacheableResponsePlugin =\n new CacheableResponsePlugin({statuses: [200]});\n }\n return this._defaultCacheableResponsePlugin;\n }\n\n /**\n * Opens a cache and maintains a reference to that cache\n * for future use.\n *\n * @example\n * requestWrapper.getCache()\n * .then((openCache) => {\n * ...\n * });\n *\n * @return {Promise<Cache>} An open `Cache` instance based on the configured\n * `cacheName`.\n */\n async getCache() {\n if (!this._cache) {\n this._cache = await caches.open(this.cacheName);\n }\n return this._cache;\n }\n\n /**\n * Wraps `cache.match()`, using the previously configured cache name and match\n * options.\n *\n * @example\n * requestWrapper.match({event.request})\n * .then((response) => {\n * if (!response) {\n * // No response in cache.\n * return;\n * }\n * ...\n * });\n *\n * @param {Object} input\n * @param {Request|string} input.request The key for the cache lookup.\n * @return {Promise.<Response>} The cached response.\n */\n async match({request}) {\n atLeastOne({request});\n\n const cache = await this.getCache();\n let cachedResponse = await cache.match(request, this.matchOptions);\n\n if (this.plugins.has('cachedResponseWillBeUsed')) {\n const plugin = this.plugins.get('cachedResponseWillBeUsed')[0];\n cachedResponse = await plugin.cachedResponseWillBeUsed({\n request, cache, cachedResponse,\n matchOptions: this.matchOptions, cacheName: this.cacheName,\n });\n }\n\n return cachedResponse;\n }\n\n /**\n * Wraps `fetch()`, calls all `requestWillFetch` before making the network\n * request, and calls any `fetchDidFail` callbacks from the\n * registered plugins if the request fails.\n *\n * @example\n * requestWrapper.fetch({\n * request: event.request\n * })\n * .then((response) => {\n * ...\n * })\n * .catch((err) => {\n * ...\n * });\n *\n * @param {Object} input\n * @param {Request|string} input.request The request or URL to be fetched.\n * @return {Promise.<Response>} The network response.\n */\n async fetch({request}) {\n if (typeof request === 'string') {\n request = new Request(request);\n } else {\n isInstance({request}, Request);\n }\n\n // If there is a fetchDidFail plugin, we need to save a clone of the\n // original request before it's either modified by a requestWillFetch\n // plugin or before the original request's body is consumed via fetch().\n const clonedRequest = this.plugins.has('fetchDidFail') ?\n request.clone() : null;\n\n if (this.plugins.has('requestWillFetch')) {\n for (let plugin of this.plugins.get('requestWillFetch')) {\n const returnedRequest = await plugin.requestWillFetch({request});\n isInstance({returnedRequest}, Request);\n request = returnedRequest;\n }\n }\n\n try {\n return await fetch(request, this.fetchOptions);\n } catch (err) {\n if (this.plugins.has('fetchDidFail')) {\n for (let plugin of this.plugins.get('fetchDidFail')) {\n await plugin.fetchDidFail({request: clonedRequest.clone()});\n }\n }\n\n throw err;\n }\n }\n\n /**\n * Combines both fetching and caching using the previously configured options\n * and calling the appropriate plugins.\n *\n * By default, responses with a status of [2xx](https://fetch.spec.whatwg.org/#ok-status)\n * will be considered valid and cacheable, but this could be overridden by\n * configuring one or more plugins that implement the `cacheWillUpdate`\n * lifecycle callback.\n *\n * @example\n * requestWrapper.fetchAndCache({\n * request: event.request\n * })\n * .then((response) => {\n * ...\n * })\n * .catch((err) => {\n * ...\n * });\n *\n * @param {Object} input\n * @param {Request} input.request The request to fetch.\n * @param {boolean} [input.waitOnCache] `true` means the method should wait\n * for the cache.put() to complete before returning. The default value\n * of `false` means return without waiting. It this value is true\n * and the response can't be cached, an error will be thrown.\n * @param {Request} [input.cacheKey] Supply a cacheKey if you wish to cache\n * the response against an alternative request to the `request`\n * argument.\n * @param {function} [input.cacheResponsePlugin] Allows the\n * caller to override the default check for cacheability, for\n * situations in which the cacheability check wasn't explicitly\n * configured when constructing the `RequestWrapper`.\n * @param {boolean} [input.cleanRedirects] If true, a \"clean\" copy of any\n * redirected responses will be added to the cache, since redirected responses\n * [can't be used](https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1)\n * to satisfy navigation requests. Defaults to false.\n * @return {Promise.<Response>} The network response.\n */\n async fetchAndCache(\n {request, waitOnCache, cacheKey, cacheResponsePlugin, cleanRedirects}) {\n atLeastOne({request});\n\n let cachingComplete;\n const response = await this.fetch({request});\n\n // We need flexibility in determining whether a given response should\n // be added to the cache. There are several possible ways that this logic\n // might be specified, and they're given the following precedence:\n // 1. Passing in a `CacheableResponsePlugin` to the `RequestWrapper`\n // constructor, which sets this._userSpecifiedCachableResponsePlugin.\n // 2. Passing in a parameter to the fetchAndCache() method (done by certain\n // runtime handlers, like `StaleWhileRevalidate`), which sets\n // cacheResponsePlugin.\n // 3. The default that applies to anything using the `RequestWrapper` class\n // that doesn't specify the custom behavior, which is accessed via\n // the this.getDefaultCacheableResponsePlugin().\n const effectiveCacheableResponsePlugin =\n this._userSpecifiedCachableResponsePlugin ||\n cacheResponsePlugin ||\n this.getDefaultCacheableResponsePlugin();\n\n // Whichever plugin we've decided is appropriate, we now call its\n // cacheWillUpdate() method to determine cacheability of the response.\n const cacheable = await effectiveCacheableResponsePlugin.cacheWillUpdate(\n {request, response});\n\n if (cacheable) {\n // If cleanRedirects is set and this is a redirected response, then\n // get a \"clean\" copy to add to the cache.\n const newResponse = cleanRedirects && response.redirected ?\n await cleanResponseCopy({response}) :\n response.clone();\n\n // cachingComplete is a promise that may or may not be used to delay the\n // completion of this method, depending on the value of `waitOnCache`.\n cachingComplete = this.getCache().then(async (cache) => {\n let oldResponse;\n const cacheRequest = cacheKey || request;\n\n // Only bother getting the old response if the new response isn't opaque\n // and there's at least one cacheDidUpdate plugin. Otherwise, we don't\n // need it.\n if (response.type !== 'opaque' &&\n this.plugins.has('cacheDidUpdate')) {\n oldResponse = await this.match({request: cacheRequest});\n }\n\n // Regardless of whether or not we'll end up invoking\n // cacheDidUpdate, wait until the cache is updated.\n await cache.put(cacheRequest, newResponse);\n\n if (this.plugins.has('cacheDidUpdate')) {\n for (let plugin of this.plugins.get('cacheDidUpdate')) {\n await plugin.cacheDidUpdate({\n cacheName: this.cacheName,\n oldResponse,\n newResponse,\n // cacheRequest may be a Request with a url property, or a string.\n url: ('url' in cacheRequest) ? cacheRequest.url : cacheRequest,\n });\n }\n }\n });\n } else if (!cacheable && waitOnCache) {\n // If the developer requested to wait on the cache but the response\n // isn't cacheable, throw an error.\n throw ErrorFactory.createError('invalid-response-for-caching');\n }\n\n // Only conditionally await the caching completion, giving developers the\n // option of returning early for, e.g., read-through-caching scenarios.\n if (waitOnCache && cachingComplete) {\n await cachingComplete;\n }\n\n return response;\n }\n}\n\nexport default RequestWrapper;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport RequestWrapper from './request-wrapper';\n\n/**\n * This a base class which each caching strategy extends.\n *\n * @memberof module:workbox-runtime-caching\n */\nclass Handler {\n /**\n * Constructor for a new Handler instance.\n *\n * @param {Object} input\n * @param {boolean} [input.waitOnCache] For handlers that write to the cache,\n * `true` means the method should wait for the `cache.put()` call to\n * complete before returning. The default value of `false` means\n * return without waiting. It this value is true and the response\n * can't be cached, an error will be thrown.\n * @param {module:workbox-runtime-caching.RequestWrapper}\n * [input.requestWrapper] An optional `RequestWrapper` that is used to\n * configure the cache name and request plugins. If not provided, a\n * new `RequestWrapper` using the [default cache name](#getDefaultCacheName)\n * will be used.\n */\n constructor({requestWrapper, waitOnCache} = {}) {\n if (requestWrapper) {\n this.requestWrapper = requestWrapper;\n } else {\n this.requestWrapper = new RequestWrapper();\n }\n\n this.waitOnCache = Boolean(waitOnCache);\n }\n\n /**\n * An abstract method that each subclass must implement.\n *\n * @abstract\n * @param {Object} input\n * @param {FetchEvent} input.event The event that triggered the service\n * worker's fetch handler.\n * @param {Object} [input.params] Additional parameters that might be passed\n * in to the method. If used in conjunction with the\n * {@link module:workbox-routing.Route|Route} class, then the return\n * value from the `match` function in the Route constructor\n * will be passed in as the `params` value.\n * @return {Promise.<Response>} A promise resolving with a response.\n */\n handle({event, params} = {}) {\n throw Error('This abstract method must be implemented in a subclass.');\n }\n}\n\nexport default Handler;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport Handler from './handler';\nimport {isInstance} from '../../../../lib/assert';\n\n/**\n * An implementation of a [cache-first](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-falling-back-to-network)\n * request strategy.\n *\n * The important thing to note with this caching strategy is that once a\n * response is cached, it will not be updated. This is useful for assets\n * that are revisioned since it caches the asset long term and doesn't waste\n * the user's data.\n *\n * @example\n * // Set up a route to match any requests made for URLs that end in .txt.\n * // The requests are handled with a cache-first strategy.\n * const route = new workbox.routing.RegExpRoute({\n * regExp: /\\.txt$/,\n * handler: new workbox.runtimeCaching.CacheFirst(),\n * });\n *\n * const router = new workbox.routing.Router();\n * router.registerRoute({route});\n *\n * @memberof module:workbox-runtime-caching\n * @extends module:workbox-runtime-caching.Handler\n */\nclass CacheFirst extends Handler {\n /**\n * The handle method will be called by the\n * {@link module:workbox-routing.Route|Route} class when a route matches a\n * request.\n *\n * @param {Object} input\n * @param {FetchEvent} input.event The event that triggered the service\n * worker's fetch handler.\n * @return {Promise.<Response>} The response, either from the cache,\n * or if that isn't available, the request will be made on the\n * the network and the result will be cached for future use.\n */\n async handle({event} = {}) {\n isInstance({event}, FetchEvent);\n\n const cachedResponse = await this.requestWrapper.match({\n request: event.request,\n });\n\n return cachedResponse || await this.requestWrapper.fetchAndCache({\n request: event.request,\n waitOnCache: this.waitOnCache,\n });\n }\n}\n\nexport default CacheFirst;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport Handler from './handler';\nimport {isInstance} from '../../../../lib/assert';\n\n/**\n * An implementation of a [cache-only](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-only)\n * request strategy.\n *\n * The advantage to using this versus directly calling `caches.match()` is that\n * it will use the cache configuration and trigger the plugins defined in\n * the underlying `RequestWrapper` which accounts for behaviors like cache\n * expiration.\n *\n * @example\n * // Set up a route to match any requests made for URLs that end in .txt.\n * // The requests are handled with a cache-only strategy.\n * const route = new workbox.routing.RegExpRoute({\n * regExp: /\\.txt$/,\n * handler: new workbox.runtimeCaching.CacheOnly(),\n * });\n *\n * const router = new workbox.routing.Router();\n * router.registerRoute({route});\n *\n * @memberof module:workbox-runtime-caching\n * @extends module:workbox-runtime-caching.Handler\n */\nclass CacheOnly extends Handler {\n /**\n * The handle method will be called by the\n * {@link module:workbox-routing.Route|Route} class when a route matches a\n * request.\n *\n * @param {Object} input\n * @param {FetchEvent} input.event The event that triggered the service\n * worker's fetch handler.\n * @return {Promise.<Response>} The response from the cache or null.\n */\n async handle({event} = {}) {\n isInstance({event}, FetchEvent);\n\n return await this.requestWrapper.match({request: event.request});\n }\n}\n\nexport default CacheOnly;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport {CacheableResponsePlugin} from\n '../../../workbox-cacheable-response/src/index';\nimport ErrorFactory from './error-factory';\nimport Handler from './handler';\nimport {isType, isInstance} from '../../../../lib/assert';\n\n/**\n * An implementation of a [network first](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#network-falling-back-to-cache)\n * request strategy.\n *\n * By default, `NetworkFirst` will cache responses with a 200 status code as\n * well as [opaque responses](http://stackoverflow.com/q/39109789)\n * (responses from cross-origin servers which don't support\n * [CORS](https://enable-cors.org/)). You can override this default by passing\n * in a `RequestWrapper` that includes an appropriately-configured\n * `CacheableResponsePlugin`.\n *\n * @example\n * // Set up a route to match any requests made for URLs that end in .txt.\n * // The requests are handled with a network-first strategy.\n * const route = new workbox.routing.RegExpRoute({\n * regExp: /\\.txt$/,\n * handler: new workbox.runtimeCaching.NetworkFirst(),\n * });\n *\n * const router = new workbox.routing.Router();\n * router.registerRoute({route});\n *\n * @memberof module:workbox-runtime-caching\n * @extends module:workbox-runtime-caching.Handler\n */\nclass NetworkFirst extends Handler {\n /**\n * Constructor for a new NetworkFirst instance.\n *\n * @param {Object} input\n * @param {number} [input.networkTimeoutSeconds] If set, and a valid network\n * response isn't returned, then the cached response\n * will be returned instead. If there is no previously cached response,\n * then an `null` response will be returned. This option is meant to\n * combat \"[lie-fi](https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi)\"\n * scenarios.\n * @param {RequestWrapper} [input.requestWrapper] An optional `RequestWrapper`\n * that is used to configure the cache name and request plugins. If\n * not provided, a new `RequestWrapper` using the\n * [default cache name](#getDefaultCacheName) will be used.\n */\n constructor(input = {}) {\n super(input);\n\n this._cacheablePlugin = new CacheableResponsePlugin({statuses: [0, 200]});\n\n const {networkTimeoutSeconds} = input;\n if (networkTimeoutSeconds) {\n isType({networkTimeoutSeconds}, 'number');\n this.networkTimeoutSeconds = networkTimeoutSeconds;\n }\n }\n\n /**\n * The handle method will be called by the\n * {@link module:workbox-routing.Route|Route} class when a route matches a\n * request.\n *\n * @param {Object} input\n * @param {FetchEvent} input.event The event that triggered the service\n * worker's fetch handler.\n * @return {Promise.<Response>} The response from the network, or if that's\n * not available, a previously cached response.\n */\n async handle({event} = {}) {\n isInstance({event}, FetchEvent);\n\n const promises = [];\n let timeoutId;\n\n if (this.networkTimeoutSeconds) {\n promises.push(new Promise((resolve) => {\n timeoutId = setTimeout(() => {\n resolve(this.requestWrapper.match({request: event.request}));\n }, this.networkTimeoutSeconds * 1000);\n }));\n }\n\n const networkPromise = this.requestWrapper.fetchAndCache({\n request: event.request,\n waitOnCache: this.waitOnCache,\n cacheResponsePlugin: this._cacheablePlugin,\n }).then((response) => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n return response ?\n response :\n Promise.reject(ErrorFactory.createError('no-response-received'));\n }).catch(() => this.requestWrapper.match({request: event.request}));\n\n promises.push(networkPromise);\n\n return Promise.race(promises);\n }\n}\n\nexport default NetworkFirst;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport Handler from './handler';\nimport {isInstance} from '../../../../lib/assert';\n\n/**\n * An implementation of a [network-only](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#network-only)\n * request strategy.\n *\n * The advantage to using this versus directly calling `fetch()` is that it will\n * trigger the plugins defined in the underlying `RequestWrapper`.\n *\n *\n * @example\n * // Set up a route to match any requests made for URLs that end in .txt.\n * // The requests are handled with a network-only strategy.\n * const route = new workbox.routing.RegExpRoute({\n * regExp: /\\.txt$/,\n * handler: new workbox.runtimeCaching.NetworkOnly(),\n * });\n *\n * const router = new workbox.routing.Router();\n * router.registerRoute({route});\n *\n * @memberof module:workbox-runtime-caching\n * @extends module:workbox-runtime-caching.Handler\n */\nclass NetworkOnly extends Handler {\n /**\n * The handle method will be called by the\n * {@link module:workbox-routing.Route|Route} class when a route matches a\n * request.\n *\n * @param {Object} input\n * @param {FetchEvent} input.event The event that triggered the service\n * worker's fetch handler.\n * @return {Promise.<Response>} The response from the network.\n */\n async handle({event} = {}) {\n isInstance({event}, FetchEvent);\n\n return await this.requestWrapper.fetch({request: event.request});\n }\n}\n\nexport default NetworkOnly;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport {CacheableResponsePlugin} from\n '../../../workbox-cacheable-response/src/index';\nimport Handler from './handler';\nimport {isInstance} from '../../../../lib/assert';\n\n/**\n * An implementation of a [stale-while-revalidate](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#stale-while-revalidate)\n * request strategy.\n *\n * Resources are requested from both the cache and the network in parallel, then\n * responds with the cached version. The cache is replaced with whatever returns\n * from the network. In addition to updating the appropriate caches, it will\n * also trigger any appropriate plugins defined in the underlying\n * `RequestWrapper`.\n *\n * By default, `StaleWhileRevalidate` will cache responses with a 200 status\n * code as well as [opaque responses](http://stackoverflow.com/q/39109789)\n * (responses from cross-origin servers which don't support\n * [CORS](https://enable-cors.org/)). You can override this default by passing\n * in a `RequestWrapper` that includes an appropriately-configured\n * `CacheableResponsePlugin`.\n *\n * @example\n * // Set up a route to match any requests made for URLs that end in .txt.\n * // The requests are handled with a stale-while-revalidate strategy.\n * const route = new workbox.routing.RegExpRoute({\n * regExp: /\\.txt$/,\n * handler: new workbox.runtimeCaching.StaleWhileRevalidate(),\n * });\n *\n * const router = new workbox.routing.Router();\n * router.registerRoute({route});\n *\n * @memberof module:workbox-runtime-caching\n * @extends module:workbox-runtime-caching.Handler\n */\nclass StaleWhileRevalidate extends Handler {\n /**\n * Constructor for a new StaleWhileRevalidate instance.\n *\n * @param {Object} input\n * @param {\n * module:workbox-runtime-caching.RequestWrapper} [input.requestWrapper]\n * An optional `RequestWrapper` that is used to\n * configure the cache name and request plugins. If\n * not provided, a new `RequestWrapper` using the\n * [default cache name](#defaultCacheName) will be used.\n */\n constructor(input = {}) {\n super(input);\n\n this._cacheablePlugin = new CacheableResponsePlugin({statuses: [0, 200]});\n }\n\n /**\n * The handle method will be called by the\n * {@link module:workbox-routing.Route|Route} class when a route matches a\n * request.\n *\n * @param {Object} input\n * @param {FetchEvent} input.event The event that triggered the service\n * worker's fetch handler.\n * @return {Promise.<Response>} The response from the cache, if present, or\n * from the network if not.\n */\n async handle({event} = {}) {\n isInstance({event}, FetchEvent);\n\n const fetchAndCacheResponse = this.requestWrapper.fetchAndCache({\n request: event.request,\n waitOnCache: this.waitOnCache,\n cacheResponsePlugin: this._cacheablePlugin,\n }).catch(() => Response.error());\n\n const cachedResponse = await this.requestWrapper.match({\n request: event.request,\n });\n\n return cachedResponse || await fetchAndCacheResponse;\n }\n}\n\nexport default StaleWhileRevalidate;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nlet tmpIdbName = `workbox-cache-expiration`;\nif (self && self.registration) {\n tmpIdbName += `-${self.registration.scope}`;\n}\nexport const idbName = tmpIdbName;\nexport const idbVersion = 1;\nexport const urlPropertyName = 'url';\nexport const timestampPropertyName = 'timestamp';\n","'use strict';\n\n(function() {\n function toArray(arr) {\n return Array.prototype.slice.call(arr);\n }\n\n function promisifyRequest(request) {\n return new Promise(function(resolve, reject) {\n request.onsuccess = function() {\n resolve(request.result);\n };\n\n request.onerror = function() {\n reject(request.error);\n };\n });\n }\n\n function promisifyRequestCall(obj, method, args) {\n var request;\n var p = new Promise(function(resolve, reject) {\n request = obj[method].apply(obj, args);\n promisifyRequest(request).then(resolve, reject);\n });\n\n p.request = request;\n return p;\n }\n\n function promisifyCursorRequestCall(obj, method, args) {\n var p = promisifyRequestCall(obj, method, args);\n return p.then(function(value) {\n if (!value) return;\n return new Cursor(value, p.request);\n });\n }\n\n function proxyProperties(ProxyClass, targetProp, properties) {\n properties.forEach(function(prop) {\n Object.defineProperty(ProxyClass.prototype, prop, {\n get: function() {\n return this[targetProp][prop];\n },\n set: function(val) {\n this[targetProp][prop] = val;\n }\n });\n });\n }\n\n function proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) {\n properties.forEach(function(prop) {\n if (!(prop in Constructor.prototype)) return;\n ProxyClass.prototype[prop] = function() {\n return promisifyRequestCall(this[targetProp], prop, arguments);\n };\n });\n }\n\n function proxyMethods(ProxyClass, targetProp, Constructor, properties) {\n properties.forEach(function(prop) {\n if (!(prop in Constructor.prototype)) return;\n ProxyClass.prototype[prop] = function() {\n return this[targetProp][prop].apply(this[targetProp], arguments);\n };\n });\n }\n\n function proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) {\n properties.forEach(function(prop) {\n if (!(prop in Constructor.prototype)) return;\n ProxyClass.prototype[prop] = function() {\n return promisifyCursorRequestCall(this[targetProp], prop, arguments);\n };\n });\n }\n\n function Index(index) {\n this._index = index;\n }\n\n proxyProperties(Index, '_index', [\n 'name',\n 'keyPath',\n 'multiEntry',\n 'unique'\n ]);\n\n proxyRequestMethods(Index, '_index', IDBIndex, [\n 'get',\n 'getKey',\n 'getAll',\n 'getAllKeys',\n 'count'\n ]);\n\n proxyCursorRequestMethods(Index, '_index', IDBIndex, [\n 'openCursor',\n 'openKeyCursor'\n ]);\n\n function Cursor(cursor, request) {\n this._cursor = cursor;\n this._request = request;\n }\n\n proxyProperties(Cursor, '_cursor', [\n 'direction',\n 'key',\n 'primaryKey',\n 'value'\n ]);\n\n proxyRequestMethods(Cursor, '_cursor', IDBCursor, [\n 'update',\n 'delete'\n ]);\n\n // proxy 'next' methods\n ['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) {\n if (!(methodName in IDBCursor.prototype)) return;\n Cursor.prototype[methodName] = function() {\n var cursor = this;\n var args = arguments;\n return Promise.resolve().then(function() {\n cursor._cursor[methodName].apply(cursor._cursor, args);\n return promisifyRequest(cursor._request).then(function(value) {\n if (!value) return;\n return new Cursor(value, cursor._request);\n });\n });\n };\n });\n\n function ObjectStore(store) {\n this._store = store;\n }\n\n ObjectStore.prototype.createIndex = function() {\n return new Index(this._store.createIndex.apply(this._store, arguments));\n };\n\n ObjectStore.prototype.index = function() {\n return new Index(this._store.index.apply(this._store, arguments));\n };\n\n proxyProperties(ObjectStore, '_store', [\n 'name',\n 'keyPath',\n 'indexNames',\n 'autoIncrement'\n ]);\n\n proxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [\n 'put',\n 'add',\n 'delete',\n 'clear',\n 'get',\n 'getAll',\n 'getKey',\n 'getAllKeys',\n 'count'\n ]);\n\n proxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [\n 'openCursor',\n 'openKeyCursor'\n ]);\n\n proxyMethods(ObjectStore, '_store', IDBObjectStore, [\n 'deleteIndex'\n ]);\n\n function Transaction(idbTransaction) {\n this._tx = idbTransaction;\n this.complete = new Promise(function(resolve, reject) {\n idbTransaction.oncomplete = function() {\n resolve();\n };\n idbTransaction.onerror = function() {\n reject(idbTransaction.error);\n };\n idbTransaction.onabort = function() {\n reject(idbTransaction.error);\n };\n });\n }\n\n Transaction.prototype.objectStore = function() {\n return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments));\n };\n\n proxyProperties(Transaction, '_tx', [\n 'objectStoreNames',\n 'mode'\n ]);\n\n proxyMethods(Transaction, '_tx', IDBTransaction, [\n 'abort'\n ]);\n\n function UpgradeDB(db, oldVersion, transaction) {\n this._db = db;\n this.oldVersion = oldVersion;\n this.transaction = new Transaction(transaction);\n }\n\n UpgradeDB.prototype.createObjectStore = function() {\n return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments));\n };\n\n proxyProperties(UpgradeDB, '_db', [\n 'name',\n 'version',\n 'objectStoreNames'\n ]);\n\n proxyMethods(UpgradeDB, '_db', IDBDatabase, [\n 'deleteObjectStore',\n 'close'\n ]);\n\n function DB(db) {\n this._db = db;\n }\n\n DB.prototype.transaction = function() {\n return new Transaction(this._db.transaction.apply(this._db, arguments));\n };\n\n proxyProperties(DB, '_db', [\n 'name',\n 'version',\n 'objectStoreNames'\n ]);\n\n proxyMethods(DB, '_db', IDBDatabase, [\n 'close'\n ]);\n\n // Add cursor iterators\n // TODO: remove this once browsers do the right thing with promises\n ['openCursor', 'openKeyCursor'].forEach(function(funcName) {\n [ObjectStore, Index].forEach(function(Constructor) {\n Constructor.prototype[funcName.replace('open', 'iterate')] = function() {\n var args = toArray(arguments);\n var callback = args[args.length - 1];\n var nativeObject = this._store || this._index;\n var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1));\n request.onsuccess = function() {\n callback(request.result);\n };\n };\n });\n });\n\n // polyfill getAll\n [Index, ObjectStore].forEach(function(Constructor) {\n if (Constructor.prototype.getAll) return;\n Constructor.prototype.getAll = function(query, count) {\n var instance = this;\n var items = [];\n\n return new Promise(function(resolve) {\n instance.iterateCursor(query, function(cursor) {\n if (!cursor) {\n resolve(items);\n return;\n }\n items.push(cursor.value);\n\n if (count !== undefined && items.length == count) {\n resolve(items);\n return;\n }\n cursor.continue();\n });\n });\n };\n });\n\n var exp = {\n open: function(name, version, upgradeCallback) {\n var p = promisifyRequestCall(indexedDB, 'open', [name, version]);\n var request = p.request;\n\n request.onupgradeneeded = function(event) {\n if (upgradeCallback) {\n upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction));\n }\n };\n\n return p.then(function(db) {\n return new DB(db);\n });\n },\n delete: function(name) {\n return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]);\n }\n };\n\n if (typeof module !== 'undefined') {\n module.exports = exp;\n module.exports.default = module.exports;\n }\n else {\n self.idb = exp;\n }\n}());\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport ErrorFactory from '../../../../lib/error-factory';\n\nconst errors = {\n 'max-entries-or-age-required': `Either the maxEntries or maxAgeSeconds\n parameters (or both) are required when constructing Plugin.`,\n 'max-entries-must-be-number': `The maxEntries parameter to the Plugin\n constructor must either be a number or undefined.`,\n 'max-age-seconds-must-be-number': `The maxAgeSeconds parameter to the Plugin\n constructor must either be a number or undefined.`,\n};\n\nexport default new ErrorFactory(errors);\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport idb from 'idb';\nimport {isType, isInstance, isArrayOfType} from '../../../../lib/assert';\nimport logHelper from '../../../../lib/log-helper';\nimport {\n idbName,\n idbVersion,\n urlPropertyName,\n timestampPropertyName,\n} from './constants';\nimport ErrorFactory from './error-factory';\n\n/**\n * The `CacheExpiration` class allows you define an expiration and / or\n * limit on the responses cached.\n *\n * @example\n * const cacheExpiration = new workbox.cacheExpiration.CacheExpiration({\n * maxEntries: 2,\n * maxAgeSeconds: 10,\n * });\n *\n * @memberof module:workbox-cache-expiration\n */\nclass CacheExpiration {\n /**\n * Creates a new `CacheExpiration` instance, which is used to remove entries\n * from a [`Cache`](https://developer.mozilla.org/en-US/docs/Web/API/Cache)\n * once certain criteria—max number of entries, age of entry, or both—is met.\n *\n * @param {Object} input\n * @param {Number} [input.maxEntries] The maximum number of entries to cache.\n * Entries will be expired using a least recently used (LRU) policy once\n * the cache reaches this threshold.\n * @param {Number} [input.maxAgeSeconds] The maximum age of an entry before\n * it's treated as staled and removed.\n */\n constructor({maxEntries, maxAgeSeconds} = {}) {\n if (!(maxEntries || maxAgeSeconds)) {\n throw ErrorFactory.createError('max-entries-or-age-required');\n }\n\n if (maxEntries && typeof maxEntries !== 'number') {\n throw ErrorFactory.createError('max-entries-must-be-number');\n }\n\n if (maxAgeSeconds && typeof maxAgeSeconds !== 'number') {\n throw ErrorFactory.createError('max-age-seconds-must-be-number');\n }\n\n this.maxEntries = maxEntries;\n this.maxAgeSeconds = maxAgeSeconds;\n\n // These are used to keep track of open IndexDB and Caches for a given name.\n this._dbs = new Map();\n this._caches = new Map();\n\n // This is used to ensure there's one asynchronous expiration operation\n // running at a time.\n this._expirationMutex = false;\n // If another expiration request comes in, the timestamp is saved here and\n // re-run after.\n this._timestampForNextRun = null;\n }\n\n /**\n * Returns a promise for the IndexedDB database used to keep track of state.\n *\n * @private\n * @param {Object} input\n * @param {string} input.cacheName Name of the cache the Responses belong to.\n * @return {DB} An open DB instance.\n */\n async getDB({cacheName} = {}) {\n isType({cacheName}, 'string');\n\n const idbId = `${idbName}-${cacheName}`;\n if (!this._dbs.has(idbId)) {\n const openDb = await idb.open(idbId, idbVersion, (upgradeDB) => {\n const objectStore = upgradeDB.createObjectStore(cacheName,\n {keyPath: urlPropertyName});\n objectStore.createIndex(timestampPropertyName, timestampPropertyName,\n {unique: false});\n });\n this._dbs.set(idbId, openDb);\n }\n\n return this._dbs.get(idbId);\n }\n\n /**\n * Returns a promise for an open Cache instance named `cacheName`.\n *\n * @private\n * @param {Object} input\n * @param {string} input.cacheName Name of the cache the Responses belong to.\n * @return {Cache} An open Cache instance.\n */\n async getCache({cacheName} = {}) {\n isType({cacheName}, 'string');\n\n if (!this._caches.has(cacheName)) {\n const openCache = await caches.open(cacheName);\n this._caches.set(cacheName, openCache);\n }\n\n return this._caches.get(cacheName);\n }\n\n /**\n * Checks whether a `Response` is \"fresh\", based on the `Response's`\n * `Date` header and the `maxAgeSeconds` parameter passed into the\n * constructor.\n *\n * The general approach is to default to fresh unless proven otherwise.\n *\n * If `maxAgeSeconds` or the `Date` header is not set then it will\n * default to returning `true`, i.e. the response is still fresh and should\n * be used.\n *\n * @param {Object} input\n * @param {string} input.cacheName Name of the cache the responses belong to.\n * @param {Response} input.cachedResponse The `Response` object that's been\n * read from a cache and whose freshness should be checked.\n * @param {Number} [input.now] A timestamp.\n *\n * Defaults to the current time.\n * @return {boolean} Either `true` if the response is fresh, or\n * `false` if the `Response` is older than `maxAgeSeconds` and should no\n * longer be used.\n *\n * @example\n * expirationPlugin.isResponseFresh({\n * cachedResponse: responseFromCache\n * });\n */\n isResponseFresh({cacheName, cachedResponse, now} = {}) {\n // Only bother checking for freshness if we have a valid response and if\n // maxAgeSeconds is set.\n if (cachedResponse && this.maxAgeSeconds) {\n isInstance({cachedResponse}, Response);\n\n const dateHeader = cachedResponse.headers.get('date');\n if (dateHeader) {\n if (typeof now === 'undefined') {\n now = Date.now();\n }\n\n const parsedDate = new Date(dateHeader);\n const headerTime = parsedDate.getTime();\n // If the Date header was invalid for some reason, parsedDate.getTime()\n // will return NaN. We want to treat that as a fresh response, since we\n // assume fresh unless proven otherwise.\n if (isNaN(headerTime)) {\n return true;\n }\n\n // If we have a valid headerTime, then our response is fresh iff the\n // headerTime plus maxAgeSeconds is greater than the current time.\n return (headerTime + (this.maxAgeSeconds * 1000)) > now;\n } else {\n // TODO (jeffposnick): Change this method interface to be async, and\n // check for the IDB for the specific URL in order to determine\n // freshness when Date is not available.\n\n // If there is no Date header (i.e. if this is a cross-origin response),\n // then we don't know for sure whether the response is fresh or not.\n // One thing we can do is trigger cache expiration, which will clean up\n // any old responses based on IDB timestamps, and ensure that when a\n // cache-first handler is used, stale responses will eventually be\n // replaced (though not until the *next* request is made).\n // See https://github.com/GoogleChrome/workbox/issues/691\n this.expireEntries({cacheName, now});\n // Return true, since otherwise a cross-origin cached response without\n // a Date header would *never* be considered valid.\n return true;\n }\n }\n\n // If either cachedResponse or maxAgeSeconds wasn't set, then the response\n // is \"trivially\" fresh, so return true.\n return true;\n }\n\n /**\n * Updates the timestamp stored in IndexedDB for `url` to be equal to `now`.\n *\n * When using this class directly (i.e. not via `CacheExpirationPlugin`),\n * it's your responsibility to call `updateTimestap()` each time an entry is\n * put into the cache. Otherwise, the `expireEntries()` method will not\n * know which entries to remove.\n *\n * @example\n * expirationPlugin.updateTimestamp({\n * cacheName: 'example-cache-name',\n * url: '/example-url'\n * });\n *\n * @param {Object} input\n * @param {string} input.cacheName Name of the cache the Responses belong to.\n * @param {string} input.url The URL for the entry to update. The hash portion\n * of the URL will be ignored.\n * @param {Number} [input.now] A timestamp. Defaults to the current time.\n */\n async updateTimestamp({cacheName, url, now} = {}) {\n isType({url}, 'string');\n isType({cacheName}, 'string');\n\n // Remove the hash, if present.\n const urlObject = new URL(url, location);\n urlObject.hash = '';\n\n if (typeof now === 'undefined') {\n now = Date.now();\n }\n\n const db = await this.getDB({cacheName});\n const tx = db.transaction(cacheName, 'readwrite');\n tx.objectStore(cacheName).put({\n [timestampPropertyName]: now,\n [urlPropertyName]: urlObject.href,\n });\n\n await tx.complete;\n }\n\n /**\n * Expires entries based on the the maximum age and the maximum number\n * of entries defined in the constructor.\n *\n * To avoid concurrency issues, calls to this method when it's already running\n * will result in the call begin re-run after the current execution has\n * finished.\n *\n * @param {Object} input\n * @param {string} input.cacheName Name of the cache to review and expire\n * entries for.\n * @param {Number} [input.now] A timestamp to treat as now. This is largely\n * only useful for testing purposes.\n *\n * Defaults to the current time.\n * @return {Promise} Resolves when the cache expiration has been performed. If\n * the function is currently executing the Promise will resolve immediately.\n *\n * @example\n * // Assume that entries have been added to 'example-cache-name', and that\n * // updateTimestamp() was called after each entry was added.\n * cacheExpiration.expireEntries({\n * cacheName: 'example-cache-name'\n * });\n */\n async expireEntries({cacheName, now} = {}) {\n // Since there's a single shared IDB instance that's queried to find entries\n // to expire, this method doesn't need to run multiple times simultaneously.\n // Use this._expirationMutex as a concurrency lock, and save the last value\n // that it's been called with in this._timestampForNextRun as a signal\n // to run it again once complete.\n if (this._expirationMutex) {\n this._timestampForNextRun = now;\n return;\n }\n this._expirationMutex = true;\n\n isType({cacheName}, 'string');\n\n if (typeof now === 'undefined') {\n now = Date.now();\n }\n\n // First, expire old entries, if maxAgeSeconds is set.\n const oldEntries = this.maxAgeSeconds ?\n await this.findOldEntries({cacheName, now}) :\n [];\n\n // Once that's done, check for the maximum size.\n const extraEntries = this.maxEntries ?\n await this.findExtraEntries({cacheName}) :\n [];\n\n // Use a Set to remove any duplicates following the concatenation, then\n // convert back into an array.\n const urls = [...new Set(oldEntries.concat(extraEntries))];\n await this.deleteFromCacheAndIDB({cacheName, urls});\n\n if (urls.length > 0) {\n logHelper.debug({\n that: this,\n message: 'Expired entries have been removed from the cache.',\n data: {cacheName, urls},\n });\n }\n\n this._expirationMutex = false;\n // If this method has been called while it was already running, then call\n // it again now that the asynchronous operations are complete, using the\n // most recent timestamp that was passed in.\n if (this._timestampForNextRun) {\n const savedTimestamp = this._timestampForNextRun;\n this._timestampForNextRun = null;\n return this.expireEntries({cacheName, now: savedTimestamp});\n }\n }\n\n /**\n * Expires entries based on the the maximum age.\n *\n * @private\n * @param {Object} input\n * @param {string} input.cacheName Name of the cache the Responses belong to.\n * @param {Number} [input.now] A timestamp.\n * @return {Array<string>} A list of the URLs that were expired.\n */\n async findOldEntries({cacheName, now} = {}) {\n isType({cacheName}, 'string');\n isType({now}, 'number');\n\n const expireOlderThan = now - (this.maxAgeSeconds * 1000);\n const urls = [];\n const db = await this.getDB({cacheName});\n const tx = db.transaction(cacheName, 'readonly');\n const store = tx.objectStore(cacheName);\n const timestampIndex = store.index(timestampPropertyName);\n\n timestampIndex.iterateCursor((cursor) => {\n if (!cursor) {\n return;\n }\n\n if (cursor.value[timestampPropertyName] < expireOlderThan) {\n urls.push(cursor.value[urlPropertyName]);\n }\n\n cursor.continue();\n });\n\n await tx.complete;\n return urls;\n }\n\n /**\n * Finds the URLs that should be expired as per the current state of IndexedDB\n * and the `maxEntries` configuration. A least-recently used policy is\n * enforced, so if `maxEntries` is `N`, and there are `N + M` URLs listed in\n * IndexedDB, then this function will return the least-recently used `M` URLs.\n *\n * @private\n * @param {Object} input\n * @param {string} input.cacheName Name of the cache the Responses belong to.\n * @return {Array<string>} A list of the URLs that are candidates for\n * expiration.\n */\n async findExtraEntries({cacheName} = {}) {\n isType({cacheName}, 'string');\n\n const urls = [];\n const db = await this.getDB({cacheName});\n let tx = db.transaction(cacheName, 'readonly');\n let store = tx.objectStore(cacheName);\n let timestampIndex = store.index(timestampPropertyName);\n const initialCount = await timestampIndex.count();\n\n if (initialCount > this.maxEntries) {\n // We need to create a new transaction to make Firefox happy.\n tx = db.transaction(cacheName, 'readonly');\n store = tx.objectStore(cacheName);\n timestampIndex = store.index(timestampPropertyName);\n\n timestampIndex.iterateCursor((cursor) => {\n if (!cursor) {\n return;\n }\n\n urls.push(cursor.value[urlPropertyName]);\n\n if (initialCount - urls.length > this.maxEntries) {\n cursor.continue();\n }\n });\n }\n\n await tx.complete;\n return urls;\n }\n\n /**\n * Removes entries corresponding to each of the URLs from both the Cache\n * Storage API and from IndexedDB.\n *\n * @private\n * @param {Object} input\n * @param {string} input.cacheName Name of the cache the Responses belong to.\n * @param {Array<string>} urls The URLs to delete.\n */\n async deleteFromCacheAndIDB({cacheName, urls} = {}) {\n isType({cacheName}, 'string');\n isArrayOfType({urls}, 'string');\n\n if (urls.length > 0) {\n const cache = await this.getCache({cacheName});\n const db = await this.getDB({cacheName});\n\n for (let url of urls) {\n await cache.delete(url);\n const tx = db.transaction(cacheName, 'readwrite');\n const store = tx.objectStore(cacheName);\n store.delete(url);\n await tx.complete;\n }\n }\n }\n}\n\nexport default CacheExpiration;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport CacheExpiration from './cache-expiration';\nimport {isType, isInstance} from '../../../../lib/assert';\n\n/**\n * The `CacheExpirationPlugin` class allows you define an expiration and / or\n * limit on the responses cached.\n *\n * This class is meant to be automatically invoked as a plugin to a\n * {@link module:workbox-runtime-caching.RequestWrapper|RequestWrapper}, which\n * is used by the `workbox-sw` and `workbox-runtime-caching` modules.\n *\n * If you would like to use this functionality outside of the `RequestWrapper`\n * context, please use the [CacheExpiration]{@link\n * module:workbox-cache-expiration.CacheExpiration} class directly.\n *\n * @example\n * const plugin = new workbox.cacheExpiration.CacheExpirationPlugin({\n * maxEntries: 2,\n * maxAgeSeconds: 10,\n * });\n *\n * @memberof module:workbox-cache-expiration\n */\nclass CacheExpirationPlugin extends CacheExpiration {\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox.runtimeCaching` handlers when a `Response` is about to be returned\n * from a [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) to\n * the handler. It allows the `Response` to be inspected for freshness and\n * prevents it from being used if the `Response`'s `Date` header value is\n * older than the configured `maxAgeSeconds`.\n *\n * @private\n * @param {Object} input\n * @param {string} input.cacheName Name of the cache the responses belong to.\n * @param {Response} input.cachedResponse The `Response` object that's been\n * read from a cache and whose freshness should be checked.\n * @param {Number} [input.now] A timestamp. Defaults to the current time.\n * @return {Response} Either the `cachedResponse`, if it's\n * fresh, or `null` if the `Response` is older than `maxAgeSeconds`.\n */\n cachedResponseWillBeUsed({cacheName, cachedResponse, now} = {}) {\n if (this.isResponseFresh({cacheName, cachedResponse, now})) {\n return cachedResponse;\n }\n\n return null;\n }\n\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox.runtimeCaching` handlers when an entry is added to a cache.\n *\n * @private\n * @param {Object} input\n * @param {string} input.cacheName Name of the cache the responses belong to.\n * @param {Response} input.newResponse The new value in the cache.\n * @param {string} input.url The URL for the cache entry.\n * @param {Number} [input.now] A timestamp. Defaults to the current time.\n */\n async cacheDidUpdate({cacheName, newResponse, url, now} = {}) {\n isType({cacheName}, 'string');\n isInstance({newResponse}, Response);\n\n if (typeof now === 'undefined') {\n now = Date.now();\n }\n\n await this.updateTimestamp({cacheName, url, now});\n await this.expireEntries({cacheName, now});\n }\n}\n\nexport default CacheExpirationPlugin;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport ErrorFactory from '../../../../lib/error-factory';\n\nconst errors = {\n 'channel-name-required': `The channelName parameter is required when\n constructing a new BroadcastCacheUpdate instance.`,\n 'responses-are-same-parameters-required': `The first, second, and\n headersToCheck parameters must be valid when calling responsesAreSame()`,\n};\n\nexport default new ErrorFactory(errors);\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/**\n * This is a static variable for the cache updated message type. Useful for\n * comparing to the messages `type` parameter to identify the kind of message.\n *\n * @type {string}\n *\n * @example\n * // Prints 'CACHE_UPDATED'\n * console.log(workbox.broadcastCacheUpdate.cacheUpdatedMessageType);\n *\n * @memberof module:workbox-broadcast-cache-update\n */\nconst cacheUpdatedMessageType = 'CACHE_UPDATED';\n\n/**\n * The default headers to compare when determining whether two `Response`\n * objects are different.\n *\n * @private\n * @type {Array<string>}\n *\n * @memberof module:workbox-broadcast-cache-update\n */\nconst defaultHeadersToCheck = [\n 'content-length',\n 'etag',\n 'last-modified',\n];\n\n/**\n * The value `'workbox-broadcast-cache-update'`, used as the `meta` field of the\n * update message.\n *\n * @private\n * @type {string}\n *\n * @memberof module:workbox-broadcast-cache-update\n */\nconst defaultSource = 'workbox-broadcast-cache-update';\n\nexport {\n cacheUpdatedMessageType,\n defaultHeadersToCheck,\n defaultSource,\n};\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport {isType, isInstance} from '../../../../lib/assert';\nimport {cacheUpdatedMessageType} from './constants';\n\n/**\n * You would not normally call this method directly; it's called automatically\n * by an instance of the {@link BroadcastCacheUpdate} class. It's exposed here\n * for the benefit of developers who would rather not use the full\n * `BroadcastCacheUpdate` implementation.\n *\n * Calling this will dispatch a message on the provided {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel}\n * to notify interested subscribers about a change to a cached resource.\n *\n * The message that's posted has a formation inspired by the\n * [Flux standard action](https://github.com/acdlite/flux-standard-action#introduction)\n * format like so:\n *\n * ```\n * {\n * type: 'CACHE_UPDATED',\n * meta: 'workbox-broadcast-cache-update',\n * payload: {\n * cacheName: 'the-cache-name',\n * updatedUrl: 'https://example.com/'\n * }\n * }\n * ```\n *\n * (Usage of [Flux](https://facebook.github.io/flux/) itself is not at\n * all required.)\n *\n * @example\n * workbox.broadcastCacheUpdate.broadcastUpdate({\n * channel: new BroadcastChannel('Channel Name'),\n * cacheName: 'example-cache-name',\n * url: '/',\n * source: 'custom-library'\n * });\n *\n * @private\n * @memberof module:workbox-broadcast-cache-update\n *\n * @param {Object} input\n * @param {BroadcastChannel} input.channel The `BroadcastChannel` to use.\n * @param {string} input.cacheName The name of the cache in which the updated\n * `Response` was stored.\n * @param {string} input.url The URL associated with the updated `Response`.\n * @param {string} input.source A string identifying this library as the source\n * of the update message.\n */\nfunction broadcastUpdate({channel, cacheName, url, source} = {}) {\n isInstance({channel}, BroadcastChannel);\n isType({cacheName}, 'string');\n isType({source}, 'string');\n isType({url}, 'string');\n\n channel.postMessage({\n type: cacheUpdatedMessageType,\n meta: source,\n payload: {\n cacheName: cacheName,\n updatedUrl: url,\n },\n });\n}\n\nexport default broadcastUpdate;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport ErrorFactory from './error-factory';\nimport logHelper from '../../../../lib/log-helper.js';\n\n/**\n * Given two `Response's`, compares several header values to see if they are\n * the same or not.\n *\n * @example\n * const responseIsSame = responsesAreSame({\n * first: firstResponse,\n * second: secondResponse,\n * headersToCheck: [\n * 'content-length',\n * 'etag',\n * 'last-modified',\n * ]\n * });\n *\n * @private\n * @memberof module:workbox-broadcast-cache-update\n *\n * @param {Object} input\n * @param {Response} input.first One of the `Response`s.\n * @param {Response} input.second Another of the `Response`s.\n * @param {Array<string>} input.headersToCheck A list of headers that will be\n * used to determine whether the `Response`s differ.\n * @return {boolean} Whether or not the `Response` objects are assumed to be\n * the same.\n */\nfunction responsesAreSame({first, second, headersToCheck}={}) {\n if (!(first instanceof Response &&\n second instanceof Response &&\n headersToCheck instanceof Array)) {\n throw ErrorFactory.createError('responses-are-same-parameters-required');\n }\n\n const atLeastOneHeaderAvailable = headersToCheck.some((header) => {\n return first.headers.has(header) && second.headers.has(header);\n });\n if (!atLeastOneHeaderAvailable) {\n logHelper.log({\n message: `Unable to determine whether the response has been updated\n because none of the headers that would be checked are present.`,\n data: {\n 'First Response': first,\n 'Second Response': second,\n 'Headers To Check': JSON.stringify(headersToCheck),\n },\n });\n\n // Just return true, indicating the that responses are the same, since we\n // can't determine otherwise.\n return true;\n }\n\n return headersToCheck.every((header) => {\n return (first.headers.has(header) === second.headers.has(header)) &&\n (first.headers.get(header) === second.headers.get(header));\n });\n}\n\nexport default responsesAreSame;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport ErrorFactory from './error-factory';\nimport {isType} from '../../../../lib/assert';\nimport broadcastUpdate from './broadcast-update';\nimport responsesAreSame from './responses-are-same';\nimport {defaultHeadersToCheck, defaultSource} from './constants';\n\n/**\n * Can be used to compare two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * and uses the {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel API}\n * to notify interested parties when those responses differ.\n *\n * For efficiency's sake, the underlying response bodies are not compared;\n * only specific response headers are checked.\n *\n * This class can be used inside any service worker, without having to use any\n * of the other modules in this repo.\n *\n * If you'd like to use this functionality but are already using `workbox-sw` or\n * `workbox-runtime-caching`, please see use the\n * [BroadcastCacheUpdatePlugin]{@link\n * module:workbox-broadcast-cache-update.BroadcastCacheUpdatePlugin}\n * for a easy integration.\n *\n * @example <caption>Using BroadcastCacheUpdate to compare a cached and fetched\n * request.</caption>\n *\n * const url = '/path/to/file';\n * const cacheName = 'my-runtime-cache';\n *\n * const bcu = new workbox.broadcastCacheUpdate.BroadcastCacheUpdate({\n * channelName: 'cache-updates'\n * });\n *\n * caches.open(cacheName)\n * .then((openCache) => {\n * return Promise.all([\n * cache.match(url),\n * fetch(url)\n * ]);\n * })\n * .then((responses) => {\n * const cachedResponse = responses[0];\n * const fetchedResponse = responses[1];\n * if (cachedResponse) {\n * bcu.notifyIfUpdated({\n * cacheName,\n * cachedResponse,\n * fetchedResponse\n * });\n * }\n * });\n *\n * @memberof module:workbox-broadcast-cache-update\n */\nclass BroadcastCacheUpdate {\n /**\n * Dispatches cache update messages when a cached response has been updated.\n * Messages will be dispatched on a broadcast channel with the name provided\n * as the `channelName` parameter.\n *\n * @param {Object} input\n * @param {string} input.channelName The name that will be used when creating\n * the `BroadcastChannel`.\n * @param {Array<string>} input.headersToCheck A list of headers that will be\n * used to determine whether the responses differ.\n *\n * Defaults to `['content-length', 'etag', 'last-modified']`.\n * @param {string} input.source An attribution value that indicates where\n * the update originated.\n *\n * Defaults to `workbox-broadcast-cache-update`.\n */\n constructor({channelName, headersToCheck, source}={}) {\n if (typeof channelName !== 'string' || channelName.length === 0) {\n throw ErrorFactory.createError('channel-name-required');\n }\n\n this.channelName = channelName;\n this.headersToCheck = headersToCheck || defaultHeadersToCheck;\n this.source = source || defaultSource;\n }\n\n /**\n * @private\n * @return {BroadcastChannel} The underlying\n * [`BroadcastChannel`](https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel/BroadcastChannel)\n * instance used for broadcasting updates.\n */\n get channel() {\n if (!this._channel) {\n this._channel = new BroadcastChannel(this.channelName);\n }\n return this._channel;\n }\n\n /**\n * An explicit method to call from your own code to trigger the comparison of\n * two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * and send a message via the\n * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel API}\n * if they differ.\n *\n * @param {Object} input The input object to this function.\n * @param {Response} input.first One of the responses to compare.\n * This should not be an {@link http://stackoverflow.com/questions/39109789|opaque response}.\n * @param {Response} input.second The response to compare with.\n * This should not be an {@link http://stackoverflow.com/questions/39109789|opaque response}.\n * @param {string} input.cacheName Name of the cache the responses belong to.\n * This is included in the message posted on the broadcast channel.\n * @param {string} input.url The URL of the updates request.\n */\n notifyIfUpdated({first, second, cacheName, url}) {\n isType({cacheName}, 'string');\n\n if (\n !responsesAreSame({first, second, headersToCheck: this.headersToCheck})) {\n broadcastUpdate({cacheName, url,\n channel: this.channel, source: this.source});\n }\n }\n}\n\nexport default BroadcastCacheUpdate;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nimport BroadcastCacheUpdate from './broadcast-cache-update';\nimport {isType, isInstance} from '../../../../lib/assert';\n\n/**\n * Can be used to compare two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * and uses the {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel API}\n * to notify interested parties when those responses differ.\n *\n * For efficiency's sake, the underlying response bodies are not compared;\n * only specific response headers are checked.\n *\n * This class is meant to be automatically invoked as a plugin by a\n * {@link module:workbox-runtime-caching.RequestWrapper|RequestWrapper}, which\n * is used by the `workbox-sw` and `workbox-runtime-caching` modules.\n *\n * If you would like to use this functionality outside of the `RequestWrapper`\n * context, please use the\n * [BroadcastCacheUpdate]{@link\n * module:workbox-broadcast-cache-update.BroadcastCacheUpdate}\n * class directly.\n *\n * @example <caption>Add a BroadcastCacheUpdatePlugin to a `RequestWrapper` to\n * dispatch messages on a cache update.</caption>\n *\n * const requestWrapper = new workbox.runtimeCaching.RequestWrapper({\n * cacheName: 'runtime-cache',\n * plugins: [\n * new workbox.broadcastCacheUpdate.Plugin({channelName: 'cache-updates'})\n * ]\n * });\n * const route = new workbox.routing.RegExpRoute({\n * match: ({url}) => url.domain === 'example.com',\n * handler: new workbox.runtimeCaching.StaleWhileRevalidate({requestWrapper})\n * });\n *\n * @memberof module:workbox-broadcast-cache-update\n */\nclass BroadcastCacheUpdatePlugin extends BroadcastCacheUpdate {\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-sw` and `workbox-runtime-caching` handlers when an entry is\n * added to a cache.\n *\n * @private\n * @param {Object} input The input object to this function.\n * @param {string} input.cacheName Name of the cache the responses belong to.\n * @param {Response} [input.oldResponse] The previous cached value, if any.\n * @param {Response} input.newResponse The new value in the cache.\n * @param {string} input.url The cache key URL.\n */\n cacheDidUpdate({cacheName, oldResponse, newResponse, url}) {\n isType({cacheName}, 'string');\n isInstance({newResponse}, Response);\n\n if (oldResponse) {\n this.notifyIfUpdated({\n cacheName,\n first: oldResponse,\n second: newResponse,\n url,\n });\n }\n }\n}\n\nexport default BroadcastCacheUpdatePlugin;\n","import {\n CacheFirst, CacheOnly, NetworkFirst,\n NetworkOnly, StaleWhileRevalidate,\n} from '../../../workbox-runtime-caching/src/index.js';\nimport {CacheExpirationPlugin} from\n '../../../workbox-cache-expiration/src/index.js';\nimport {BroadcastCacheUpdatePlugin} from\n '../../../workbox-broadcast-cache-update/src/index.js';\nimport {CacheableResponsePlugin} from\n '../../../workbox-cacheable-response/src/index.js';\nimport {RequestWrapper} from '../../../workbox-runtime-caching/src/index.js';\n\n/**\n * StrategyOptions is just a JavaScript object, but the structure\n * explains the options for runtime strategies used in workbox-sw.\n *\n * See the example of how this can be used with the `cacheFirst()` caching\n * strategy.\n *\n * @example\n * const workboxSW = new WorkboxSW();\n * const cacheFirstStrategy = workboxSW.strategies.cacheFirst({\n * cacheName: 'example-cache',\n * cacheExpiration: {\n * maxEntries: 10,\n * maxAgeSeconds: 7 * 24 * 60 * 60\n * },\n * broadcastCacheUpdate: {\n * channelName: 'example-channel-name'\n * },\n * cacheableResponse: {\n * statuses: [0, 200, 404],\n * headers: {\n * 'Example-Header-1': 'Header-Value-1',\n * 'Example-Header-2': 'Header-Value-2'\n * }\n * }\n * plugins: [\n * // Additional Plugins\n * ]\n * });\n *\n * @typedef {Object} StrategyOptions\n * @property {String} cacheName Name of cache to use\n * for caching (both lookup and updating).\n * @property {Object} cacheExpiration Defining this\n * object will add a cache expiration plugins to this strategy.\n * @property {Number} cacheExpiration.maxEntries\n * The maximum number of entries to store in a cache.\n * @property {Number} cacheExpiration.maxAgeSeconds\n * The maximum lifetime of a request to stay in the cache before it's removed.\n * @property {Object} broadcastCacheUpdate Defining\n * this object will add a broadcast cache update plugin.\n * @property {String} broadcastCacheUpdate.channelName\n * The name of the broadcast channel to dispatch messages on.\n * @property {Array<plugins>} plugins For\n * any additional plugins you wish to add, simply include them in this\n * array.\n * @property {Object} cacheableResponse Specifies types of responses to cache\n * by status codes, headers, or both.\n * @property {Array<Number>} cacheableResponse.statuses An array of status\n * codes to cache.\n * @property {Array<Object>} cacheableResponse.headers An array of\n * header-value pairs for HTTP headers to cache. See the example, above.\n * @memberof module:workbox-sw.Strategies\n */\n\n/**\n * This is a simple class used to namespace the supported caching strategies in\n * workbox-sw.\n *\n * You would never access this class directly but instead use with\n * `workboxSW.strategies.<Strategy Name>`.\n *\n * @memberof module:workbox-sw\n */\nclass Strategies {\n /**\n * This constructor will configure shared options across each strategy.\n * @param {String} [input.cacheId] The cacheId to be applied to the run\n * time strategies cache names.\n */\n constructor({cacheId} = {}) {\n this._cacheId = cacheId;\n }\n\n /**\n * A [cache first](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-falling-back-to-network)\n * run-time caching strategy.\n *\n * @example\n * const = new WorkboxSW();\n * const cacheFirstStrategy = workboxSW.strategies.cacheFirst();\n *\n * workboxSW.router.registerRoute('/styles/*', cacheFirstStrategy);\n *\n * @param {module:workbox-sw.Strategies.StrategyOptions} [options] To\n * define any additional caching or broadcast plugins pass in option values.\n * @return {module:workbox-runtime-caching.CacheFirst} An instance of a\n * `CacheFirst` handler.\n */\n cacheFirst(options) {\n return this._getCachingMechanism(CacheFirst, options);\n }\n\n /**\n * A [cache only](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-only)\n * run-time caching strategy.\n *\n * @example\n * const workboxSW = new WorkboxSW();\n * const cacheOnlyStrategy = workboxSW.strategies.cacheOnly();\n *\n * workboxSW.router.registerRoute('/styles/*', cacheOnlyStrategy);\n *\n * @param {module:workbox-sw.Strategies.StrategyOptions} [options] To\n * define any additional caching or broadcast plugins pass in option values.\n * @return {module:workbox-runtime-caching.CacheOnly} An instance of a\n * `CacheOnly` handler.\n */\n cacheOnly(options) {\n return this._getCachingMechanism(CacheOnly, options);\n }\n\n /**\n * A [network first](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#network-falling-back-to-cache)\n * run-time caching strategy.\n *\n * @example\n * const workboxSW = new WorkboxSW();\n * const networkFirstStrategy = workboxSW.strategies.networkFirst();\n *\n * workboxSW.router.registerRoute('/blog/', networkFirstStrategy);\n *\n * @param {module:workbox-sw.Strategies.StrategyOptions} [options] To\n * define any additional caching or broadcast plugins pass in option values.\n * @return {module:workbox-runtime-caching.NetworkFirst} An instance of a\n * `NetworkFirst` handler.\n */\n networkFirst(options) {\n return this._getCachingMechanism(NetworkFirst, options);\n }\n\n /**\n * A [network only](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#network-only)\n * run-time caching strategy.\n *\n * @example\n * const workboxSW = new WorkboxSW();\n * const networkOnlyStrategy = workboxSW.strategies.networkOnly();\n *\n * workboxSW.router.registerRoute('/admin/', networkOnlyStrategy);\n *\n * @param {module:workbox-sw.Strategies.StrategyOptions} [options] To\n * define any additional caching or broadcast plugins pass in option values.\n * @return {module:workbox-runtime-caching.NetworkOnly} An instance of a\n * `NetworkOnly` handler.\n */\n networkOnly(options) {\n return this._getCachingMechanism(NetworkOnly, options);\n }\n\n /**\n * A [stale while revalidate](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#stale-while-revalidate)\n * run-time caching strategy.\n *\n * @example\n * const workboxSW = new WorkboxSW();\n * const staleWhileRevalidateStrategy =\n * workboxSW.strategies.staleWhileRevalidate();\n *\n * workboxSW.router.registerRoute('/styles/*', staleWhileRevalidateStrategy);\n *\n * @param {module:workbox-sw.Strategies.StrategyOptions} [options] To\n * define any additional caching or broadcast plugins pass in option values.\n * @return {module:workbox-runtime-caching.StaleWhileRevalidate}\n * An instance of a `StaleWhileRevalidate` handler.\n */\n staleWhileRevalidate(options) {\n return this._getCachingMechanism(StaleWhileRevalidate, options);\n }\n\n /**\n * This method will add plugins based on options passed in by the\n * developer.\n *\n * @private\n * @param {Class} HandlerClass The class to be configured and instantiated.\n * @param {Object} [options] Options to configure the handler.\n * @param {boolean} [options.excludeCacheId] If true, we assume that\n * options.cacheName already includes the cacheId, and it does not need to\n * be specified twice.\n * @return {Handler} A handler instance configured with the appropriate\n * behaviours\n */\n _getCachingMechanism(HandlerClass, options = {}) {\n const pluginParamsToClass = {\n 'cacheExpiration': CacheExpirationPlugin,\n 'broadcastCacheUpdate': BroadcastCacheUpdatePlugin,\n 'cacheableResponse': CacheableResponsePlugin,\n };\n\n const wrapperOptions = {\n plugins: [],\n };\n\n if (!options.excludeCacheId) {\n wrapperOptions.cacheId = this._cacheId;\n }\n\n if (options['cacheName']) {\n wrapperOptions['cacheName'] = options['cacheName'];\n }\n\n // Iterate over known plugins and add them to Request Wrapper options.\n const pluginKeys = Object.keys(pluginParamsToClass);\n pluginKeys.forEach((pluginKey) => {\n if (options[pluginKey]) {\n const PluginClass = pluginParamsToClass[pluginKey];\n const pluginParams = options[pluginKey];\n\n wrapperOptions.plugins.push(new PluginClass(pluginParams));\n }\n });\n\n // Add custom plugins.\n if (options.plugins) {\n options.plugins.forEach((plugin) => {\n wrapperOptions.plugins.push(plugin);\n });\n }\n\n options.requestWrapper = new RequestWrapper(wrapperOptions);\n // Pass through the initial options to the underlying Handler constructor\n // to allow for Handler-specific customization.\n return new HandlerClass(options);\n }\n}\n\nexport default Strategies;\n","const errorMessageFactory = (code, context) => {\n let message = `An error was thrown by workbox with error code: ` +\n `;'${code}'`;\n if (context) {\n message += ` with extras: '${JSON.stringify(context)}'`;\n }\n return message;\n};\n\nexport default errorMessageFactory;\n","import errorMessageFactory from './error-message-factory';\n\n/**\n * This is a class for managing errors thrown by Workbox.\n *\n * This class will have full fat error messages in dev builds\n * and be slimmed down in prod.\n */\nclass WorkboxError extends Error {\n /**\n * Construct a new Workbox Error Message.\n * @param {String} errorCode The error code that is associated with the\n * error message and will be used to generate the appropriate error message.\n * @param {Object} [extras] These are fields that will be passed to\n * the error message to be included if the message wants and exposed\n * under `err.extra` should the developer need to access the information.\n */\n constructor(errorCode, extras) {\n super();\n\n this.name = errorCode;\n this.message = errorMessageFactory(errorCode, extras);\n\n if (extras) {\n this.extras = extras;\n }\n }\n}\n\nexport default WorkboxError;\n","import {RequestWrapper} from '../../../../workbox-runtime-caching/src/index';\nimport WorkboxError from '../../../../../lib/workbox-error';\n\n/**\n * This class handles the shared logic for caching revisioned and unrevisioned\n * assets.\n *\n * @memberof module:workbox-precaching\n */\nclass BaseCacheManager {\n /**\n * Constructor for BaseCacheManager\n *\n * @param {Object} input\n * @param {String} [input.cacheName] This is the cache name to store requested\n * assets.\n * @param {String} [input.cacheId] The cacheId can be used to ensure that\n * multiple projects sharing `http://localhost` have unique cache names.\n * @param {Array<Object>} [input.plugins] Any plugins that should be\n * invoked by the underlying `RequestWrapper`.\n */\n constructor({cacheName, cacheId, plugins} = {}) {\n if (cacheId && (typeof cacheId !== 'string' || cacheId.length === 0)) {\n throw new WorkboxError('bad-cache-id', {cacheId});\n }\n\n this._entriesToCache = new Map();\n this._requestWrapper = new RequestWrapper({\n cacheName,\n cacheId,\n plugins,\n fetchOptions: {\n credentials: 'same-origin',\n },\n });\n }\n\n /**\n * Adds entries to the install list.\n * This will manage duplicate entries and perform the caching during\n * the install step.\n *\n * @private\n * @param {Array<String|Request|Object>} rawEntries A raw entry that can be\n * parsed into a BaseCacheEntry by the inheriting CacheManager.\n */\n _addEntries(rawEntries) {\n this._parsedCacheUrls = null;\n\n rawEntries.forEach((rawEntry) => {\n this._addEntryToInstallList(\n this._parseEntry(rawEntry)\n );\n });\n }\n\n /**\n * Gives access to the cache name used by this caching manager.\n * @return {String} The cache name used by this manager.\n */\n getCacheName() {\n return this._requestWrapper.cacheName;\n }\n\n /**\n * Returns an array of fully qualified URL's that will be cached by this\n * cache manager.\n *\n * @return {Array<String>} An array of URLs that will be cached.\n */\n getCachedUrls() {\n if (!this._parsedCacheUrls) {\n this._parsedCacheUrls = Array.from(this._entriesToCache.keys())\n .map((url) => new URL(url, location).href);\n }\n\n return this._parsedCacheUrls;\n }\n\n /**\n * Adds an entry to the install list.\n *\n * Duplicates are filtered out and checks are made for the scenario\n * where two entries have the same URL but different revisions. For example\n * caching:\n * [\n * {url: '/hello.txt', revision: 'abcd1234'},\n * {url: '/hello.txt', revision: 'efgh5678'},\n * ]\n * This will throw an error as the library can't determine the correct\n * revision and this may cause issues in future when updating the service\n * worker with new revisions.\n *\n * @private\n * @param {RevisionedCacheEntry} precacheEntry The file entry to be cached\n * during the next install event.\n */\n _addEntryToInstallList(precacheEntry) {\n const entryID = precacheEntry.entryID;\n const previousEntry = this._entriesToCache.get(precacheEntry.entryID);\n if (!previousEntry) {\n // This entry isn't in the install list\n this._entriesToCache.set(entryID, precacheEntry);\n return;\n }\n\n this._onDuplicateInstallEntryFound(precacheEntry, previousEntry);\n }\n\n /**\n * This method will go through each asset added to the cache list and\n * fetch and update the cache for assets which have a new revision hash.\n *\n * @return {Promise<Array<Object>>} The promise resolves when all the\n * desired assets are cached and up -to-date.\n */\n async install() {\n if (this._entriesToCache.size === 0) {\n return [];\n }\n\n const cachePromises = [];\n this._entriesToCache.forEach((precacheEntry) => {\n cachePromises.push(\n this._cacheEntry(precacheEntry)\n );\n });\n\n // Wait for all requests to be cached.\n return Promise.all(cachePromises);\n }\n\n /**\n * Requests the entry and saves it to the cache if the response\n * is valid.\n *\n * @private\n * @param {BaseCacheEntry} precacheEntry The entry to fetch and cache.\n * @return {Promise<Object>} Returns a promise that resolves once the entry\n * has been fetched and cached or skipped if no update is needed. The\n * promise resolved with details of the entry and whether it was\n * updated or not.\n */\n async _cacheEntry(precacheEntry) {\n const isCached = await this._isAlreadyCached(precacheEntry);\n const precacheDetails = {\n url: precacheEntry.request.url,\n revision: precacheEntry.revision,\n wasUpdated: !isCached,\n };\n if (isCached) {\n return precacheDetails;\n }\n\n try {\n await this._requestWrapper.fetchAndCache({\n request: precacheEntry.getNetworkRequest(),\n waitOnCache: true,\n cacheKey: precacheEntry.request,\n cleanRedirects: true,\n });\n\n await this._onEntryCached(precacheEntry);\n return precacheDetails;\n } catch (err) {\n throw new WorkboxError('request-not-cached', {\n url: precacheEntry.request.url,\n error: err,\n });\n }\n }\n\n /**\n * Compare the URL's and determines which assets are no longer required\n * in the cache.\n *\n * This should be called in the service worker activate event.\n *\n * @return {Promise} Promise that resolves once the cache entries have been\n * cleaned.\n */\n async cleanup() {\n if (!await caches.has(this.getCacheName())) {\n // Cache doesn't exist, so nothing to delete\n return;\n }\n\n const requestsCachedOnInstall = [];\n this._entriesToCache.forEach((entry) => {\n requestsCachedOnInstall.push(entry.request.url);\n });\n\n const openCache = await this._getCache();\n const allCachedRequests = await openCache.keys();\n\n const cachedRequestsToDelete = allCachedRequests.filter(\n (cachedRequest) => !requestsCachedOnInstall.includes(cachedRequest.url));\n\n return Promise.all(\n cachedRequestsToDelete.map(async (cachedRequest) => {\n await openCache.delete(cachedRequest);\n await this._onEntryDeleted(cachedRequest.url);\n })\n );\n }\n\n /**\n * A simple helper method to get the open cache used for precaching assets.\n *\n * @private\n * @return {Promise<Cache>} The cache to be used for precaching.\n */\n async _getCache() {\n if (!this._cache) {\n this._cache = await caches.open(this.getCacheName());\n }\n\n return this._cache;\n }\n\n /**\n * Ensures the file entry in the maniest is valid and\n * can be parsed as a BaseCacheEntry.\n *\n * @private\n * @abstract\n * @param {String | Request | Object} input Either a URL string, a Request\n * or an object with a `url`, `revision` and optional `cacheBust` parameter.\n * @return {BaseCacheEntry} Returns a parsed version of the file entry.\n */\n _parseEntry(input) {\n throw new WorkboxError('requires-overriding');\n }\n\n /**\n * Called in case subclasses have cache entries that are to be installed\n * but have the same \"entryID\".\n * This means that the user is trying to cache the same thing twice.\n * Subclasses can use this method to throw an error if there is an edge\n * case that can't be handled.\n *\n * @private\n * @abstract\n * @param {BaseCacheEntry} newEntry The entry that is to be cached.\n * @param {BaseCacheEntry} previous The entry that is currently cached.\n */\n _onDuplicateEntryFound(newEntry, previous) {\n throw new WorkboxError('requires-overriding');\n }\n\n /**\n * Confirms whether a fileEntry is already in the cache with the\n * appropriate revision or not.\n *\n * @private\n * @abstract\n * @param {BaseCacheEntry} precacheEntry A file entry with `path` and\n * `revision` parameters.\n * @return {Promise<Boolean>} Returns true is the fileEntry is already\n * cached, false otherwise.\n */\n _isAlreadyCached(precacheEntry) {\n throw new WorkboxError('requires-overriding');\n }\n\n /**\n * Subclasses can use this method for any work that needs to be done once a\n * URL has been cached.\n *\n * @private\n * @abstract\n * @param {BaseCacheEntry} precacheEntry A file entry with `path` and\n * `revision` parameters.\n * @return {Promise} Returns a Promise that resolves once it's work has\n * been done.\n */\n _onEntryCached(precacheEntry) {\n throw new WorkboxError('requires-overriding');\n }\n\n /**\n * Subclasses can use this method for any work that needs to be done once a\n * URL has been deleted from the cache.\n *\n * @private\n * @abstract\n * @param {String} url The URL of the entry that was deleted.\n * @return {Promise} Returns a Promise that resolves once the work is done.\n */\n _onEntryDeleted(url) {\n throw new WorkboxError('requires-overriding');\n }\n}\n\nexport default BaseCacheManager;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/* eslint-disable require-jsdoc */\n\nimport idb from 'idb';\n\n/**\n * A wrapper to store for an IDB connection to a particular ObjectStore.\n *\n * @private\n */\nclass IDBHelper {\n constructor(name, version, storeName) {\n if (name == undefined || version == undefined || storeName == undefined) {\n throw Error('name, version, storeName must be passed to the ' +\n 'constructor.');\n }\n\n this._name = name;\n this._version = version;\n this._storeName = storeName;\n }\n\n /**\n * Returns a promise that resolves with an open connection to IndexedDB,\n * either existing or newly opened.\n *\n * @private\n * @return {Promise<DB>}\n */\n _getDb() {\n if (this._dbPromise) {\n return this._dbPromise;\n }\n\n this._dbPromise = idb.open(this._name, this._version, (upgradeDB) => {\n upgradeDB.createObjectStore(this._storeName);\n })\n .then((db) => {\n return db;\n });\n\n return this._dbPromise;\n }\n\n close() {\n if (!this._dbPromise) {\n return;\n }\n\n return this._dbPromise\n .then((db) => {\n db.close();\n this._dbPromise = null;\n });\n }\n\n /**\n * Wrapper on top of the idb wrapper, which simplifies saving the key/value\n * pair to the object store.\n * Returns a Promise that fulfills when the transaction completes.\n *\n * @private\n * @param {String} key\n * @param {Object} value\n * @return {Promise<T>}\n */\n put(key, value) {\n return this._getDb().then((db) => {\n const tx = db.transaction(this._storeName, 'readwrite');\n const objectStore = tx.objectStore(this._storeName);\n objectStore.put(value, key);\n return tx.complete;\n });\n }\n\n /**\n * Wrapper on top of the idb wrapper, which simplifies deleting an entry\n * from the object store.\n * Returns a Promise that fulfills when the transaction completes.\n *\n * @private\n * @param {String} key\n * @return {Promise<T>}\n */\n delete(key) {\n return this._getDb().then((db) => {\n const tx = db.transaction(this._storeName, 'readwrite');\n const objectStore = tx.objectStore(this._storeName);\n objectStore.delete(key);\n return tx.complete;\n });\n }\n\n /**\n * Wrapper on top of the idb wrapper, which simplifies getting a key's value\n * from the object store.\n * Returns a promise that fulfills with the value.\n *\n * @private\n * @param {String} key\n * @return {Promise<Object>}\n */\n get(key) {\n return this._getDb().then((db) => {\n return db.transaction(this._storeName)\n .objectStore(this._storeName)\n .get(key);\n });\n }\n\n /**\n * Wrapper on top of the idb wrapper, which simplifies getting all the values\n * in an object store.\n * Returns a promise that fulfills with all the values.\n *\n * @private\n * @return {Promise<Array<Object>>}\n */\n getAllValues() {\n return this._getDb().then((db) => {\n return db.transaction(this._storeName)\n .objectStore(this._storeName)\n .getAll();\n });\n }\n\n /**\n * Wrapper on top of the idb wrapper, which simplifies getting all the keys\n * in an object store.\n * Returns a promise that fulfills with all the keys.\n *\n * @private\n * @param {String} storeName\n * @return {Promise<Array<Object>>}\n */\n getAllKeys() {\n return this._getDb().then((db) => {\n return db.transaction(this._storeName)\n .objectStore(this._storeName)\n .getAllKeys();\n });\n }\n}\n\nexport default IDBHelper;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nexport const cacheBustParamName = '_workbox-precaching';\nexport const version = 'v1';\nexport const dbName = 'workbox-precaching';\nexport const dbVersion = '1';\nexport const dbStorename = 'asset-revisions';\n\nlet tmpRevisionedCacheName = `workbox-precaching-revisioned-${version}`;\nif (self && self.registration) {\n tmpRevisionedCacheName += `-${self.registration.scope}`;\n}\nexport const defaultRevisionedCacheName = tmpRevisionedCacheName;\n","import IDBHelper from '../../../../../lib/idb-helper.js';\nimport {dbName, dbVersion, dbStorename} from '../constants';\n\n/**\n * This class is a simple model that stores EntryID's with their current\n * revision. This is used when caching revisioned assets so that only entries\n * with different revisions are downloaded and updated.\n *\n * @private\n * @memberof module:workbox-precaching\n */\nclass RevisionDetailsModel {\n /**\n * Constructor for RevisionDetails Model.\n */\n constructor() {\n this._idbHelper = new IDBHelper(dbName, dbVersion, dbStorename);\n }\n\n /**\n * This method gets the revision details for a given entryID.\n * @param {String} entryID The ID of the revision.\n * @return {Promise<String|null>} Returns a revision string or\n * null if there is no revision information.\n */\n get(entryID) {\n return this._idbHelper.get(entryID);\n }\n\n /**\n * This method saves the revision details to indexedDB.\n * @param {String} entryID The ID of the revision.\n * @param {String} revision The current revision for this entryID.\n * @return {Promise} Promise that resolves once the data has been saved.\n */\n put(entryID, revision) {\n return this._idbHelper.put(entryID, revision);\n }\n\n /**\n * This method deletes the revision details from indexedDB for a given entry.\n * @param {String} entryID The ID of the revision.\n * @return {Promise} Promise that resolves once the data has been deleted.\n */\n delete(entryID) {\n return this._idbHelper.delete(entryID);\n }\n\n /**\n * This method closes the indexdDB helper. This is only used for unit testing\n * to ensure clean state between tests.\n *\n * @private\n */\n _close() {\n this._idbHelper.close();\n }\n}\n\nexport default RevisionDetailsModel;\n","import {cacheBustParamName} from '../../constants';\n\n/**\n * This class is extended by a number of classes that take different inputs\n * and generates the required fields for a BaseCacheEntry.\n *\n * @private\n * @memberof module:workbox-precaching\n */\nclass BaseCacheEntry {\n /**\n * This constructor expects an object and a number or required fields.\n * You shouldn't need to use this constructor directly.\n *\n * @param {Object} input\n * @param {String} input.entryID\n * @param {String} input.revision\n * @param {Request} input.request\n * @param {boolean} input.cacheBust\n */\n constructor({entryID, revision, request, cacheBust}) {\n this.entryID = entryID;\n this.revision = revision;\n this.request = request;\n this.cacheBust = cacheBust;\n }\n\n /**\n * This method is required since any revisioned request needs to cache bust.\n * To ensure this is consistent, CacheManagers will make a network request\n * using this specially formatted request.\n *\n * When caching the response, it will be cached against the origin `request`,\n * removing lookup for the cachebusted URL.\n *\n * @return {Request} Returns a cache busted request if needed, otherwise\n * a normal request with credentials set to 'same-origin' and redirect set to\n * follow.\n */\n getNetworkRequest() {\n if (this.cacheBust !== true) {\n // For the RequestCacheEntry we should return it to ensure headers are\n // kept in tact and part of the request.\n return this.request;\n }\n\n let url = this.request.url;\n const requestOptions = {};\n\n if (this.cacheBust === true) {\n if ('cache' in Request.prototype) {\n // Make use of the Request cache mode where we can.\n // Reload skips the HTTP cache for outgoing requests and updates\n // the cache with the returned reponse.\n requestOptions.cache = 'reload';\n } else {\n const parsedURL = new URL(url, location);\n parsedURL.search += (parsedURL.search ? '&' : '') +\n encodeURIComponent(cacheBustParamName) + '=' +\n encodeURIComponent(this.revision);\n url = parsedURL.toString();\n }\n }\n\n return new Request(url, requestOptions);\n }\n}\n\nexport default BaseCacheEntry;\n","import BaseCacheEntry from './base-precache-entry';\nimport {isType} from '../../../../../../lib/assert';\nimport WorkboxError from '../../../../../../lib/workbox-error';\n\n/**\n * This class will take a string and parse it as a BaseCacheEntry.\n *\n * @private\n * @memberof module:workbox-precaching\n * @extends {module:workbox-precaching.BaseCacheEntry}\n */\nclass StringCacheEntry extends BaseCacheEntry {\n /**\n * Cosntructor for StringCacheEntry.\n *\n * @param {String} url A URL to cache.\n */\n constructor(url) {\n isType({url}, 'string');\n if (url.length === 0) {\n throw new WorkboxError('invalid-string-entry', {\n url,\n });\n }\n\n super({\n entryID: url,\n revision: url,\n request: new Request(url),\n cacheBust: false,\n });\n }\n}\n\nexport default StringCacheEntry;\n","import WorkboxError from '../../../../../../lib/workbox-error';\nimport BaseCacheEntry from './base-precache-entry';\nimport {isType} from '../../../../../../lib/assert';\n\n/**\n * This class will take an object of parameters, validate the input and\n * parse to be used as a BaseCacheEntry.\n *\n * @private\n * @memberof module:workbox-precaching\n * @extends {module:workbox-precaching.BaseCacheEntry}\n */\nclass ObjectCacheEntry extends BaseCacheEntry {\n /**\n * This class gives most control over configuring a cache entry.\n * @param {Object} input\n * @param {String} [input.entryID] The ID of the entry. This is the key used\n * with IndexDB to store the revision. Normally this is just the URL.\n * @param {String} [input.revision] This is the revision associated with this\n * URL.\n * @param {String} input.url The URL to cache.\n * @param {boolean} [input.cacheBust] A boolean to indicate if this request\n * will require cache busting (i.e. the URL is not unique between SW install).\n */\n constructor({entryID, revision, url, cacheBust}) {\n if (typeof revision !== 'undefined') {\n isType({revision}, 'string');\n if (revision.length === 0) {\n throw new WorkboxError('invalid-object-entry',\n {problemParam: 'revision', problemValue: revision});\n }\n }\n\n if (typeof cacheBust === 'undefined') {\n // If the cacheBust value is not explicitly set, then set it to true\n // if there's a revision provided, and false if there's no revision.\n cacheBust = Boolean(revision);\n }\n isType({cacheBust}, 'boolean');\n\n isType({url}, 'string');\n if (url.length === 0) {\n throw new WorkboxError('invalid-object-entry',\n {problemParam: 'url', problemValue: url});\n }\n\n if (typeof entryID === 'undefined') {\n entryID = new URL(url, location).toString();\n } else {\n if (entryID.length === 0) {\n throw new WorkboxError('invalid-object-entry',\n {problemParam: 'entryID', problemValue: entryID});\n }\n }\n\n super({\n entryID,\n // If revision isn't set, assume that the URL contains revision info.\n revision: revision || url,\n request: new Request(url),\n cacheBust,\n });\n }\n}\n\nexport default ObjectCacheEntry;\n","import BaseCacheManager from './base-cache-manager';\nimport RevisionDetailsModel from '../models/revision-details-model';\nimport {defaultRevisionedCacheName} from '../constants';\nimport StringCacheEntry from\n '../models/precache-entries/string-cache-entry';\nimport ObjectPrecacheEntry from\n '../models/precache-entries/object-precache-entry';\nimport {isInstance} from '../../../../../lib/assert';\nimport logHelper from '../../../../../lib/log-helper';\nimport WorkboxError from '../../../../../lib/workbox-error';\n\n/**\n * You can instantiate this class to add requests to a precache list and\n * eventually install the assets by calling [install()]{@link\n * module:workbox-precaching.BaseCacheManager#install} and to remove\n * old entries call [cleanup()]{@link\n * module:workbox-precaching.RevisionedCacheManager#cleanup}.\n *\n * @memberof module:workbox-precaching\n * @extends module:workbox-precaching.BaseCacheManager\n */\nclass RevisionedCacheManager extends BaseCacheManager {\n /**\n * Constructs a new RevisionedCacheManager to handle caching of revisioned\n * assets only.\n *\n * @param {Object} input\n * @param {String} [input.cacheName] The cache to be used for precaching.\n * @param {String} [input.cacheId] The cacheId is prepended to the\n * cache name. This is useful if you have multiple projects sharing\n * the same `http://localhost` origin and want unique cache names.\n * @param {Array<Object>} [input.plugins] Any plugins that should be\n * invoked by the underlying `RequestWrapper`.\n */\n constructor(input = {}) {\n input.cacheName = input.cacheName || defaultRevisionedCacheName;\n\n super(input);\n\n this._revisionDetailsModel = new RevisionDetailsModel();\n }\n\n /**\n * This method will add the supplied entries to the install list and\n * can be called multiple times.\n *\n * The `revisionedFiles` parameter of the input should contain an array\n * of objects or strings.\n *\n * Objects in this array should have a `url` and `revision` parameter where\n * the revision is a hash, unique to the files contents, which changes\n * whenever the file is updated. (See our [getting started guide to learn\n * how to automate this](/#get-started)).\n *\n * Strings should be URL's that contain revisioning information\n * i.e. `/styles/main.abcd.css` instead of `/styles/main.css`. If you supply\n * a URL which *isn't* revisioned, the `install()` step will **never** update\n * the precached asset.\n *\n * @param {Object} input\n * @param {Array<String|Object>} input.revisionedFiles This should be an\n * array of either objects or strings.\n *\n * @example\n * revisionedManager.addToCacheList({\n * revisionedFiles: [\n * '/styles/hello.1234.css',\n * {\n * url: '/images/logo.png',\n * revision: 'abcd1234'\n * }\n * ]\n * });\n */\n addToCacheList({revisionedFiles} = {}) {\n isInstance({revisionedFiles}, Array);\n super._addEntries(revisionedFiles);\n\n const urlsWithoutRevisionFields = revisionedFiles\n .filter((entry) => typeof entry === 'string' || !entry.revision);\n if (urlsWithoutRevisionFields.length > 0) {\n logHelper.debug({\n that: this,\n message: `Some precache entries are URLs without separate revision\n fields. If the URLs themselves do not contain revisioning info,\n like a hash or a version number, your users won't receive updates.`,\n data: {\n 'URLs without revision fields':\n JSON.stringify(urlsWithoutRevisionFields),\n 'Examples of safe, versioned URLs':\n `'/path/file.abcd1234.css' or '/v1.0.0/file.js'`,\n 'Examples of dangerous, unversioned URLs':\n `'index.html' or '/path/file.css' or '/latest/file.js'`,\n },\n });\n }\n }\n\n /**\n * This method ensures that the file entry in the maniest is valid and\n * can be parsed as a BaseCacheEntry.\n *\n * @private\n * @param {String | Object} input Either a URL string or an object with a\n * `url` and optional `revision` and `cacheBust` parameters.\n * @return {BaseCacheEntry} Returns a parsed version of the file entry.\n */\n _parseEntry(input) {\n if (input === null) {\n throw new WorkboxError('unexpected-precache-entry', {input});\n }\n\n let precacheEntry;\n switch (typeof input) {\n case 'string':\n precacheEntry = new StringCacheEntry(input);\n break;\n case 'object':\n precacheEntry = new ObjectPrecacheEntry(input);\n break;\n default:\n throw new WorkboxError('unexpected-precache-entry', {input});\n }\n\n return precacheEntry;\n }\n\n /**\n * If a dupe entry exists, check the revision. If the revisions are the same\n * it's simply a duplicate entry. If they are different, we have two\n * identical requests with two different revisions which will put this\n * module into a bad state.\n *\n * @private\n * @param {BaseCacheEntry} newEntry The entry that is to be cached.\n * @param {BaseCacheEntry} previousEntry The entry that is currently cached.\n */\n _onDuplicateInstallEntryFound(newEntry, previousEntry) {\n if (previousEntry.revision !== newEntry.revision) {\n throw new WorkboxError('duplicate-entry-diff-revisions', {\n firstEntry: {\n url: previousEntry.request.url,\n revision: previousEntry.revision,\n },\n secondEntry: {\n url: newEntry.request.url,\n revision: newEntry.revision,\n },\n });\n }\n }\n\n /**\n * This method confirms with a precacheEntry is already in the cache with the\n * appropriate revision.\n * If the revision is known, the requested `precacheEntry.revision` is saved\n * and the cache entry exists for the `precacheEntry.path` this method\n * will return true.\n *\n * @private\n * @param {BaseCacheEntry} precacheEntry A entry with `path` and `revision`\n * parameters.\n * @return {Promise<Boolean>} Returns true if the precacheEntry is already\n * cached, false otherwise.\n */\n async _isAlreadyCached(precacheEntry) {\n const revisionDetails = await\n this._revisionDetailsModel.get(precacheEntry.entryID);\n if (revisionDetails !== precacheEntry.revision) {\n return false;\n }\n\n const openCache = await this._getCache();\n const cachedResponse = await openCache.match(precacheEntry.request);\n return cachedResponse ? true : false;\n }\n\n /**\n * @private\n * @param {BaseCacheEntry} precacheEntry A file entry with `path` and\n * `revision` parameters.\n */\n async _onEntryCached(precacheEntry) {\n await this._revisionDetailsModel.put(\n precacheEntry.entryID, precacheEntry.revision);\n }\n\n /**\n * Removes a URL from IndexedDB when the corresponding entry has been removed\n * from the Cache Storage API.\n *\n * @private\n * @param {String} url The URL that has been deleted from the cache.\n */\n async _onEntryDeleted(url) {\n await this._revisionDetailsModel.delete(url);\n }\n\n /**\n * This method closes the indexdDB helper. This is used for unit testing\n * to ensure cleanup between tests.\n * @private\n */\n _close() {\n this._revisionDetailsModel._close();\n }\n\n /**\n * This method will compare the currently cached requests's and determine\n * which requests are no longer in the cache list and can be removed from the\n * cache.\n *\n * This should be called in a service worker's activate event to avoid\n * removing requests that are still be used by currently open pages.\n *\n * @return {Promise} Promise that resolves once the cache entries have been\n * cleaned.\n */\n cleanup() {\n return super.cleanup()\n .then(() => {\n return this._close();\n });\n }\n\n /**\n * Given an array of objects with a 'url', 'revision' value this\n * method will create a friendly string to log.\n * @private\n * @param {Array<Object>} allCacheDetails\n * @return {String} A log friendly string.\n */\n _createLogFriendlyString(allCacheDetails) {\n let stringVersion = `\\n`;\n allCacheDetails.forEach((cacheDetails) => {\n stringVersion += ` URL: '${cacheDetails.url}' Revision: ` +\n `'${cacheDetails.revision}'\\n`;\n });\n return stringVersion;\n }\n\n /**\n * This method will go through each asset added to the cache list and\n * fetch and update the cache for assets which have a new revision hash.\n *\n * @return {Promise<Array<Object>>} The promise resolves when all the\n * desired assets are cached and up -to-date.\n */\n install() {\n return super.install()\n .then((allCacheDetails) => {\n const updatedCacheDetails = [];\n const notUpdatedCacheDetails = [];\n allCacheDetails.forEach((cacheDetails) => {\n if (cacheDetails.wasUpdated) {\n updatedCacheDetails.push({\n url: cacheDetails.url,\n revision: cacheDetails.revision,\n });\n } else {\n notUpdatedCacheDetails.push({\n url: cacheDetails.url,\n revision: cacheDetails.revision,\n });\n }\n });\n\n const logData = {};\n if (updatedCacheDetails.length > 0) {\n logData['New / Updated Precache URL\\'s'] =\n this._createLogFriendlyString(updatedCacheDetails);\n }\n\n if (notUpdatedCacheDetails.length > 0) {\n logData['Up-to-date Precache URL\\'s'] =\n this._createLogFriendlyString(notUpdatedCacheDetails);\n }\n\n logHelper.log({\n message: `Precache Details: ${updatedCacheDetails.length} requests ` +\n `were added or updated and ` +\n `${notUpdatedCacheDetails.length} request are already ` +\n `cached and up-to-date.`,\n data: logData,\n });\n\n return allCacheDetails;\n });\n }\n}\n\nexport default RevisionedCacheManager;\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/**\n * # workbox-precaching\n *\n * The precaching library intelligently caches and updates files\n * during the install step of your service worker.\n *\n * When given a list of URL's to precache, this module will go through\n * each URL and check if the URL is already cached and, if it is, compare\n * the hash to see if revision hash has changed.\n *\n * If the revision is old or the entry isn't cached, this library will make\n * a request for the asset and cache it, ensuring the the browsers HTTP cache\n * is skipped by using `Request.cache = 'reload'` or adding a cache busting\n * search parameter to the request.\n *\n * @example\n * importScripts('/<Path to Module>/build/workbox-precaching.min.js');\n *\n * const revCacheManager = new workbox.precaching.RevisionedCacheManager();\n * revCacheManager.addToCacheList({\n * revisionedFiles: [\n * '/styles/main.1234.css',\n * {\n * url: '/',\n * revision: '1234'\n * }\n * ],\n * });\n *\n * self.addEventListener('install', (event) => {\n * event.waitUntil(\n * revCacheManager.install()\n * );\n * });\n *\n * self.addEventListener('activate', (event) => {\n * event.waitUntil(\n * revCacheManager.cleanup()\n * );\n * });\n *\n * @module workbox-precaching\n */\nimport RevisionedCacheManager from\n './lib/controllers/revisioned-cache-manager.js';\n\nimport WorkboxError from '../../../lib/workbox-error';\nimport {isServiceWorkerGlobalScope} from '../../../lib/environment.js';\n\nif (!isServiceWorkerGlobalScope()) {\n // We are not running in a service worker, print error message\n throw new WorkboxError('not-in-sw');\n}\n\nexport {\n RevisionedCacheManager,\n};\n","/*\n Copyright 2016 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n/* eslint-env browser, serviceworker */\n\nimport ErrorFactory from './error-factory.js';\nimport Router from './router.js';\nimport Strategies from './strategies';\nimport {isServiceWorkerGlobalScope, isDevBuild, isLocalhost} from\n '../../../../lib/environment.js';\nimport logHelper from '../../../../lib/log-helper';\nimport {BroadcastCacheUpdatePlugin} from\n '../../../workbox-broadcast-cache-update/src/index.js';\nimport {RevisionedCacheManager} from '../../../workbox-precaching/src/index.js';\nimport {\n getDefaultCacheName} from '../../../workbox-runtime-caching/src/index.js';\n\n/**\n * This class uses the Workbox libraries to create a clean and easy API for\n * common caching and serving needs.\n *\n * @memberof module:workbox-sw\n */\nclass WorkboxSW {\n /**\n * You should instantiate this class with `new self.WorkboxSW()`.\n * @param {Object} input\n * @param {string} [input.cacheId] Defining a cacheId is useful to ensure\n * uniqueness across cache names. Useful if you have multiple sites served\n * over localhost.\n * @param {boolean} [input.skipWaiting] To activate the service worker as\n * soon as the install step has finished set this value to true.\n *\n * Defaults to false.\n * @param {boolean} [input.clientsClaim] To claim currently open clients set\n * this value to true.\n *\n * Defaults to false.\n * @param {String} [input.directoryIndex] The directoryIndex will\n * check cache entries for a URLs ending with '/' to see if there is a hit\n * when appending the directoryIndex (i.e. '/index.html').\n * @param {Array<RegExp>} [input.ignoreUrlParametersMatching] An array of\n * regex's to remove search params when looking for a cache match.\n * @param {string} [input.precacheChannelName] This value will be used as\n * the `channelName` to construct a {@link BroadcastCacheUpdate} plugin. The\n * plugin sends a message whenever a precached URL is updated. To disable this\n * plugin, set `precacheChannelName` to an empty string.\n *\n * Defaults to `'precache-updates'`\n */\n constructor({cacheId, skipWaiting, clientsClaim,\n handleFetch = true,\n directoryIndex = 'index.html',\n precacheChannelName = 'precache-updates',\n ignoreUrlParametersMatching = [/^utm_/]} = {}) {\n if (!isServiceWorkerGlobalScope()) {\n // If we are not running in a service worker, fail early.\n throw ErrorFactory.createError('not-in-sw');\n }\n\n if (isDevBuild()) {\n if (isLocalhost()) {\n // If this is a dev bundle on localhost, print a welcome message.\n logHelper.debug({\n message: 'Welcome to Workbox!',\n data: {\n '📖': 'Read the guides and documentation\\n' +\n 'https://workboxjs.org/',\n '❓': 'Use the [workbox] tag on StackOverflow to ask questions\\n' +\n 'https://stackoverflow.com/questions/ask?tags=workbox',\n '🐛': 'Found a bug? Report it on GitHub\\n' +\n 'https://github.com/GoogleChrome/workbox/issues/new',\n },\n });\n } else {\n // If this is a dev bundle not on localhost, recommend the prod bundle.\n logHelper.warn(`This appears to be a production server. Please switch\n to the smaller, optimized production build of Workbox.`);\n }\n }\n\n if (cacheId && (typeof cacheId !== 'string' || cacheId.length === 0)) {\n throw ErrorFactory.createError('bad-cache-id');\n }\n if (skipWaiting && (typeof skipWaiting !== 'boolean')) {\n throw ErrorFactory.createError('bad-skip-waiting');\n }\n if (clientsClaim && (typeof clientsClaim !== 'boolean')) {\n throw ErrorFactory.createError('bad-clients-claim');\n }\n if (typeof directoryIndex !== 'undefined') {\n if (directoryIndex === false || directoryIndex === null) {\n directoryIndex = false;\n } else if (typeof directoryIndex !== 'string' ||\n directoryIndex.length === 0) {\n throw ErrorFactory.createError('bad-directory-index');\n }\n }\n\n const plugins = [];\n if (precacheChannelName) {\n plugins.push(new BroadcastCacheUpdatePlugin({\n channelName: precacheChannelName,\n source: registration && registration.scope ?\n registration.scope :\n location,\n }));\n }\n\n this._runtimeCacheName = getDefaultCacheName({cacheId});\n this._revisionedCacheManager = new RevisionedCacheManager({\n cacheId,\n plugins,\n });\n this._strategies = new Strategies({\n cacheId,\n });\n\n // Create a Router instance that's used by the `Route` for precached assets.\n // See https://github.com/GoogleChrome/workbox/issues/839\n this._precacheRouter = new Router(\n this._revisionedCacheManager.getCacheName(),\n );\n\n this._router = new Router(\n this._revisionedCacheManager.getCacheName(),\n );\n\n if (handleFetch) {\n // Give precedence to the _precacheRouter by registering its `fetch`\n // handler first.\n this._precacheRouter.addFetchListener();\n this._router.addFetchListener();\n }\n\n this._registerInstallActivateEvents(skipWaiting, clientsClaim);\n this._registerDefaultRoutes(ignoreUrlParametersMatching, directoryIndex);\n }\n\n /**\n * Revisioned assets can be cached intelligently\n * during the install (i.e. old files are cleared from the cache, new files\n * are added to the cache and unchanged files are left as is).\n *\n * The input needs to be an array of URL strings which having revisioning\n * details in them otherwise the entry should be an object with `url` and\n * `revision` parameters.\n *\n * In addition to maintaining the cache, this method will also set up the\n * necessary routes to serve the precached assets using a cache-first\n * strategy.\n *\n * @example <caption>Cache revisioned assets.</caption>\n * // Cache a set of revisioned URLs\n * const workboxSW = new WorkboxSW();\n * workboxSW.precache([\n * '/styles/main.613e6c7332dd83e848a8b00c403827ed.css',\n * '/images/logo.59a325f32baad11bd47a8c515ec44ae5.jpg'\n * ]);\n *\n * // ...precache() can also take objects to cache\n * // non-revisioned URLs.\n * // Please use workbox-build or the workbox CLI to generate the manifest for\n * // you.\n * workboxSW.precache([\n * {\n * url: '/index.html',\n * revision: '613e6c7332dd83e848a8b00c403827ed'\n * },\n * {\n * url: '/about.html',\n * revision: '59a325f32baad11bd47a8c515ec44ae5'\n * }\n * ]);\n *\n * @param {Array<String|Object>} revisionedFiles A set of urls to cache\n * when the service worker is installed.\n */\n precache(revisionedFiles) {\n // Add a more helpful error message than assertion error.\n if (!Array.isArray(revisionedFiles)) {\n throw ErrorFactory.createError('bad-revisioned-cache-list');\n }\n\n this._revisionedCacheManager.addToCacheList({\n revisionedFiles,\n });\n }\n\n /**\n * The router for this library is exposed via the `router` parameter.\n * This is an instance of the {@link module:workbox-sw.Router|Router}.\n *\n * @example\n * const workboxSW = new WorkboxSW();\n * workboxSW.router.registerRoute('/', workboxSW.workbox.cacheFirst());\n *\n * @type {Router}\n */\n get router() {\n return this._router;\n }\n\n /**\n * The supported caching strategies shipped with workbox-sw are provided via\n * the `strategies` object.\n * {@link module:workbox-sw.Strategies|See Strategies for a complete list}.\n *\n * @example\n * const workboxSW = new WorkboxSW();\n * workboxSW.router.registerRoute('/styles/*',\n * workboxSW.strategies.cacheFirst());\n */\n get strategies() {\n return this._strategies;\n }\n\n /**\n * The name of the cache used by default by the runtime caching strategies.\n *\n * Entries that are managed via `precache()` are stored in a separate cache\n * with a different name.\n *\n * You can override the default cache name when constructing a strategy if\n * you'd prefer, via\n * `workboxSW.strategies.cacheFirst({cacheName: 'my-cache-name'});`\n *\n * If you would like to explicitly add to, remove, or check the contents of\n * the default cache, you can use the [Cache Storage API](https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage)\n * to pass in the default cache name to `caches.open()`. This can be useful if\n * you want to \"prime\" your cache with remote resources that can't be properly\n * managed via `precache()`.\n *\n * @example\n * const cache = await caches.open(workboxSW.runtimeCacheName);\n * await cache.add('https://third-party.com/path/to/file');\n * const contentsOfRuntimeCache = await cache.keys();\n */\n get runtimeCacheName() {\n return this._runtimeCacheName;\n }\n\n /**\n * This method will register listeners for the install and activate events.\n * @private\n * @param {boolean} skipWaiting Whether to activate service worker\n * immediately.\n * @param {boolean} clientsClaim Whether to claim clients in activate or not.\n */\n _registerInstallActivateEvents(skipWaiting, clientsClaim) {\n self.addEventListener('install', (event) => {\n const cachedUrls = this._revisionedCacheManager.getCachedUrls();\n if (cachedUrls.length > 0) {\n logHelper.debug({\n that: this,\n message: `The precached URLs will automatically be served using a\n cache-first strategy.`,\n data: {'Precached URLs': JSON.stringify(cachedUrls)},\n });\n }\n\n event.waitUntil(\n this._revisionedCacheManager.install()\n .then(() => {\n if (skipWaiting) {\n return self.skipWaiting();\n }\n })\n );\n });\n\n self.addEventListener('activate', (event) => {\n event.waitUntil(\n this._revisionedCacheManager.cleanup()\n .then(() => {\n if (clientsClaim) {\n return self.clients.claim();\n }\n })\n );\n });\n }\n\n /**\n * This method will register any default routes the library will need.\n * @private\n * @param {Array<RegExp>} ignoreUrlParametersMatching An array of regex's\n * used to remove search parameters which match on of them.\n * @param {string} directoryIndex The directory index is appended to URLs\n * ending with '/'.\n */\n _registerDefaultRoutes(ignoreUrlParametersMatching, directoryIndex) {\n const plugins = [];\n\n // Add custom directory index plugin.\n if (ignoreUrlParametersMatching || directoryIndex) {\n plugins.push(\n this._getCacheMatchPlugin(ignoreUrlParametersMatching, directoryIndex)\n );\n }\n\n const cacheFirstHandler = this.strategies.cacheFirst({\n cacheName: this._revisionedCacheManager.getCacheName(),\n plugins,\n // this._revisionedCacheManager.getCacheName() already includes a cacheId\n // prefix if the developer set one. We want to tell the cacheFirst()\n // factory method to exclude the cacheId to ensure that it doesn't prepend\n // the cacheId twice when it determines its cache name.\n // See https://github.com/GoogleChrome/workbox/issues/714\n excludeCacheId: true,\n });\n\n const capture = ({url}) => {\n // See https://github.com/GoogleChrome/workbox/issues/488.\n // The incoming URL might include a hash/URL fragment, and the URLs in\n // the cachedUrls array will never include a hash. We need to normalize\n // the incoming URL to ensure that the string comparison works.\n url.hash = '';\n\n const cachedUrls = this._revisionedCacheManager.getCachedUrls();\n if (cachedUrls.indexOf(url.href) !== -1) {\n return true;\n }\n\n let strippedUrl =\n this._removeIgnoreUrlParams(url.href, ignoreUrlParametersMatching);\n if (cachedUrls.indexOf(strippedUrl.href) !== -1) {\n return true;\n }\n\n if (directoryIndex && strippedUrl.pathname.endsWith('/')) {\n strippedUrl.pathname += directoryIndex;\n return cachedUrls.indexOf(strippedUrl.href) !== -1;\n }\n\n return false;\n };\n\n this._precacheRouter.registerRoute(capture, cacheFirstHandler);\n }\n\n /**\n * @private\n * @param {Array<RegExp>} ignoreUrlParametersMatching An array of regex's to\n * define which search parameters should be removed before looking for cache\n * match.\n * @param {string} directoryIndex The directory index is appended to URLs\n * ending with '/'.\n * @return {Promise<Object>} Returns a plugin that attempts to match the\n * URL with /index.html\n */\n _getCacheMatchPlugin(ignoreUrlParametersMatching, directoryIndex) {\n const cacheMatchFunction = async (\n {request, cache, cachedResponse, matchOptions}) => {\n // If we already have a cache hit, then just return that.\n if (cachedResponse) {\n return cachedResponse;\n }\n\n let strippedUrl =\n this._removeIgnoreUrlParams(request.url, ignoreUrlParametersMatching);\n return cache.match(strippedUrl.toString(), matchOptions)\n .then((response) => {\n if (!response) {\n // Otherwise, try again with the indexHtmlString value.\n if (strippedUrl.pathname.endsWith('/')) {\n strippedUrl.pathname += directoryIndex;\n return cache.match(strippedUrl.toString(), matchOptions);\n }\n }\n\n return response;\n });\n };\n\n return {cachedResponseWillBeUsed: cacheMatchFunction};\n }\n\n /**\n * @private\n * @param {string} originalUrl The original url to remove the search params.\n * @param {Array<RegExp>} ignoreUrlParametersMatching An array of regex's to\n * define which search parameters should be removed before looking for cache\n * match.\n * @return {string} An object that can be used as a plugin within a\n * RequestWrapper.\n */\n _removeIgnoreUrlParams(originalUrl, ignoreUrlParametersMatching) {\n const url = new URL(originalUrl);\n\n // Exclude initial '?'\n const searchString = url.search.slice(1);\n\n // Split into an array of 'key=value' strings\n const keyValueStrings = searchString.split('&');\n const keyValuePairs = keyValueStrings.map((keyValueString) => {\n // Split each 'key=value' string into a [key, value] array\n return keyValueString.split('=');\n });\n\n const filteredKeyValuesPairs = keyValuePairs.filter((keyValuePair) => {\n return ignoreUrlParametersMatching\n .every((ignoredRegex) => {\n // Return true iff the key doesn't match any of the regexes.\n return !ignoredRegex.test(keyValuePair[0]);\n });\n });\n const filteredStrings = filteredKeyValuesPairs.map((keyValuePair) => {\n // Join each [key, value] array into a 'key=value' string\n return keyValuePair.join('=');\n });\n\n // Join the array of 'key=value' strings into a string with '&' in\n // between each\n url.search = filteredStrings.join('&');\n\n return url;\n }\n}\n\nexport default WorkboxSW;\n"],"names":["constructor","_errors","createError","replace","message","stack","name","errors","parse","Object","keys","some","throwError","map","join","pop","includes","Array","isArray","ErrorStackParser","length","functionName","hasMethod","handler","isType","handle","match","method","normalizeHandler","isOneOf","validMethods","defaultMethod","prototype","toString","call","pathToRegexp","compile","tokensToFunction","tokensToRegExp","PATH_REGEXP","delimiter","exec","index","slice","push","prefix","optional","repeat","partial","asterisk","pattern","escapeGroup","escapeString","substr","charCodeAt","toUpperCase","pretty","encodeURIComponentPretty","encodeURIComponent","isarray","JSON","stringify","test","encodeAsterisk","sensitive","source","flags","strict","end","attachKeys","regexpToRegexp","arrayToRegexp","stringToRegexp","path","startsWith","pathToRegExp","url","origin","location","pathname","href","forEach","_logs","_childGroups","_isFallbackMode","navigator","userAgent","parseInt","addPrimaryLog","_primaryLog","addLog","addChildGroup","print","_printLogDetails","console","groupCollapsed","_getLogContent","groupEnd","logFunc","log","colors","concat","args","self","hostname","workbox","LOG_LEVEL","none","verbose","debug","warn","error","DARK_GREY","LIGHT_GREEN","LIGHT_YELLOW","LIGHT_RED","LIGHT_BLUE","_defaultLogLevel","isDevBuild","_printMessage","_shouldLogMessage","_getAllLogGroups","_getPrimaryMessageDetails","that","_getKeyValueDetails","data","LIGHT_GREY","logLevel","whitelist","blacklist","isArrayOfClass","RegExp","event","request","mode","search","logHelper","regExp","isInstance","_routes","_isListenerRegistered","addFetchListener","addEventListener","handleRequest","respondWith","FetchEvent","protocol","params","_findHandlerAndParams","defaultHandler","catchHandler","catch","get","route","setDefaultHandler","setCatchHandler","registerRoutes","routes","Route","has","set","unshift","registerRoute","unregisterRoutes","indexOf","splice","unregisterRoute","handleFetch","_revisionedCacheName","registerNavigationRoute","cacheName","caches","statuses","headers","atLeastOne","isArrayOfType","isResponseCacheable","response","Response","status","cacheWillUpdate","cacheId","registration","scope","pluginCallbacks","clone","Promise","resolve","body","blob","then","statusText","plugins","fetchOptions","matchOptions","getDefaultCacheName","_userSpecifiedCachableResponsePlugin","getDefaultCacheableResponsePlugin","_defaultCacheableResponsePlugin","getCache","_cache","open","cachedResponseWillBeUsed","cache","cachedResponse","fetch","Request","requestWillFetch","returnedRequest","fetchDidFail","fetchAndCache","waitOnCache","cacheKey","cacheResponsePlugin","cleanRedirects","redirected","type","put","cacheDidUpdate","oldResponse","newResponse","requestWrapper","_cacheablePlugin","networkTimeoutSeconds","setTimeout","clearTimeout","reject","ErrorFactory","race","tmpIdbName","onsuccess","result","onerror","apply","defineProperty","arguments","_index","_cursor","_request","_store","_tx","complete","oncomplete","onabort","_db","oldVersion","transaction","IDBIndex","IDBCursor","createIndex","IDBObjectStore","objectStore","IDBTransaction","createObjectStore","IDBDatabase","getAll","iterateCursor","value","continue","indexedDB","onupgradeneeded","delete","exports","maxEntries","maxAgeSeconds","_dbs","_caches","_expirationMutex","_timestampForNextRun","getDB","idbName","idbVersion","keyPath","urlPropertyName","timestampPropertyName","unique","isResponseFresh","now","Date","getTime","isNaN","expireEntries","updateTimestamp","hash","findOldEntries","findExtraEntries","deleteFromCacheAndIDB","urls","count","defaultHeadersToCheck","defaultSource","channel","BroadcastChannel","postMessage","cacheUpdatedMessageType","meta","payload","updatedUrl","first","second","headersToCheck","every","channelName","_channel","notifyIfUpdated","responsesAreSame","broadcastUpdate","_cacheId","cacheFirst","_getCachingMechanism","CacheFirst","cacheOnly","CacheOnly","networkFirst","NetworkFirst","networkOnly","NetworkOnly","staleWhileRevalidate","StaleWhileRevalidate","CacheExpirationPlugin","BroadcastCacheUpdatePlugin","CacheableResponsePlugin","excludeCacheId","errorMessageFactory","extras","_entriesToCache","_requestWrapper","credentials","_addEntries","_parsedCacheUrls","_addEntryToInstallList","_parseEntry","getCacheName","getCachedUrls","from","entryID","_onDuplicateInstallEntryFound","install","size","_cacheEntry","all","_isAlreadyCached","revision","wasUpdated","getNetworkRequest","_onEntryCached","cleanup","_getCache","filter","_onEntryDeleted","_onDuplicateEntryFound","_name","_version","_storeName","_getDb","_dbPromise","idb","close","getAllValues","getAllKeys","version","tmpRevisionedCacheName","_idbHelper","dbName","dbVersion","dbStorename","_close","cacheBust","cacheBustParamName","problemParam","problemValue","defaultRevisionedCacheName","_revisionDetailsModel","addToCacheList","revisionedFiles","input","firstEntry","secondEntry","_createLogFriendlyString","isServiceWorkerGlobalScope","skipWaiting","clientsClaim","directoryIndex","precacheChannelName","ignoreUrlParametersMatching","isLocalhost","_runtimeCacheName","_revisionedCacheManager","_strategies","_precacheRouter","_router","_registerInstallActivateEvents","_registerDefaultRoutes","precache","waitUntil","clients","claim","_getCacheMatchPlugin","strategies","_removeIgnoreUrlParams","endsWith","split"],"mappings":"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"} |