/** * Copyright 2016 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY! // This file should be overwritten as part of your build process. // If you need to extend the behavior of the generated service worker, the best approach is to write // additional code and include it using the importScripts option: // https://github.com/GoogleChrome/sw-precache#importscripts-arraystring // // Alternatively, it's possible to make changes to the underlying template file and then use that as the // new base for generating output, via the templateFilePath option: // https://github.com/GoogleChrome/sw-precache#templatefilepath-string // // If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any // changes made to this original template file with your modified copy. // This generated service worker JavaScript will precache your site's resources. // The code needs to be saved in a .js file at the top-level of your site, and registered // from your pages in order to be used. See // https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js // for an example of how you can register this script and handle various service worker events. /* eslint-env worker, serviceworker */ /* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */ 'use strict'; var precacheConfig = [["404.html","27161e9319153913027bd7dfea90de2e"],["browserconfig.xml","67c3113b1574fecc6015d56d774e1d38"],["categories/index.xml","b7219ca118bac884b575439e179569e2"],["css/fonts/miriamlibre-bold.woff","96496f6f06535d25b3bcba876917ca35"],["css/fonts/miriamlibre-bold.woff2","668defa44d9a74dd709ce0c826a5eb11"],["css/images/arrow_effect.svg","1434d178461f70c16b77acb4bdbc51e3"],["css/images/icon-tick.svg","35d4d4728ea80d254508b2bca4109d70"],["css/images/stripe.svg","fa3f32a026b6a1bb04ee98d963432e15"],["css/prism.css","004029c8c70ed2bbaa5d9debcf14f8c7"],["css/styles.css","5045782434e99730a2fa795b0b4af63b"],["images/android-icon-144x144.png","43e1f47f182b13d0dee15f510213e928"],["images/android-icon-192x192.png","4c07782e52e0ab714074e6d3d69dc3ec"],["images/android-icon-36x36.png","3b2cd8c925a66bf84c89b68bb30e5f62"],["images/android-icon-48x48.png","45dc386eea1d8a46216a8b6de9b156c6"],["images/android-icon-512x512.png","42d6b28cc7eb41810a5392c81368340a"],["images/android-icon-72x72.png","b04c64637efed2b04fa900ddfcbfe75d"],["images/android-icon-96x96.png","bd9c126a4d6baf7ce442122ce0e89e11"],["images/apple-icon-precomposed.png","478755b1c3e0d2c8aea975033cff9ac8"],["images/apple-icon.png","478755b1c3e0d2c8aea975033cff9ac8"],["images/apple-touch-icon-114x114.png","95804b2192b0cea406b54cb31345c47d"],["images/apple-touch-icon-120x120.png","b5da0625c9e876bdf9768875f7dd9cca"],["images/apple-touch-icon-144x144.png","976151c9ecd72311dc6024917292209d"],["images/apple-touch-icon-152x152.png","8bd6a2e592c1c8463b5205ba8436227e"],["images/apple-touch-icon-180x180.png","56a93f4271dea903196794095e9f9ccc"],["images/apple-touch-icon-57x57.png","977183ab3bfb98da8d79e025f1cb4946"],["images/apple-touch-icon-60x60.png","55e9e05103a9b472a52f4c572a73b2b2"],["images/apple-touch-icon-72x72.png","1ef87a2887baab846f2501beb27445ee"],["images/apple-touch-icon-76x76.png","769826cd7526df4db7f4ba1a820158bd"],["images/bad_design_system.png","9c0e87a34e7d842b0e2831dc947249aa"],["images/browser-chrome-android.svg","3100b2a9c5f0e34982c717fc2aa46d73"],["images/browser-chrome.svg","fa39b4be6727525330e928f582fbe80a"],["images/browser-edge.svg","9e8265ab8f6a701587a4271dd3aa6a73"],["images/browser-firefox-android.svg","452df7b9e83c70a07e8e03b4e8dab9c4"],["images/browser-firefox.svg","d3093eda664be3d0cc6d791e1386420f"],["images/browser-ie.svg","13e192cf2b3fe17e7049a49b7d085caa"],["images/browser-opera.svg","95d65630c9f7deef6a3098af8f5baf9f"],["images/browser-safari-ios.svg","f729e629ec998ec40d313495d7257741"],["images/browser-safari.svg","523ee9491f5a937b8975f4d23aa77f62"],["images/favicon-16x16.png","7a99c20d6c00babddd26d03607b8721d"],["images/favicon-32x32.png","129881474a1bf130027bff7a1e89febd"],["images/favicon-96x96.png","bd9c126a4d6baf7ce442122ce0e89e11"],["images/favicon.ico","81c46feedbfcc6c6dc9495e4fd5adfad"],["images/icon-info.svg","53a6c555ce41f818556c71ab0dfc533b"],["images/icon-tag.svg","f067bbbc072941b2a0335679300bfc6c"],["images/icon-warning.svg","2a4322abbee9aed694fadb50e98a1f61"],["images/logo.svg","41f1c1780c2c5efa41d64359dbd651bb"],["images/ms-icon-144x144.png","43e1f47f182b13d0dee15f510213e928"],["images/ms-icon-150x150.png","e73370837ab9060772a18d62aaacd0f0"],["images/ms-icon-310x310.png","8a7143516b929702e3309bb537a99c5c"],["images/ms-icon-70x70.png","d7c6e7368733d53b5f979546d5aa4fe9"],["images/open_in_desktop.png","e899d6679b011aa7b0e783683d90d99b"],["images/samsung_homescreen.jpg","4462178424f5ce79b5757748ba5f1ec4"],["images/serve_from_docs.png","15ae9eac3737a21593ebe00a9312bf9e"],["index.html","1dd18efb1e872a6fa04f0e24d69f51e2"],["index.xml","3607b9dfcc8b4de39e9b24d84e079e0b"],["js/dom-scripts.js","d1226c17a56c156113ee538031a0b6bf"],["js/prism.js","0c1fb8d3a69ee7c91dbf0f361ded7763"],["js/service-worker-registration.js","d60f01dc1393cbaaf4f7435339074d5e"],["manifest.json","381e6af4fc2816f9a137f1ef30c10ebd"],["patterns/coding/code-blocks/index.html","30e4e4cafccfc068b28f369b952225a2"],["patterns/coding/color-palettes/index.html","02d6a136bdda617ccea10bfdce73e9de"],["patterns/coding/command-line/index.html","be235322e7cce7dd73ba38838c505254"],["patterns/coding/demo-embedding/index.html","967a28d183c34de6e49bd8cf397db32e"],["patterns/coding/file-trees/index.html","a52c1705bf6e3a45721f5ca15b5d6ccc"],["patterns/coding/index.html","326e8de49357cb8f3f4e8f7ad3989746"],["patterns/coding/index.xml","bb560877223964ac60e0b9a1248a6d35"],["patterns/coding/tested/index.html","84049828961d923b6d5028bff54e97db"],["patterns/coding/writing-inline-demos/index.html","30d4f9fb64d039c6160ea41cf6d99699"],["patterns/index.html","fbc29e79051ca0e88d82cfb9f9802dbd"],["patterns/index.xml","d5858fce0b97eabfdd83c867eed1375b"],["patterns/installation/index.html","3c1c25eb7c5ec2f6a4192dc6c90188de"],["patterns/media/including-images/index.html","99d1e7c2edda76aaa1b81f5766f388a6"],["patterns/media/including-videos/index.html","07b9627cdd045d289489694873e8ce6c"],["patterns/media/index.html","d24c9248c4d23ea88c9be4f501a7ca9a"],["patterns/media/index.xml","71e2766a93623611b6b4c31ae4023eb8"],["patterns/printing/index.html","0ff01ea9a5f2b992d294923617a955fc"],["patterns/serving/index.html","7f8059530d8c617a07e5e4f1c596bc00"],["patterns/setup/index.html","c19f005ae018d13489d1a80b5b2f8420"],["patterns/updating/index.html","f0db2d7b9dadf803dfd76abe57a8a41b"],["patterns/writing/expandable-sections/index.html","14c6973c2b21d97bf8d5c88a1d533af3"],["patterns/writing/index.html","aee1e81de99522785f3b10129e8816b7"],["patterns/writing/index.xml","4cddff005a675e89bf2677d91ffc3723"],["patterns/writing/markdown-and-metadata/index.html","cf0648192aac416bc155d940d31717fc"],["patterns/writing/notes-and-warnings/index.html","04851100417c568a94f18d728e6355a6"],["patterns/writing/project-structure/index.html","5012abea3a86c86704187bade40509f7"],["patterns/writing/references/index.html","88a0d590dc87da54bef9ac8288b01c9d"],["patterns/writing/snippets/index.html","184a9cefcd8f4db3b1ee56a613dc3cab"],["patterns/writing/tables-of-contents/index.html","3108ad93ed97288fcbf4c32d8d76cee3"],["print-version/index.html","e773f9a83feb1461c206dd6e738b446f"],["sitemap.xml","3eb68d8dc7012b3f5e73b45320d81868"],["tags/index.xml","f9dcce911a40c37aa7dc4ffd4e623a29"],["tags/markdown/index.html","ff8cdddef3117c8a1156e0d9e7a8995a"],["tags/markdown/index.xml","7e7c99e47c7ba81c9f36493e87925bc4"],["tags/metadata/index.html","d9a8d80f07e4fa6c8f1100bae79e7537"],["tags/metadata/index.xml","39f48a6b0cc323e2c1f24dacb7a11442"]]; var cacheName = 'sw-precache-v3-sw-precache-' + (self.registration ? self.registration.scope : ''); var ignoreUrlParametersMatching = [/^utm_/]; var addDirectoryIndex = function (originalUrl, index) { var url = new URL(originalUrl); if (url.pathname.slice(-1) === '/') { url.pathname += index; } return url.toString(); }; var cleanResponse = function (originalResponse) { // If this is not a redirected response, then we don't have to do anything. if (!originalResponse.redirected) { return Promise.resolve(originalResponse); } // Firefox 50 and below doesn't support the Response.body stream, so we may // need to read the entire body to memory as a Blob. var bodyPromise = 'body' in originalResponse ? Promise.resolve(originalResponse.body) : originalResponse.blob(); return bodyPromise.then(function(body) { // new Response() is happy when passed either a stream or a Blob. return new Response(body, { headers: originalResponse.headers, status: originalResponse.status, statusText: originalResponse.statusText }); }); }; var createCacheKey = function (originalUrl, paramName, paramValue, dontCacheBustUrlsMatching) { // Create a new URL object to avoid modifying originalUrl. var url = new URL(originalUrl); // If dontCacheBustUrlsMatching is not set, or if we don't have a match, // then add in the extra cache-busting URL parameter. if (!dontCacheBustUrlsMatching || !(url.pathname.match(dontCacheBustUrlsMatching))) { url.search += (url.search ? '&' : '') + encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue); } return url.toString(); }; var isPathWhitelisted = function (whitelist, absoluteUrlString) { // If the whitelist is empty, then consider all URLs to be whitelisted. if (whitelist.length === 0) { return true; } // Otherwise compare each path regex to the path of the URL passed in. var path = (new URL(absoluteUrlString)).pathname; return whitelist.some(function(whitelistedPathRegex) { return path.match(whitelistedPathRegex); }); }; var stripIgnoredUrlParameters = function (originalUrl, ignoreUrlParametersMatching) { var url = new URL(originalUrl); // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290 url.hash = ''; url.search = url.search.slice(1) // Exclude initial '?' .split('&') // Split into an array of 'key=value' strings .map(function(kv) { return kv.split('='); // Split each 'key=value' string into a [key, value] array }) .filter(function(kv) { return ignoreUrlParametersMatching.every(function(ignoredRegex) { return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes. }); }) .map(function(kv) { return kv.join('='); // Join each [key, value] array into a 'key=value' string }) .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each return url.toString(); }; var hashParamName = '_sw-precache'; var urlsToCacheKeys = new Map( precacheConfig.map(function(item) { var relativeUrl = item[0]; var hash = item[1]; var absoluteUrl = new URL(relativeUrl, self.location); var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false); return [absoluteUrl.toString(), cacheKey]; }) ); function setOfCachedUrls(cache) { return cache.keys().then(function(requests) { return requests.map(function(request) { return request.url; }); }).then(function(urls) { return new Set(urls); }); } self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return setOfCachedUrls(cache).then(function(cachedUrls) { return Promise.all( Array.from(urlsToCacheKeys.values()).map(function(cacheKey) { // If we don't have a key matching url in the cache already, add it. if (!cachedUrls.has(cacheKey)) { var request = new Request(cacheKey, {credentials: 'same-origin'}); return fetch(request).then(function(response) { // Bail out of installation unless we get back a 200 OK for // every request. if (!response.ok) { throw new Error('Request for ' + cacheKey + ' returned a ' + 'response with status ' + response.status); } return cleanResponse(response).then(function(responseToCache) { return cache.put(cacheKey, responseToCache); }); }); } }) ); }); }).then(function() { // Force the SW to transition from installing -> active state return self.skipWaiting(); }) ); }); self.addEventListener('activate', function(event) { var setOfExpectedUrls = new Set(urlsToCacheKeys.values()); event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.keys().then(function(existingRequests) { return Promise.all( existingRequests.map(function(existingRequest) { if (!setOfExpectedUrls.has(existingRequest.url)) { return cache.delete(existingRequest); } }) ); }); }).then(function() { return self.clients.claim(); }) ); }); self.addEventListener('fetch', function(event) { if (event.request.method === 'GET') { // Should we call event.respondWith() inside this fetch event handler? // This needs to be determined synchronously, which will give other fetch // handlers a chance to handle the request if need be. var shouldRespond; // First, remove all the ignored parameters and hash fragment, and see if we // have that URL in our cache. If so, great! shouldRespond will be true. var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching); shouldRespond = urlsToCacheKeys.has(url); // If shouldRespond is false, check again, this time with 'index.html' // (or whatever the directoryIndex option is set to) at the end. var directoryIndex = 'index.html'; if (!shouldRespond && directoryIndex) { url = addDirectoryIndex(url, directoryIndex); shouldRespond = urlsToCacheKeys.has(url); } // If shouldRespond is still false, check to see if this is a navigation // request, and if so, whether the URL matches navigateFallbackWhitelist. var navigateFallback = ''; if (!shouldRespond && navigateFallback && (event.request.mode === 'navigate') && isPathWhitelisted([], event.request.url)) { url = new URL(navigateFallback, self.location).toString(); shouldRespond = urlsToCacheKeys.has(url); } // If shouldRespond was set to true at any point, then call // event.respondWith(), using the appropriate cache key. if (shouldRespond) { event.respondWith( caches.open(cacheName).then(function(cache) { return cache.match(urlsToCacheKeys.get(url)).then(function(response) { if (response) { return response; } throw Error('The cached response that was expected is missing.'); }); }).catch(function(e) { // Fall back to just fetch()ing the request if some unexpected error // prevented the cached response from being valid. console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e); return fetch(event.request); }) ); } } });