From 1edee4141c6e90d61e296fbf780d8b7e54da51f9 Mon Sep 17 00:00:00 2001 From: Ali Akbar <116874053+aliakbar-deriv@users.noreply.github.com> Date: Tue, 7 Jan 2025 12:31:36 +0400 Subject: [PATCH] Feat/pwa implementation (#59) * feat: implement PWA functionality with vite-plugin-pwa * fix: update app icons * feat: improve PWA install banner UI and UX * fix: update PWA configuration and manifest paths * refactor: move pwa-handler to utils and improve PWA installation * chore: update mobile screenshot path in vite config --- dev-dist/suppress-warnings.js | 0 dev-dist/sw.js | 102 + dev-dist/sw.js.map | 1 + dev-dist/workbox-54d0af47.js | 3391 +++++++++++++++++++ dev-dist/workbox-e755d862.js | 4702 +++++++++++++++++++++++++++ dev-dist/workbox-e755d862.js.map | 1 + index.html | 53 +- package-lock.json | 2514 +++++++++++++- package.json | 3 +- public/apple-touch-icon.png | Bin 0 -> 919 bytes public/desktop-screenshot.png | Bin 0 -> 95071 bytes public/favicon.ico | Bin 0 -> 1006 bytes public/favicon.svg | 1 + public/mobile-screenshot.png | Bin 0 -> 180460 bytes public/pwa-192x192.png | Bin 0 -> 1208 bytes public/pwa-512x512.png | Bin 0 -> 3615 bytes public/pwa-maskable-192x192.png | Bin 0 -> 962 bytes public/pwa-maskable-512x512.png | Bin 0 -> 2888 bytes src/App.jsx | 2 + src/components/PWAInstallBanner.jsx | 123 + src/main.jsx | 29 + src/utils/pwa-handler.js | 31 + tailwind.config.js | 9 + vite.config.js | 127 +- 24 files changed, 11001 insertions(+), 88 deletions(-) create mode 100644 dev-dist/suppress-warnings.js create mode 100644 dev-dist/sw.js create mode 100644 dev-dist/sw.js.map create mode 100644 dev-dist/workbox-54d0af47.js create mode 100644 dev-dist/workbox-e755d862.js create mode 100644 dev-dist/workbox-e755d862.js.map create mode 100644 public/apple-touch-icon.png create mode 100644 public/desktop-screenshot.png create mode 100644 public/favicon.ico create mode 100644 public/favicon.svg create mode 100644 public/mobile-screenshot.png create mode 100644 public/pwa-192x192.png create mode 100644 public/pwa-512x512.png create mode 100644 public/pwa-maskable-192x192.png create mode 100644 public/pwa-maskable-512x512.png create mode 100644 src/components/PWAInstallBanner.jsx create mode 100644 src/utils/pwa-handler.js diff --git a/dev-dist/suppress-warnings.js b/dev-dist/suppress-warnings.js new file mode 100644 index 0000000..e69de29 diff --git a/dev-dist/sw.js b/dev-dist/sw.js new file mode 100644 index 0000000..a0de607 --- /dev/null +++ b/dev-dist/sw.js @@ -0,0 +1,102 @@ +/** + * Copyright 2018 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. + */ + +// If the loader is already loaded, just stop. +if (!self.define) { + let registry = {}; + + // Used for `eval` and `importScripts` where we can't get script URL by other means. + // In both cases, it's safe to use a global var because those functions are synchronous. + let nextDefineUri; + + const singleRequire = (uri, parentUri) => { + uri = new URL(uri + ".js", parentUri).href; + return registry[uri] || ( + + new Promise(resolve => { + if ("document" in self) { + const script = document.createElement("script"); + script.src = uri; + script.onload = resolve; + document.head.appendChild(script); + } else { + nextDefineUri = uri; + importScripts(uri); + resolve(); + } + }) + + .then(() => { + let promise = registry[uri]; + if (!promise) { + throw new Error(`Module ${uri} didn’t register its module`); + } + return promise; + }) + ); + }; + + self.define = (depsNames, factory) => { + const uri = nextDefineUri || ("document" in self ? document.currentScript.src : "") || location.href; + if (registry[uri]) { + // Module is already loading or loaded. + return; + } + let exports = {}; + const require = depUri => singleRequire(depUri, uri); + const specialDeps = { + module: { uri }, + exports, + require + }; + registry[uri] = Promise.all(depsNames.map( + depName => specialDeps[depName] || require(depName) + )).then(deps => { + factory(...deps); + return exports; + }); + }; +} +define(['./workbox-e755d862'], (function (workbox) { 'use strict'; + + self.skipWaiting(); + workbox.clientsClaim(); + + /** + * The precacheAndRoute() method efficiently caches and responds to + * requests for URLs in the manifest. + * See https://goo.gl/S9QRab + */ + workbox.precacheAndRoute([{ + "url": "suppress-warnings.js", + "revision": "d41d8cd98f00b204e9800998ecf8427e" + }, { + "url": "index.html", + "revision": "0.sbb7t5tl6kg" + }], {}); + workbox.cleanupOutdatedCaches(); + workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { + allowlist: [/^\/$/] + })); + workbox.registerRoute(/^https:\/\/api\.deriv\.com\/.*/i, new workbox.NetworkFirst({ + "cacheName": "api-cache", + plugins: [new workbox.ExpirationPlugin({ + maxEntries: 50, + maxAgeSeconds: 86400 + }), new workbox.CacheableResponsePlugin({ + statuses: [0, 200] + })] + }), 'GET'); + +})); +//# sourceMappingURL=sw.js.map diff --git a/dev-dist/sw.js.map b/dev-dist/sw.js.map new file mode 100644 index 0000000..73771e5 --- /dev/null +++ b/dev-dist/sw.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sw.js","sources":["../../../../../private/var/folders/d9/jx1w3yzd77lbjj7ygwch_kgh0000gn/T/f57b6b56154ba591d3ee577aae5d13ad/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/aliakbar/Documents/Projects/copy-trading/node_modules/workbox-routing/registerRoute.mjs';\nimport {ExpirationPlugin as workbox_expiration_ExpirationPlugin} from '/Users/aliakbar/Documents/Projects/copy-trading/node_modules/workbox-expiration/ExpirationPlugin.mjs';\nimport {CacheableResponsePlugin as workbox_cacheable_response_CacheableResponsePlugin} from '/Users/aliakbar/Documents/Projects/copy-trading/node_modules/workbox-cacheable-response/CacheableResponsePlugin.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/aliakbar/Documents/Projects/copy-trading/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/aliakbar/Documents/Projects/copy-trading/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/Users/aliakbar/Documents/Projects/copy-trading/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from '/Users/aliakbar/Documents/Projects/copy-trading/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/Users/aliakbar/Documents/Projects/copy-trading/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/Users/aliakbar/Documents/Projects/copy-trading/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"suppress-warnings.js\",\n \"revision\": \"d41d8cd98f00b204e9800998ecf8427e\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"0.sbb7t5tl6kg\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"index.html\"), {\n allowlist: [/^\\/$/],\n \n}));\n\n\nworkbox_routing_registerRoute(/^https:\\/\\/api\\.deriv\\.com\\/.*/i, new workbox_strategies_NetworkFirst({ \"cacheName\":\"api-cache\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 50, maxAgeSeconds: 86400 }), new workbox_cacheable_response_CacheableResponsePlugin({ statuses: [ 0, 200 ] })] }), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","workbox_precaching_cleanupOutdatedCaches","workbox_routing_registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","allowlist","workbox_strategies_NetworkFirst","plugins","workbox_expiration_ExpirationPlugin","maxEntries","maxAgeSeconds","workbox_cacheable_response_CacheableResponsePlugin","statuses"],"mappings":"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"} \ No newline at end of file diff --git a/dev-dist/workbox-54d0af47.js b/dev-dist/workbox-54d0af47.js new file mode 100644 index 0000000..238d10b --- /dev/null +++ b/dev-dist/workbox-54d0af47.js @@ -0,0 +1,3391 @@ +define(['exports'], (function (exports) { 'use strict'; + + // @ts-ignore + try { + self['workbox:core:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Claim any currently available clients once the service worker + * becomes active. This is normally used in conjunction with `skipWaiting()`. + * + * @memberof workbox-core + */ + function clientsClaim() { + self.addEventListener('activate', () => self.clients.claim()); + } + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const logger = (() => { + // Don't overwrite this value if it's already set. + // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923 + if (!('__WB_DISABLE_DEV_LOGS' in globalThis)) { + self.__WB_DISABLE_DEV_LOGS = false; + } + let inGroup = false; + const methodToColorMap = { + debug: `#7f8c8d`, + log: `#2ecc71`, + warn: `#f39c12`, + error: `#c0392b`, + groupCollapsed: `#3498db`, + groupEnd: null // No colored prefix on groupEnd + }; + const print = function (method, args) { + if (self.__WB_DISABLE_DEV_LOGS) { + return; + } + if (method === 'groupCollapsed') { + // Safari doesn't print all console.groupCollapsed() arguments: + // https://bugs.webkit.org/show_bug.cgi?id=182754 + if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { + console[method](...args); + return; + } + } + const styles = [`background: ${methodToColorMap[method]}`, `border-radius: 0.5em`, `color: white`, `font-weight: bold`, `padding: 2px 0.5em`]; + // When in a group, the workbox prefix is not displayed. + const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')]; + console[method](...logPrefix, ...args); + if (method === 'groupCollapsed') { + inGroup = true; + } + if (method === 'groupEnd') { + inGroup = false; + } + }; + // eslint-disable-next-line @typescript-eslint/ban-types + const api = {}; + const loggerMethods = Object.keys(methodToColorMap); + for (const key of loggerMethods) { + const method = key; + api[method] = (...args) => { + print(method, args); + }; + } + return api; + })(); + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const messages = { + 'invalid-value': ({ + paramName, + validValueDescription, + value + }) => { + if (!paramName || !validValueDescription) { + throw new Error(`Unexpected input to 'invalid-value' error.`); + } + return `The '${paramName}' parameter was given a value with an ` + `unexpected value. ${validValueDescription} Received a value of ` + `${JSON.stringify(value)}.`; + }, + 'not-an-array': ({ + moduleName, + className, + funcName, + paramName + }) => { + if (!moduleName || !className || !funcName || !paramName) { + throw new Error(`Unexpected input to 'not-an-array' error.`); + } + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${className}.${funcName}()' must be an array.`; + }, + 'incorrect-type': ({ + expectedType, + paramName, + moduleName, + className, + funcName + }) => { + if (!expectedType || !paramName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'incorrect-type' error.`); + } + const classNameStr = className ? `${className}.` : ''; + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}` + `${funcName}()' must be of type ${expectedType}.`; + }, + 'incorrect-class': ({ + expectedClassName, + paramName, + moduleName, + className, + funcName, + isReturnValueProblem + }) => { + if (!expectedClassName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'incorrect-class' error.`); + } + const classNameStr = className ? `${className}.` : ''; + if (isReturnValueProblem) { + return `The return value from ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`; + } + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`; + }, + 'missing-a-method': ({ + expectedMethod, + paramName, + moduleName, + className, + funcName + }) => { + if (!expectedMethod || !paramName || !moduleName || !className || !funcName) { + throw new Error(`Unexpected input to 'missing-a-method' error.`); + } + return `${moduleName}.${className}.${funcName}() expected the ` + `'${paramName}' parameter to expose a '${expectedMethod}' method.`; + }, + 'add-to-cache-list-unexpected-type': ({ + entry + }) => { + return `An unexpected entry was passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' The entry ` + `'${JSON.stringify(entry)}' isn't supported. You must supply an array of ` + `strings with one or more characters, objects with a url property or ` + `Request objects.`; + }, + 'add-to-cache-list-conflicting-entries': ({ + firstEntry, + secondEntry + }) => { + if (!firstEntry || !secondEntry) { + throw new Error(`Unexpected input to ` + `'add-to-cache-list-duplicate-entries' error.`); + } + return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + `${firstEntry} but different revision details. Workbox is ` + `unable to cache and version the asset correctly. Please remove one ` + `of the entries.`; + }, + 'plugin-error-request-will-fetch': ({ + thrownErrorMessage + }) => { + if (!thrownErrorMessage) { + throw new Error(`Unexpected input to ` + `'plugin-error-request-will-fetch', error.`); + } + return `An error was thrown by a plugins 'requestWillFetch()' method. ` + `The thrown error message was: '${thrownErrorMessage}'.`; + }, + 'invalid-cache-name': ({ + cacheNameId, + value + }) => { + if (!cacheNameId) { + throw new Error(`Expected a 'cacheNameId' for error 'invalid-cache-name'`); + } + return `You must provide a name containing at least one character for ` + `setCacheDetails({${cacheNameId}: '...'}). Received a value of ` + `'${JSON.stringify(value)}'`; + }, + 'unregister-route-but-not-found-with-method': ({ + method + }) => { + if (!method) { + throw new Error(`Unexpected input to ` + `'unregister-route-but-not-found-with-method' error.`); + } + return `The route you're trying to unregister was not previously ` + `registered for the method type '${method}'.`; + }, + 'unregister-route-route-not-registered': () => { + return `The route you're trying to unregister was not previously ` + `registered.`; + }, + 'queue-replay-failed': ({ + name + }) => { + return `Replaying the background sync queue '${name}' failed.`; + }, + 'duplicate-queue-name': ({ + name + }) => { + return `The Queue name '${name}' is already being used. ` + `All instances of backgroundSync.Queue must be given unique names.`; + }, + 'expired-test-without-max-age': ({ + methodName, + paramName + }) => { + return `The '${methodName}()' method can only be used when the ` + `'${paramName}' is used in the constructor.`; + }, + 'unsupported-route-type': ({ + moduleName, + className, + funcName, + paramName + }) => { + return `The supplied '${paramName}' parameter was an unsupported type. ` + `Please check the docs for ${moduleName}.${className}.${funcName} for ` + `valid input types.`; + }, + 'not-array-of-class': ({ + value, + expectedClass, + moduleName, + className, + funcName, + paramName + }) => { + return `The supplied '${paramName}' parameter must be an array of ` + `'${expectedClass}' objects. Received '${JSON.stringify(value)},'. ` + `Please check the call to ${moduleName}.${className}.${funcName}() ` + `to fix the issue.`; + }, + 'max-entries-or-age-required': ({ + moduleName, + className, + funcName + }) => { + return `You must define either config.maxEntries or config.maxAgeSeconds` + `in ${moduleName}.${className}.${funcName}`; + }, + 'statuses-or-headers-required': ({ + moduleName, + className, + funcName + }) => { + return `You must define either config.statuses or config.headers` + `in ${moduleName}.${className}.${funcName}`; + }, + 'invalid-string': ({ + moduleName, + funcName, + paramName + }) => { + if (!paramName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'invalid-string' error.`); + } + return `When using strings, the '${paramName}' parameter must start with ` + `'http' (for cross-origin matches) or '/' (for same-origin matches). ` + `Please see the docs for ${moduleName}.${funcName}() for ` + `more info.`; + }, + 'channel-name-required': () => { + return `You must provide a channelName to construct a ` + `BroadcastCacheUpdate instance.`; + }, + 'invalid-responses-are-same-args': () => { + return `The arguments passed into responsesAreSame() appear to be ` + `invalid. Please ensure valid Responses are used.`; + }, + 'expire-custom-caches-only': () => { + return `You must provide a 'cacheName' property when using the ` + `expiration plugin with a runtime caching strategy.`; + }, + 'unit-must-be-bytes': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'unit-must-be-bytes' error.`); + } + return `The 'unit' portion of the Range header must be set to 'bytes'. ` + `The Range header provided was "${normalizedRangeHeader}"`; + }, + 'single-range-only': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'single-range-only' error.`); + } + return `Multiple ranges are not supported. Please use a single start ` + `value, and optional end value. The Range header provided was ` + `"${normalizedRangeHeader}"`; + }, + 'invalid-range-values': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'invalid-range-values' error.`); + } + return `The Range header is missing both start and end values. At least ` + `one of those values is needed. The Range header provided was ` + `"${normalizedRangeHeader}"`; + }, + 'no-range-header': () => { + return `No Range header was found in the Request provided.`; + }, + 'range-not-satisfiable': ({ + size, + start, + end + }) => { + return `The start (${start}) and end (${end}) values in the Range are ` + `not satisfiable by the cached response, which is ${size} bytes.`; + }, + 'attempt-to-cache-non-get-request': ({ + url, + method + }) => { + return `Unable to cache '${url}' because it is a '${method}' request and ` + `only 'GET' requests can be cached.`; + }, + 'cache-put-with-no-response': ({ + url + }) => { + return `There was an attempt to cache '${url}' but the response was not ` + `defined.`; + }, + 'no-response': ({ + url, + error + }) => { + let message = `The strategy could not generate a response for '${url}'.`; + if (error) { + message += ` The underlying error is ${error}.`; + } + return message; + }, + 'bad-precaching-response': ({ + url, + status + }) => { + return `The precaching request for '${url}' failed` + (status ? ` with an HTTP status of ${status}.` : `.`); + }, + 'non-precached-url': ({ + url + }) => { + return `createHandlerBoundToURL('${url}') was called, but that URL is ` + `not precached. Please pass in a URL that is precached instead.`; + }, + 'add-to-cache-list-conflicting-integrities': ({ + url + }) => { + return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + `${url} with different integrity values. Please remove one of them.`; + }, + 'missing-precache-entry': ({ + cacheName, + url + }) => { + return `Unable to find a precached response in ${cacheName} for ${url}.`; + }, + 'cross-origin-copy-response': ({ + origin + }) => { + return `workbox-core.copyResponse() can only be used with same-origin ` + `responses. It was passed a response with origin ${origin}.`; + }, + 'opaque-streams-source': ({ + type + }) => { + const message = `One of the workbox-streams sources resulted in an ` + `'${type}' response.`; + if (type === 'opaqueredirect') { + return `${message} Please do not use a navigation request that results ` + `in a redirect as a source.`; + } + return `${message} Please ensure your sources are CORS-enabled.`; + } + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const generatorFunction = (code, details = {}) => { + const message = messages[code]; + if (!message) { + throw new Error(`Unable to find message for code '${code}'.`); + } + return message(details); + }; + const messageGenerator = generatorFunction; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Workbox errors should be thrown with this class. + * This allows use to ensure the type easily in tests, + * helps developers identify errors from workbox + * easily and allows use to optimise error + * messages correctly. + * + * @private + */ + class WorkboxError extends Error { + /** + * + * @param {string} errorCode The error code that + * identifies this particular error. + * @param {Object=} details Any relevant arguments + * that will help developers identify issues should + * be added as a key on the context object. + */ + constructor(errorCode, details) { + const message = messageGenerator(errorCode, details); + super(message); + this.name = errorCode; + this.details = details; + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /* + * This method throws if the supplied value is not an array. + * The destructed values are required to produce a meaningful error for users. + * The destructed and restructured object is so it's clear what is + * needed. + */ + const isArray = (value, details) => { + if (!Array.isArray(value)) { + throw new WorkboxError('not-an-array', details); + } + }; + const hasMethod = (object, expectedMethod, details) => { + const type = typeof object[expectedMethod]; + if (type !== 'function') { + details['expectedMethod'] = expectedMethod; + throw new WorkboxError('missing-a-method', details); + } + }; + const isType = (object, expectedType, details) => { + if (typeof object !== expectedType) { + details['expectedType'] = expectedType; + throw new WorkboxError('incorrect-type', details); + } + }; + const isInstance = (object, + // Need the general type to do the check later. + // eslint-disable-next-line @typescript-eslint/ban-types + expectedClass, details) => { + if (!(object instanceof expectedClass)) { + details['expectedClassName'] = expectedClass.name; + throw new WorkboxError('incorrect-class', details); + } + }; + const isOneOf = (value, validValues, details) => { + if (!validValues.includes(value)) { + details['validValueDescription'] = `Valid values are ${JSON.stringify(validValues)}.`; + throw new WorkboxError('invalid-value', details); + } + }; + const isArrayOfClass = (value, + // Need general type to do check later. + expectedClass, + // eslint-disable-line + details) => { + const error = new WorkboxError('not-array-of-class', details); + if (!Array.isArray(value)) { + throw error; + } + for (const item of value) { + if (!(item instanceof expectedClass)) { + throw error; + } + } + }; + const finalAssertExports = { + hasMethod, + isArray, + isInstance, + isOneOf, + isType, + isArrayOfClass + }; + + // @ts-ignore + try { + self['workbox:routing:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The default HTTP method, 'GET', used when there's no specific method + * configured for a route. + * + * @type {string} + * + * @private + */ + const defaultMethod = 'GET'; + /** + * The list of valid HTTP methods associated with requests that could be routed. + * + * @type {Array} + * + * @private + */ + const validMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT']; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * @param {function()|Object} handler Either a function, or an object with a + * 'handle' method. + * @return {Object} An object with a handle method. + * + * @private + */ + const normalizeHandler = handler => { + if (handler && typeof handler === 'object') { + { + finalAssertExports.hasMethod(handler, 'handle', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'handler' + }); + } + return handler; + } else { + { + finalAssertExports.isType(handler, 'function', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'handler' + }); + } + return { + handle: handler + }; + } + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A `Route` consists of a pair of callback functions, "match" and "handler". + * The "match" callback determine if a route should be used to "handle" a + * request by returning a non-falsy value if it can. The "handler" callback + * is called when there is a match and should return a Promise that resolves + * to a `Response`. + * + * @memberof workbox-routing + */ + class Route { + /** + * Constructor for Route class. + * + * @param {workbox-routing~matchCallback} match + * A callback function that determines whether the route matches a given + * `fetch` event by returning a non-falsy value. + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resolving to a Response. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + */ + constructor(match, handler, method = defaultMethod) { + { + finalAssertExports.isType(match, 'function', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'match' + }); + if (method) { + finalAssertExports.isOneOf(method, validMethods, { + paramName: 'method' + }); + } + } + // These values are referenced directly by Router so cannot be + // altered by minificaton. + this.handler = normalizeHandler(handler); + this.match = match; + this.method = method; + } + /** + * + * @param {workbox-routing-handlerCallback} handler A callback + * function that returns a Promise resolving to a Response + */ + setCatchHandler(handler) { + this.catchHandler = normalizeHandler(handler); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * RegExpRoute makes it easy to create a regular expression based + * {@link workbox-routing.Route}. + * + * For same-origin requests the RegExp only needs to match part of the URL. For + * requests against third-party servers, you must define a RegExp that matches + * the start of the URL. + * + * @memberof workbox-routing + * @extends workbox-routing.Route + */ + class RegExpRoute extends Route { + /** + * If the regular expression contains + * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references}, + * the captured values will be passed to the + * {@link workbox-routing~handlerCallback} `params` + * argument. + * + * @param {RegExp} regExp The regular expression to match against URLs. + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + */ + constructor(regExp, handler, method) { + { + finalAssertExports.isInstance(regExp, RegExp, { + moduleName: 'workbox-routing', + className: 'RegExpRoute', + funcName: 'constructor', + paramName: 'pattern' + }); + } + const match = ({ + url + }) => { + const result = regExp.exec(url.href); + // Return immediately if there's no match. + if (!result) { + return; + } + // Require that the match start at the first character in the URL string + // if it's a cross-origin request. + // See https://github.com/GoogleChrome/workbox/issues/281 for the context + // behind this behavior. + if (url.origin !== location.origin && result.index !== 0) { + { + logger.debug(`The regular expression '${regExp.toString()}' only partially matched ` + `against the cross-origin URL '${url.toString()}'. RegExpRoute's will only ` + `handle cross-origin requests if they match the entire URL.`); + } + return; + } + // If the route matches, but there aren't any capture groups defined, then + // this will return [], which is truthy and therefore sufficient to + // indicate a match. + // If there are capture groups, then it will return their values. + return result.slice(1); + }; + super(match, handler, method); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const getFriendlyURL = url => { + const urlObj = new URL(String(url), location.href); + // See https://github.com/GoogleChrome/workbox/issues/2323 + // We want to include everything, except for the origin if it's same-origin. + return urlObj.href.replace(new RegExp(`^${location.origin}`), ''); + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The Router can be used to process a `FetchEvent` using one or more + * {@link workbox-routing.Route}, responding with a `Response` if + * a matching route exists. + * + * If no route matches a given a request, the Router will use a "default" + * handler if one is defined. + * + * Should the matching Route throw an error, the Router will use a "catch" + * handler if one is defined to gracefully deal with issues and respond with a + * Request. + * + * If a request matches multiple routes, the **earliest** registered route will + * be used to respond to the request. + * + * @memberof workbox-routing + */ + class Router { + /** + * Initializes a new Router. + */ + constructor() { + this._routes = new Map(); + this._defaultHandlerMap = new Map(); + } + /** + * @return {Map>} routes A `Map` of HTTP + * method name ('GET', etc.) to an array of all the corresponding `Route` + * instances that are registered. + */ + get routes() { + return this._routes; + } + /** + * Adds a fetch event listener to respond to events when a route matches + * the event's request. + */ + addFetchListener() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('fetch', event => { + const { + request + } = event; + const responsePromise = this.handleRequest({ + request, + event + }); + if (responsePromise) { + event.respondWith(responsePromise); + } + }); + } + /** + * Adds a message event listener for URLs to cache from the window. + * This is useful to cache resources loaded on the page prior to when the + * service worker started controlling it. + * + * The format of the message data sent from the window should be as follows. + * Where the `urlsToCache` array may consist of URL strings or an array of + * URL string + `requestInit` object (the same as you'd pass to `fetch()`). + * + * ``` + * { + * type: 'CACHE_URLS', + * payload: { + * urlsToCache: [ + * './script1.js', + * './script2.js', + * ['./script3.js', {mode: 'no-cors'}], + * ], + * }, + * } + * ``` + */ + addCacheListener() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('message', event => { + // event.data is type 'any' + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (event.data && event.data.type === 'CACHE_URLS') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const { + payload + } = event.data; + { + logger.debug(`Caching URLs from the window`, payload.urlsToCache); + } + const requestPromises = Promise.all(payload.urlsToCache.map(entry => { + if (typeof entry === 'string') { + entry = [entry]; + } + const request = new Request(...entry); + return this.handleRequest({ + request, + event + }); + // TODO(philipwalton): TypeScript errors without this typecast for + // some reason (probably a bug). The real type here should work but + // doesn't: `Array | undefined>`. + })); // TypeScript + event.waitUntil(requestPromises); + // If a MessageChannel was used, reply to the message on success. + if (event.ports && event.ports[0]) { + void requestPromises.then(() => event.ports[0].postMessage(true)); + } + } + }); + } + /** + * Apply the routing rules to a FetchEvent object to get a Response from an + * appropriate Route's handler. + * + * @param {Object} options + * @param {Request} options.request The request to handle. + * @param {ExtendableEvent} options.event The event that triggered the + * request. + * @return {Promise|undefined} A promise is returned if a + * registered route can handle the request. If there is no matching + * route and there's no `defaultHandler`, `undefined` is returned. + */ + handleRequest({ + request, + event + }) { + { + finalAssertExports.isInstance(request, Request, { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'handleRequest', + paramName: 'options.request' + }); + } + const url = new URL(request.url, location.href); + if (!url.protocol.startsWith('http')) { + { + logger.debug(`Workbox Router only supports URLs that start with 'http'.`); + } + return; + } + const sameOrigin = url.origin === location.origin; + const { + params, + route + } = this.findMatchingRoute({ + event, + request, + sameOrigin, + url + }); + let handler = route && route.handler; + const debugMessages = []; + { + if (handler) { + debugMessages.push([`Found a route to handle this request:`, route]); + if (params) { + debugMessages.push([`Passing the following params to the route's handler:`, params]); + } + } + } + // If we don't have a handler because there was no matching route, then + // fall back to defaultHandler if that's defined. + const method = request.method; + if (!handler && this._defaultHandlerMap.has(method)) { + { + debugMessages.push(`Failed to find a matching route. Falling ` + `back to the default handler for ${method}.`); + } + handler = this._defaultHandlerMap.get(method); + } + if (!handler) { + { + // No handler so Workbox will do nothing. If logs is set of debug + // i.e. verbose, we should print out this information. + logger.debug(`No route found for: ${getFriendlyURL(url)}`); + } + return; + } + { + // We have a handler, meaning Workbox is going to handle the route. + // print the routing details to the console. + logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`); + debugMessages.forEach(msg => { + if (Array.isArray(msg)) { + logger.log(...msg); + } else { + logger.log(msg); + } + }); + logger.groupEnd(); + } + // Wrap in try and catch in case the handle method throws a synchronous + // error. It should still callback to the catch handler. + let responsePromise; + try { + responsePromise = handler.handle({ + url, + request, + event, + params + }); + } catch (err) { + responsePromise = Promise.reject(err); + } + // Get route's catch handler, if it exists + const catchHandler = route && route.catchHandler; + if (responsePromise instanceof Promise && (this._catchHandler || catchHandler)) { + responsePromise = responsePromise.catch(async err => { + // If there's a route catch handler, process that first + if (catchHandler) { + { + // Still include URL here as it will be async from the console group + // and may not make sense without the URL + logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL(url)}. Falling back to route's Catch Handler.`); + logger.error(`Error thrown by:`, route); + logger.error(err); + logger.groupEnd(); + } + try { + return await catchHandler.handle({ + url, + request, + event, + params + }); + } catch (catchErr) { + if (catchErr instanceof Error) { + err = catchErr; + } + } + } + if (this._catchHandler) { + { + // Still include URL here as it will be async from the console group + // and may not make sense without the URL + logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL(url)}. Falling back to global Catch Handler.`); + logger.error(`Error thrown by:`, route); + logger.error(err); + logger.groupEnd(); + } + return this._catchHandler.handle({ + url, + request, + event + }); + } + throw err; + }); + } + return responsePromise; + } + /** + * Checks a request and URL (and optionally an event) against the list of + * registered routes, and if there's a match, returns the corresponding + * route along with any params generated by the match. + * + * @param {Object} options + * @param {URL} options.url + * @param {boolean} options.sameOrigin The result of comparing `url.origin` + * against the current origin. + * @param {Request} options.request The request to match. + * @param {Event} options.event The corresponding event. + * @return {Object} An object with `route` and `params` properties. + * They are populated if a matching route was found or `undefined` + * otherwise. + */ + findMatchingRoute({ + url, + sameOrigin, + request, + event + }) { + const routes = this._routes.get(request.method) || []; + for (const route of routes) { + let params; + // route.match returns type any, not possible to change right now. + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const matchResult = route.match({ + url, + sameOrigin, + request, + event + }); + if (matchResult) { + { + // Warn developers that using an async matchCallback is almost always + // not the right thing to do. + if (matchResult instanceof Promise) { + logger.warn(`While routing ${getFriendlyURL(url)}, an async ` + `matchCallback function was used. Please convert the ` + `following route to use a synchronous matchCallback function:`, route); + } + } + // See https://github.com/GoogleChrome/workbox/issues/2079 + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + params = matchResult; + if (Array.isArray(params) && params.length === 0) { + // Instead of passing an empty array in as params, use undefined. + params = undefined; + } else if (matchResult.constructor === Object && + // eslint-disable-line + Object.keys(matchResult).length === 0) { + // Instead of passing an empty object in as params, use undefined. + params = undefined; + } else if (typeof matchResult === 'boolean') { + // For the boolean value true (rather than just something truth-y), + // don't set params. + // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353 + params = undefined; + } + // Return early if have a match. + return { + route, + params + }; + } + } + // If no match was found above, return and empty object. + return {}; + } + /** + * Define a default `handler` that's called when no routes explicitly + * match the incoming request. + * + * Each HTTP method ('GET', 'POST', etc.) gets its own default handler. + * + * Without a default handler, unmatched requests will go against the + * network as if there were no service worker present. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {string} [method='GET'] The HTTP method to associate with this + * default handler. Each method has its own default. + */ + setDefaultHandler(handler, method = defaultMethod) { + this._defaultHandlerMap.set(method, normalizeHandler(handler)); + } + /** + * If a Route throws an error while handling a request, this `handler` + * will be called and given a chance to provide a response. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + */ + setCatchHandler(handler) { + this._catchHandler = normalizeHandler(handler); + } + /** + * Registers a route with the router. + * + * @param {workbox-routing.Route} route The route to register. + */ + registerRoute(route) { + { + finalAssertExports.isType(route, 'object', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.hasMethod(route, 'match', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.isType(route.handler, 'object', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.hasMethod(route.handler, 'handle', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route.handler' + }); + finalAssertExports.isType(route.method, 'string', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route.method' + }); + } + if (!this._routes.has(route.method)) { + this._routes.set(route.method, []); + } + // Give precedence to all of the earlier routes by adding this additional + // route to the end of the array. + this._routes.get(route.method).push(route); + } + /** + * Unregisters a route with the router. + * + * @param {workbox-routing.Route} route The route to unregister. + */ + unregisterRoute(route) { + if (!this._routes.has(route.method)) { + throw new WorkboxError('unregister-route-but-not-found-with-method', { + method: route.method + }); + } + const routeIndex = this._routes.get(route.method).indexOf(route); + if (routeIndex > -1) { + this._routes.get(route.method).splice(routeIndex, 1); + } else { + throw new WorkboxError('unregister-route-route-not-registered'); + } + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + let defaultRouter; + /** + * Creates a new, singleton Router instance if one does not exist. If one + * does already exist, that instance is returned. + * + * @private + * @return {Router} + */ + const getOrCreateDefaultRouter = () => { + if (!defaultRouter) { + defaultRouter = new Router(); + // The helpers that use the default Router assume these listeners exist. + defaultRouter.addFetchListener(); + defaultRouter.addCacheListener(); + } + return defaultRouter; + }; + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Easily register a RegExp, string, or function with a caching + * strategy to a singleton Router instance. + * + * This method will generate a Route for you if needed and + * call {@link workbox-routing.Router#registerRoute}. + * + * @param {RegExp|string|workbox-routing.Route~matchCallback|workbox-routing.Route} capture + * If the capture param is a `Route`, all other arguments will be ignored. + * @param {workbox-routing~handlerCallback} [handler] A callback + * function that returns a Promise resulting in a Response. This parameter + * is required if `capture` is not a `Route` object. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + * @return {workbox-routing.Route} The generated `Route`. + * + * @memberof workbox-routing + */ + function registerRoute(capture, handler, method) { + let route; + if (typeof capture === 'string') { + const captureUrl = new URL(capture, location.href); + { + if (!(capture.startsWith('/') || capture.startsWith('http'))) { + throw new WorkboxError('invalid-string', { + moduleName: 'workbox-routing', + funcName: 'registerRoute', + paramName: 'capture' + }); + } + // We want to check if Express-style wildcards are in the pathname only. + // TODO: Remove this log message in v4. + const valueToCheck = capture.startsWith('http') ? captureUrl.pathname : capture; + // See https://github.com/pillarjs/path-to-regexp#parameters + const wildcards = '[*:?+]'; + if (new RegExp(`${wildcards}`).exec(valueToCheck)) { + logger.debug(`The '$capture' parameter contains an Express-style wildcard ` + `character (${wildcards}). Strings are now always interpreted as ` + `exact matches; use a RegExp for partial or wildcard matches.`); + } + } + const matchCallback = ({ + url + }) => { + { + if (url.pathname === captureUrl.pathname && url.origin !== captureUrl.origin) { + logger.debug(`${capture} only partially matches the cross-origin URL ` + `${url.toString()}. This route will only handle cross-origin requests ` + `if they match the entire URL.`); + } + } + return url.href === captureUrl.href; + }; + // If `capture` is a string then `handler` and `method` must be present. + route = new Route(matchCallback, handler, method); + } else if (capture instanceof RegExp) { + // If `capture` is a `RegExp` then `handler` and `method` must be present. + route = new RegExpRoute(capture, handler, method); + } else if (typeof capture === 'function') { + // If `capture` is a function then `handler` and `method` must be present. + route = new Route(capture, handler, method); + } else if (capture instanceof Route) { + route = capture; + } else { + throw new WorkboxError('unsupported-route-type', { + moduleName: 'workbox-routing', + funcName: 'registerRoute', + paramName: 'capture' + }); + } + const defaultRouter = getOrCreateDefaultRouter(); + defaultRouter.registerRoute(route); + return route; + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const _cacheNameDetails = { + googleAnalytics: 'googleAnalytics', + precache: 'precache-v2', + prefix: 'workbox', + runtime: 'runtime', + suffix: typeof registration !== 'undefined' ? registration.scope : '' + }; + const _createCacheName = cacheName => { + return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix].filter(value => value && value.length > 0).join('-'); + }; + const eachCacheNameDetail = fn => { + for (const key of Object.keys(_cacheNameDetails)) { + fn(key); + } + }; + const cacheNames = { + updateDetails: details => { + eachCacheNameDetail(key => { + if (typeof details[key] === 'string') { + _cacheNameDetails[key] = details[key]; + } + }); + }, + getGoogleAnalyticsName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics); + }, + getPrecacheName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.precache); + }, + getPrefix: () => { + return _cacheNameDetails.prefix; + }, + getRuntimeName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.runtime); + }, + getSuffix: () => { + return _cacheNameDetails.suffix; + } + }; + + /* + Copyright 2020 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A utility method that makes it easier to use `event.waitUntil` with + * async functions and return the result. + * + * @param {ExtendableEvent} event + * @param {Function} asyncFn + * @return {Function} + * @private + */ + function waitUntil(event, asyncFn) { + const returnPromise = asyncFn(); + event.waitUntil(returnPromise); + return returnPromise; + } + + // @ts-ignore + try { + self['workbox:precaching:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + // Name of the search parameter used to store revision info. + const REVISION_SEARCH_PARAM = '__WB_REVISION__'; + /** + * Converts a manifest entry into a versioned URL suitable for precaching. + * + * @param {Object|string} entry + * @return {string} A URL with versioning info. + * + * @private + * @memberof workbox-precaching + */ + function createCacheKey(entry) { + if (!entry) { + throw new WorkboxError('add-to-cache-list-unexpected-type', { + entry + }); + } + // If a precache manifest entry is a string, it's assumed to be a versioned + // URL, like '/app.abcd1234.js'. Return as-is. + if (typeof entry === 'string') { + const urlObject = new URL(entry, location.href); + return { + cacheKey: urlObject.href, + url: urlObject.href + }; + } + const { + revision, + url + } = entry; + if (!url) { + throw new WorkboxError('add-to-cache-list-unexpected-type', { + entry + }); + } + // If there's just a URL and no revision, then it's also assumed to be a + // versioned URL. + if (!revision) { + const urlObject = new URL(url, location.href); + return { + cacheKey: urlObject.href, + url: urlObject.href + }; + } + // Otherwise, construct a properly versioned URL using the custom Workbox + // search parameter along with the revision info. + const cacheKeyURL = new URL(url, location.href); + const originalURL = new URL(url, location.href); + cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision); + return { + cacheKey: cacheKeyURL.href, + url: originalURL.href + }; + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A plugin, designed to be used with PrecacheController, to determine the + * of assets that were updated (or not updated) during the install event. + * + * @private + */ + class PrecacheInstallReportPlugin { + constructor() { + this.updatedURLs = []; + this.notUpdatedURLs = []; + this.handlerWillStart = async ({ + request, + state + }) => { + // TODO: `state` should never be undefined... + if (state) { + state.originalRequest = request; + } + }; + this.cachedResponseWillBeUsed = async ({ + event, + state, + cachedResponse + }) => { + if (event.type === 'install') { + if (state && state.originalRequest && state.originalRequest instanceof Request) { + // TODO: `state` should never be undefined... + const url = state.originalRequest.url; + if (cachedResponse) { + this.notUpdatedURLs.push(url); + } else { + this.updatedURLs.push(url); + } + } + } + return cachedResponse; + }; + } + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A plugin, designed to be used with PrecacheController, to translate URLs into + * the corresponding cache key, based on the current revision info. + * + * @private + */ + class PrecacheCacheKeyPlugin { + constructor({ + precacheController + }) { + this.cacheKeyWillBeUsed = async ({ + request, + params + }) => { + // Params is type any, can't change right now. + /* eslint-disable */ + const cacheKey = (params === null || params === void 0 ? void 0 : params.cacheKey) || this._precacheController.getCacheKeyForURL(request.url); + /* eslint-enable */ + return cacheKey ? new Request(cacheKey, { + headers: request.headers + }) : request; + }; + this._precacheController = precacheController; + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * @param {string} groupTitle + * @param {Array} deletedURLs + * + * @private + */ + const logGroup = (groupTitle, deletedURLs) => { + logger.groupCollapsed(groupTitle); + for (const url of deletedURLs) { + logger.log(url); + } + logger.groupEnd(); + }; + /** + * @param {Array} deletedURLs + * + * @private + * @memberof workbox-precaching + */ + function printCleanupDetails(deletedURLs) { + const deletionCount = deletedURLs.length; + if (deletionCount > 0) { + logger.groupCollapsed(`During precaching cleanup, ` + `${deletionCount} cached ` + `request${deletionCount === 1 ? ' was' : 's were'} deleted.`); + logGroup('Deleted Cache Requests', deletedURLs); + logger.groupEnd(); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * @param {string} groupTitle + * @param {Array} urls + * + * @private + */ + function _nestedGroup(groupTitle, urls) { + if (urls.length === 0) { + return; + } + logger.groupCollapsed(groupTitle); + for (const url of urls) { + logger.log(url); + } + logger.groupEnd(); + } + /** + * @param {Array} urlsToPrecache + * @param {Array} urlsAlreadyPrecached + * + * @private + * @memberof workbox-precaching + */ + function printInstallDetails(urlsToPrecache, urlsAlreadyPrecached) { + const precachedCount = urlsToPrecache.length; + const alreadyPrecachedCount = urlsAlreadyPrecached.length; + if (precachedCount || alreadyPrecachedCount) { + let message = `Precaching ${precachedCount} file${precachedCount === 1 ? '' : 's'}.`; + if (alreadyPrecachedCount > 0) { + message += ` ${alreadyPrecachedCount} ` + `file${alreadyPrecachedCount === 1 ? ' is' : 's are'} already cached.`; + } + logger.groupCollapsed(message); + _nestedGroup(`View newly precached URLs.`, urlsToPrecache); + _nestedGroup(`View previously precached URLs.`, urlsAlreadyPrecached); + logger.groupEnd(); + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + let supportStatus; + /** + * A utility function that determines whether the current browser supports + * constructing a new `Response` from a `response.body` stream. + * + * @return {boolean} `true`, if the current browser can successfully + * construct a `Response` from a `response.body` stream, `false` otherwise. + * + * @private + */ + function canConstructResponseFromBodyStream() { + if (supportStatus === undefined) { + const testResponse = new Response(''); + if ('body' in testResponse) { + try { + new Response(testResponse.body); + supportStatus = true; + } catch (error) { + supportStatus = false; + } + } + supportStatus = false; + } + return supportStatus; + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Allows developers to copy a response and modify its `headers`, `status`, + * or `statusText` values (the values settable via a + * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax} + * object in the constructor). + * To modify these values, pass a function as the second argument. That + * function will be invoked with a single object with the response properties + * `{headers, status, statusText}`. The return value of this function will + * be used as the `ResponseInit` for the new `Response`. To change the values + * either modify the passed parameter(s) and return it, or return a totally + * new object. + * + * This method is intentionally limited to same-origin responses, regardless of + * whether CORS was used or not. + * + * @param {Response} response + * @param {Function} modifier + * @memberof workbox-core + */ + async function copyResponse(response, modifier) { + let origin = null; + // If response.url isn't set, assume it's cross-origin and keep origin null. + if (response.url) { + const responseURL = new URL(response.url); + origin = responseURL.origin; + } + if (origin !== self.location.origin) { + throw new WorkboxError('cross-origin-copy-response', { + origin + }); + } + const clonedResponse = response.clone(); + // Create a fresh `ResponseInit` object by cloning the headers. + const responseInit = { + headers: new Headers(clonedResponse.headers), + status: clonedResponse.status, + statusText: clonedResponse.statusText + }; + // Apply any user modifications. + const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit; + // Create the new response from the body stream and `ResponseInit` + // modifications. Note: not all browsers support the Response.body stream, + // so fall back to reading the entire body into memory as a blob. + const body = canConstructResponseFromBodyStream() ? clonedResponse.body : await clonedResponse.blob(); + return new Response(body, modifiedResponseInit); + } + + /* + Copyright 2020 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + function stripParams(fullURL, ignoreParams) { + const strippedURL = new URL(fullURL); + for (const param of ignoreParams) { + strippedURL.searchParams.delete(param); + } + return strippedURL.href; + } + /** + * Matches an item in the cache, ignoring specific URL params. This is similar + * to the `ignoreSearch` option, but it allows you to ignore just specific + * params (while continuing to match on the others). + * + * @private + * @param {Cache} cache + * @param {Request} request + * @param {Object} matchOptions + * @param {Array} ignoreParams + * @return {Promise} + */ + async function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) { + const strippedRequestURL = stripParams(request.url, ignoreParams); + // If the request doesn't include any ignored params, match as normal. + if (request.url === strippedRequestURL) { + return cache.match(request, matchOptions); + } + // Otherwise, match by comparing keys + const keysOptions = Object.assign(Object.assign({}, matchOptions), { + ignoreSearch: true + }); + const cacheKeys = await cache.keys(request, keysOptions); + for (const cacheKey of cacheKeys) { + const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams); + if (strippedRequestURL === strippedCacheKeyURL) { + return cache.match(cacheKey, matchOptions); + } + } + return; + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The Deferred class composes Promises in a way that allows for them to be + * resolved or rejected from outside the constructor. In most cases promises + * should be used directly, but Deferreds can be necessary when the logic to + * resolve a promise must be separate. + * + * @private + */ + class Deferred { + /** + * Creates a promise and exposes its resolve and reject functions as methods. + */ + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + // Callbacks to be executed whenever there's a quota error. + // Can't change Function type right now. + // eslint-disable-next-line @typescript-eslint/ban-types + const quotaErrorCallbacks = new Set(); + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Runs all of the callback functions, one at a time sequentially, in the order + * in which they were registered. + * + * @memberof workbox-core + * @private + */ + async function executeQuotaErrorCallbacks() { + { + logger.log(`About to run ${quotaErrorCallbacks.size} ` + `callbacks to clean up caches.`); + } + for (const callback of quotaErrorCallbacks) { + await callback(); + { + logger.log(callback, 'is complete.'); + } + } + { + logger.log('Finished running callbacks.'); + } + } + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Returns a promise that resolves and the passed number of milliseconds. + * This utility is an async/await-friendly version of `setTimeout`. + * + * @param {number} ms + * @return {Promise} + * @private + */ + function timeout(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + // @ts-ignore + try { + self['workbox:strategies:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + function toRequest(input) { + return typeof input === 'string' ? new Request(input) : input; + } + /** + * A class created every time a Strategy instance instance calls + * {@link workbox-strategies.Strategy~handle} or + * {@link workbox-strategies.Strategy~handleAll} that wraps all fetch and + * cache actions around plugin callbacks and keeps track of when the strategy + * is "done" (i.e. all added `event.waitUntil()` promises have resolved). + * + * @memberof workbox-strategies + */ + class StrategyHandler { + /** + * Creates a new instance associated with the passed strategy and event + * that's handling the request. + * + * The constructor also initializes the state that will be passed to each of + * the plugins handling this request. + * + * @param {workbox-strategies.Strategy} strategy + * @param {Object} options + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] The return value from the + * {@link workbox-routing~matchCallback} (if applicable). + */ + constructor(strategy, options) { + this._cacheKeys = {}; + /** + * The request the strategy is performing (passed to the strategy's + * `handle()` or `handleAll()` method). + * @name request + * @instance + * @type {Request} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * The event associated with this request. + * @name event + * @instance + * @type {ExtendableEvent} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * A `URL` instance of `request.url` (if passed to the strategy's + * `handle()` or `handleAll()` method). + * Note: the `url` param will be present if the strategy was invoked + * from a workbox `Route` object. + * @name url + * @instance + * @type {URL|undefined} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * A `param` value (if passed to the strategy's + * `handle()` or `handleAll()` method). + * Note: the `param` param will be present if the strategy was invoked + * from a workbox `Route` object and the + * {@link workbox-routing~matchCallback} returned + * a truthy value (it will be that value). + * @name params + * @instance + * @type {*|undefined} + * @memberof workbox-strategies.StrategyHandler + */ + { + finalAssertExports.isInstance(options.event, ExtendableEvent, { + moduleName: 'workbox-strategies', + className: 'StrategyHandler', + funcName: 'constructor', + paramName: 'options.event' + }); + } + Object.assign(this, options); + this.event = options.event; + this._strategy = strategy; + this._handlerDeferred = new Deferred(); + this._extendLifetimePromises = []; + // Copy the plugins list (since it's mutable on the strategy), + // so any mutations don't affect this handler instance. + this._plugins = [...strategy.plugins]; + this._pluginStateMap = new Map(); + for (const plugin of this._plugins) { + this._pluginStateMap.set(plugin, {}); + } + this.event.waitUntil(this._handlerDeferred.promise); + } + /** + * Fetches a given request (and invokes any applicable plugin callback + * methods) using the `fetchOptions` (for non-navigation requests) and + * `plugins` defined on the `Strategy` object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - `requestWillFetch()` + * - `fetchDidSucceed()` + * - `fetchDidFail()` + * + * @param {Request|string} input The URL or request to fetch. + * @return {Promise} + */ + async fetch(input) { + const { + event + } = this; + let request = toRequest(input); + if (request.mode === 'navigate' && event instanceof FetchEvent && event.preloadResponse) { + const possiblePreloadResponse = await event.preloadResponse; + if (possiblePreloadResponse) { + { + logger.log(`Using a preloaded navigation response for ` + `'${getFriendlyURL(request.url)}'`); + } + return possiblePreloadResponse; + } + } + // If there is a fetchDidFail plugin, we need to save a clone of the + // original request before it's either modified by a requestWillFetch + // plugin or before the original request's body is consumed via fetch(). + const originalRequest = this.hasCallback('fetchDidFail') ? request.clone() : null; + try { + for (const cb of this.iterateCallbacks('requestWillFetch')) { + request = await cb({ + request: request.clone(), + event + }); + } + } catch (err) { + if (err instanceof Error) { + throw new WorkboxError('plugin-error-request-will-fetch', { + thrownErrorMessage: err.message + }); + } + } + // The request can be altered by plugins with `requestWillFetch` making + // the original request (most likely from a `fetch` event) different + // from the Request we make. Pass both to `fetchDidFail` to aid debugging. + const pluginFilteredRequest = request.clone(); + try { + let fetchResponse; + // See https://github.com/GoogleChrome/workbox/issues/1796 + fetchResponse = await fetch(request, request.mode === 'navigate' ? undefined : this._strategy.fetchOptions); + if ("development" !== 'production') { + logger.debug(`Network request for ` + `'${getFriendlyURL(request.url)}' returned a response with ` + `status '${fetchResponse.status}'.`); + } + for (const callback of this.iterateCallbacks('fetchDidSucceed')) { + fetchResponse = await callback({ + event, + request: pluginFilteredRequest, + response: fetchResponse + }); + } + return fetchResponse; + } catch (error) { + { + logger.log(`Network request for ` + `'${getFriendlyURL(request.url)}' threw an error.`, error); + } + // `originalRequest` will only exist if a `fetchDidFail` callback + // is being used (see above). + if (originalRequest) { + await this.runCallbacks('fetchDidFail', { + error: error, + event, + originalRequest: originalRequest.clone(), + request: pluginFilteredRequest.clone() + }); + } + throw error; + } + } + /** + * Calls `this.fetch()` and (in the background) runs `this.cachePut()` on + * the response generated by `this.fetch()`. + * + * The call to `this.cachePut()` automatically invokes `this.waitUntil()`, + * so you do not have to manually call `waitUntil()` on the event. + * + * @param {Request|string} input The request or URL to fetch and cache. + * @return {Promise} + */ + async fetchAndCachePut(input) { + const response = await this.fetch(input); + const responseClone = response.clone(); + void this.waitUntil(this.cachePut(input, responseClone)); + return response; + } + /** + * Matches a request from the cache (and invokes any applicable plugin + * callback methods) using the `cacheName`, `matchOptions`, and `plugins` + * defined on the strategy object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - cacheKeyWillBeUsed() + * - cachedResponseWillBeUsed() + * + * @param {Request|string} key The Request or URL to use as the cache key. + * @return {Promise} A matching response, if found. + */ + async cacheMatch(key) { + const request = toRequest(key); + let cachedResponse; + const { + cacheName, + matchOptions + } = this._strategy; + const effectiveRequest = await this.getCacheKey(request, 'read'); + const multiMatchOptions = Object.assign(Object.assign({}, matchOptions), { + cacheName + }); + cachedResponse = await caches.match(effectiveRequest, multiMatchOptions); + { + if (cachedResponse) { + logger.debug(`Found a cached response in '${cacheName}'.`); + } else { + logger.debug(`No cached response found in '${cacheName}'.`); + } + } + for (const callback of this.iterateCallbacks('cachedResponseWillBeUsed')) { + cachedResponse = (await callback({ + cacheName, + matchOptions, + cachedResponse, + request: effectiveRequest, + event: this.event + })) || undefined; + } + return cachedResponse; + } + /** + * Puts a request/response pair in the cache (and invokes any applicable + * plugin callback methods) using the `cacheName` and `plugins` defined on + * the strategy object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - cacheKeyWillBeUsed() + * - cacheWillUpdate() + * - cacheDidUpdate() + * + * @param {Request|string} key The request or URL to use as the cache key. + * @param {Response} response The response to cache. + * @return {Promise} `false` if a cacheWillUpdate caused the response + * not be cached, and `true` otherwise. + */ + async cachePut(key, response) { + const request = toRequest(key); + // Run in the next task to avoid blocking other cache reads. + // https://github.com/w3c/ServiceWorker/issues/1397 + await timeout(0); + const effectiveRequest = await this.getCacheKey(request, 'write'); + { + if (effectiveRequest.method && effectiveRequest.method !== 'GET') { + throw new WorkboxError('attempt-to-cache-non-get-request', { + url: getFriendlyURL(effectiveRequest.url), + method: effectiveRequest.method + }); + } + // See https://github.com/GoogleChrome/workbox/issues/2818 + const vary = response.headers.get('Vary'); + if (vary) { + logger.debug(`The response for ${getFriendlyURL(effectiveRequest.url)} ` + `has a 'Vary: ${vary}' header. ` + `Consider setting the {ignoreVary: true} option on your strategy ` + `to ensure cache matching and deletion works as expected.`); + } + } + if (!response) { + { + logger.error(`Cannot cache non-existent response for ` + `'${getFriendlyURL(effectiveRequest.url)}'.`); + } + throw new WorkboxError('cache-put-with-no-response', { + url: getFriendlyURL(effectiveRequest.url) + }); + } + const responseToCache = await this._ensureResponseSafeToCache(response); + if (!responseToCache) { + { + logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' ` + `will not be cached.`, responseToCache); + } + return false; + } + const { + cacheName, + matchOptions + } = this._strategy; + const cache = await self.caches.open(cacheName); + const hasCacheUpdateCallback = this.hasCallback('cacheDidUpdate'); + const oldResponse = hasCacheUpdateCallback ? await cacheMatchIgnoreParams( + // TODO(philipwalton): the `__WB_REVISION__` param is a precaching + // feature. Consider into ways to only add this behavior if using + // precaching. + cache, effectiveRequest.clone(), ['__WB_REVISION__'], matchOptions) : null; + { + logger.debug(`Updating the '${cacheName}' cache with a new Response ` + `for ${getFriendlyURL(effectiveRequest.url)}.`); + } + try { + await cache.put(effectiveRequest, hasCacheUpdateCallback ? responseToCache.clone() : responseToCache); + } catch (error) { + if (error instanceof Error) { + // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError + if (error.name === 'QuotaExceededError') { + await executeQuotaErrorCallbacks(); + } + throw error; + } + } + for (const callback of this.iterateCallbacks('cacheDidUpdate')) { + await callback({ + cacheName, + oldResponse, + newResponse: responseToCache.clone(), + request: effectiveRequest, + event: this.event + }); + } + return true; + } + /** + * Checks the list of plugins for the `cacheKeyWillBeUsed` callback, and + * executes any of those callbacks found in sequence. The final `Request` + * object returned by the last plugin is treated as the cache key for cache + * reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have + * been registered, the passed request is returned unmodified + * + * @param {Request} request + * @param {string} mode + * @return {Promise} + */ + async getCacheKey(request, mode) { + const key = `${request.url} | ${mode}`; + if (!this._cacheKeys[key]) { + let effectiveRequest = request; + for (const callback of this.iterateCallbacks('cacheKeyWillBeUsed')) { + effectiveRequest = toRequest(await callback({ + mode, + request: effectiveRequest, + event: this.event, + // params has a type any can't change right now. + params: this.params // eslint-disable-line + })); + } + this._cacheKeys[key] = effectiveRequest; + } + return this._cacheKeys[key]; + } + /** + * Returns true if the strategy has at least one plugin with the given + * callback. + * + * @param {string} name The name of the callback to check for. + * @return {boolean} + */ + hasCallback(name) { + for (const plugin of this._strategy.plugins) { + if (name in plugin) { + return true; + } + } + return false; + } + /** + * Runs all plugin callbacks matching the given name, in order, passing the + * given param object (merged ith the current plugin state) as the only + * argument. + * + * Note: since this method runs all plugins, it's not suitable for cases + * where the return value of a callback needs to be applied prior to calling + * the next callback. See + * {@link workbox-strategies.StrategyHandler#iterateCallbacks} + * below for how to handle that case. + * + * @param {string} name The name of the callback to run within each plugin. + * @param {Object} param The object to pass as the first (and only) param + * when executing each callback. This object will be merged with the + * current plugin state prior to callback execution. + */ + async runCallbacks(name, param) { + for (const callback of this.iterateCallbacks(name)) { + // TODO(philipwalton): not sure why `any` is needed. It seems like + // this should work with `as WorkboxPluginCallbackParam[C]`. + await callback(param); + } + } + /** + * Accepts a callback and returns an iterable of matching plugin callbacks, + * where each callback is wrapped with the current handler state (i.e. when + * you call each callback, whatever object parameter you pass it will + * be merged with the plugin's current state). + * + * @param {string} name The name fo the callback to run + * @return {Array} + */ + *iterateCallbacks(name) { + for (const plugin of this._strategy.plugins) { + if (typeof plugin[name] === 'function') { + const state = this._pluginStateMap.get(plugin); + const statefulCallback = param => { + const statefulParam = Object.assign(Object.assign({}, param), { + state + }); + // TODO(philipwalton): not sure why `any` is needed. It seems like + // this should work with `as WorkboxPluginCallbackParam[C]`. + return plugin[name](statefulParam); + }; + yield statefulCallback; + } + } + } + /** + * Adds a promise to the + * [extend lifetime promises]{@link https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises} + * of the event event associated with the request being handled (usually a + * `FetchEvent`). + * + * Note: you can await + * {@link workbox-strategies.StrategyHandler~doneWaiting} + * to know when all added promises have settled. + * + * @param {Promise} promise A promise to add to the extend lifetime promises + * of the event that triggered the request. + */ + waitUntil(promise) { + this._extendLifetimePromises.push(promise); + return promise; + } + /** + * Returns a promise that resolves once all promises passed to + * {@link workbox-strategies.StrategyHandler~waitUntil} + * have settled. + * + * Note: any work done after `doneWaiting()` settles should be manually + * passed to an event's `waitUntil()` method (not this handler's + * `waitUntil()` method), otherwise the service worker thread my be killed + * prior to your work completing. + */ + async doneWaiting() { + let promise; + while (promise = this._extendLifetimePromises.shift()) { + await promise; + } + } + /** + * Stops running the strategy and immediately resolves any pending + * `waitUntil()` promises. + */ + destroy() { + this._handlerDeferred.resolve(null); + } + /** + * This method will call cacheWillUpdate on the available plugins (or use + * status === 200) to determine if the Response is safe and valid to cache. + * + * @param {Request} options.request + * @param {Response} options.response + * @return {Promise} + * + * @private + */ + async _ensureResponseSafeToCache(response) { + let responseToCache = response; + let pluginsUsed = false; + for (const callback of this.iterateCallbacks('cacheWillUpdate')) { + responseToCache = (await callback({ + request: this.request, + response: responseToCache, + event: this.event + })) || undefined; + pluginsUsed = true; + if (!responseToCache) { + break; + } + } + if (!pluginsUsed) { + if (responseToCache && responseToCache.status !== 200) { + responseToCache = undefined; + } + { + if (responseToCache) { + if (responseToCache.status !== 200) { + if (responseToCache.status === 0) { + logger.warn(`The response for '${this.request.url}' ` + `is an opaque response. The caching strategy that you're ` + `using will not cache opaque responses by default.`); + } else { + logger.debug(`The response for '${this.request.url}' ` + `returned a status code of '${response.status}' and won't ` + `be cached as a result.`); + } + } + } + } + } + return responseToCache; + } + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * An abstract base class that all other strategy classes must extend from: + * + * @memberof workbox-strategies + */ + class Strategy { + /** + * Creates a new instance of the strategy and sets all documented option + * properties as public instance properties. + * + * Note: if a custom strategy class extends the base Strategy class and does + * not need more than these properties, it does not need to define its own + * constructor. + * + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) + * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) + * `fetch()` requests made by this strategy. + * @param {Object} [options.matchOptions] The + * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + */ + constructor(options = {}) { + /** + * Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * + * @type {string} + */ + this.cacheName = cacheNames.getRuntimeName(options.cacheName); + /** + * The list + * [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * used by this strategy. + * + * @type {Array} + */ + this.plugins = options.plugins || []; + /** + * Values passed along to the + * [`init`]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters} + * of all fetch() requests made by this strategy. + * + * @type {Object} + */ + this.fetchOptions = options.fetchOptions; + /** + * The + * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + * + * @type {Object} + */ + this.matchOptions = options.matchOptions; + } + /** + * Perform a request strategy and returns a `Promise` that will resolve with + * a `Response`, invoking all relevant plugin callbacks. + * + * When a strategy instance is registered with a Workbox + * {@link workbox-routing.Route}, this method is automatically + * called when the route matches. + * + * Alternatively, this method can be used in a standalone `FetchEvent` + * listener by passing it to `event.respondWith()`. + * + * @param {FetchEvent|Object} options A `FetchEvent` or an object with the + * properties listed below. + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] + */ + handle(options) { + const [responseDone] = this.handleAll(options); + return responseDone; + } + /** + * Similar to {@link workbox-strategies.Strategy~handle}, but + * instead of just returning a `Promise` that resolves to a `Response` it + * it will return an tuple of `[response, done]` promises, where the former + * (`response`) is equivalent to what `handle()` returns, and the latter is a + * Promise that will resolve once any promises that were added to + * `event.waitUntil()` as part of performing the strategy have completed. + * + * You can await the `done` promise to ensure any extra work performed by + * the strategy (usually caching responses) completes successfully. + * + * @param {FetchEvent|Object} options A `FetchEvent` or an object with the + * properties listed below. + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] + * @return {Array} A tuple of [response, done] + * promises that can be used to determine when the response resolves as + * well as when the handler has completed all its work. + */ + handleAll(options) { + // Allow for flexible options to be passed. + if (options instanceof FetchEvent) { + options = { + event: options, + request: options.request + }; + } + const event = options.event; + const request = typeof options.request === 'string' ? new Request(options.request) : options.request; + const params = 'params' in options ? options.params : undefined; + const handler = new StrategyHandler(this, { + event, + request, + params + }); + const responseDone = this._getResponse(handler, request, event); + const handlerDone = this._awaitComplete(responseDone, handler, request, event); + // Return an array of promises, suitable for use with Promise.all(). + return [responseDone, handlerDone]; + } + async _getResponse(handler, request, event) { + await handler.runCallbacks('handlerWillStart', { + event, + request + }); + let response = undefined; + try { + response = await this._handle(request, handler); + // The "official" Strategy subclasses all throw this error automatically, + // but in case a third-party Strategy doesn't, ensure that we have a + // consistent failure when there's no response or an error response. + if (!response || response.type === 'error') { + throw new WorkboxError('no-response', { + url: request.url + }); + } + } catch (error) { + if (error instanceof Error) { + for (const callback of handler.iterateCallbacks('handlerDidError')) { + response = await callback({ + error, + event, + request + }); + if (response) { + break; + } + } + } + if (!response) { + throw error; + } else { + logger.log(`While responding to '${getFriendlyURL(request.url)}', ` + `an ${error instanceof Error ? error.toString() : ''} error occurred. Using a fallback response provided by ` + `a handlerDidError plugin.`); + } + } + for (const callback of handler.iterateCallbacks('handlerWillRespond')) { + response = await callback({ + event, + request, + response + }); + } + return response; + } + async _awaitComplete(responseDone, handler, request, event) { + let response; + let error; + try { + response = await responseDone; + } catch (error) { + // Ignore errors, as response errors should be caught via the `response` + // promise above. The `done` promise will only throw for errors in + // promises passed to `handler.waitUntil()`. + } + try { + await handler.runCallbacks('handlerDidRespond', { + event, + request, + response + }); + await handler.doneWaiting(); + } catch (waitUntilError) { + if (waitUntilError instanceof Error) { + error = waitUntilError; + } + } + await handler.runCallbacks('handlerDidComplete', { + event, + request, + response, + error: error + }); + handler.destroy(); + if (error) { + throw error; + } + } + } + /** + * Classes extending the `Strategy` based class should implement this method, + * and leverage the {@link workbox-strategies.StrategyHandler} + * arg to perform all fetching and cache logic, which will ensure all relevant + * cache, cache options, fetch options and plugins are used (per the current + * strategy instance). + * + * @name _handle + * @instance + * @abstract + * @function + * @param {Request} request + * @param {workbox-strategies.StrategyHandler} handler + * @return {Promise} + * + * @memberof workbox-strategies.Strategy + */ + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A {@link workbox-strategies.Strategy} implementation + * specifically designed to work with + * {@link workbox-precaching.PrecacheController} + * to both cache and fetch precached assets. + * + * Note: an instance of this class is created automatically when creating a + * `PrecacheController`; it's generally not necessary to create this yourself. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-precaching + */ + class PrecacheStrategy extends Strategy { + /** + * + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] {@link https://developers.google.com/web/tools/workbox/guides/using-plugins|Plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init} + * of all fetch() requests made by this strategy. + * @param {Object} [options.matchOptions] The + * {@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions|CacheQueryOptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to + * get the response from the network if there's a precache miss. + */ + constructor(options = {}) { + options.cacheName = cacheNames.getPrecacheName(options.cacheName); + super(options); + this._fallbackToNetwork = options.fallbackToNetwork === false ? false : true; + // Redirected responses cannot be used to satisfy a navigation request, so + // any redirected response must be "copied" rather than cloned, so the new + // response doesn't contain the `redirected` flag. See: + // https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1 + this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin); + } + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request, handler) { + const response = await handler.cacheMatch(request); + if (response) { + return response; + } + // If this is an `install` event for an entry that isn't already cached, + // then populate the cache. + if (handler.event && handler.event.type === 'install') { + return await this._handleInstall(request, handler); + } + // Getting here means something went wrong. An entry that should have been + // precached wasn't found in the cache. + return await this._handleFetch(request, handler); + } + async _handleFetch(request, handler) { + let response; + const params = handler.params || {}; + // Fall back to the network if we're configured to do so. + if (this._fallbackToNetwork) { + { + logger.warn(`The precached response for ` + `${getFriendlyURL(request.url)} in ${this.cacheName} was not ` + `found. Falling back to the network.`); + } + const integrityInManifest = params.integrity; + const integrityInRequest = request.integrity; + const noIntegrityConflict = !integrityInRequest || integrityInRequest === integrityInManifest; + // Do not add integrity if the original request is no-cors + // See https://github.com/GoogleChrome/workbox/issues/3096 + response = await handler.fetch(new Request(request, { + integrity: request.mode !== 'no-cors' ? integrityInRequest || integrityInManifest : undefined + })); + // It's only "safe" to repair the cache if we're using SRI to guarantee + // that the response matches the precache manifest's expectations, + // and there's either a) no integrity property in the incoming request + // or b) there is an integrity, and it matches the precache manifest. + // See https://github.com/GoogleChrome/workbox/issues/2858 + // Also if the original request users no-cors we don't use integrity. + // See https://github.com/GoogleChrome/workbox/issues/3096 + if (integrityInManifest && noIntegrityConflict && request.mode !== 'no-cors') { + this._useDefaultCacheabilityPluginIfNeeded(); + const wasCached = await handler.cachePut(request, response.clone()); + { + if (wasCached) { + logger.log(`A response for ${getFriendlyURL(request.url)} ` + `was used to "repair" the precache.`); + } + } + } + } else { + // This shouldn't normally happen, but there are edge cases: + // https://github.com/GoogleChrome/workbox/issues/1441 + throw new WorkboxError('missing-precache-entry', { + cacheName: this.cacheName, + url: request.url + }); + } + { + const cacheKey = params.cacheKey || (await handler.getCacheKey(request, 'read')); + // Workbox is going to handle the route. + // print the routing details to the console. + logger.groupCollapsed(`Precaching is responding to: ` + getFriendlyURL(request.url)); + logger.log(`Serving the precached url: ${getFriendlyURL(cacheKey instanceof Request ? cacheKey.url : cacheKey)}`); + logger.groupCollapsed(`View request details here.`); + logger.log(request); + logger.groupEnd(); + logger.groupCollapsed(`View response details here.`); + logger.log(response); + logger.groupEnd(); + logger.groupEnd(); + } + return response; + } + async _handleInstall(request, handler) { + this._useDefaultCacheabilityPluginIfNeeded(); + const response = await handler.fetch(request); + // Make sure we defer cachePut() until after we know the response + // should be cached; see https://github.com/GoogleChrome/workbox/issues/2737 + const wasCached = await handler.cachePut(request, response.clone()); + if (!wasCached) { + // Throwing here will lead to the `install` handler failing, which + // we want to do if *any* of the responses aren't safe to cache. + throw new WorkboxError('bad-precaching-response', { + url: request.url, + status: response.status + }); + } + return response; + } + /** + * This method is complex, as there a number of things to account for: + * + * The `plugins` array can be set at construction, and/or it might be added to + * to at any time before the strategy is used. + * + * At the time the strategy is used (i.e. during an `install` event), there + * needs to be at least one plugin that implements `cacheWillUpdate` in the + * array, other than `copyRedirectedCacheableResponsesPlugin`. + * + * - If this method is called and there are no suitable `cacheWillUpdate` + * plugins, we need to add `defaultPrecacheCacheabilityPlugin`. + * + * - If this method is called and there is exactly one `cacheWillUpdate`, then + * we don't have to do anything (this might be a previously added + * `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin). + * + * - If this method is called and there is more than one `cacheWillUpdate`, + * then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so, + * we need to remove it. (This situation is unlikely, but it could happen if + * the strategy is used multiple times, the first without a `cacheWillUpdate`, + * and then later on after manually adding a custom `cacheWillUpdate`.) + * + * See https://github.com/GoogleChrome/workbox/issues/2737 for more context. + * + * @private + */ + _useDefaultCacheabilityPluginIfNeeded() { + let defaultPluginIndex = null; + let cacheWillUpdatePluginCount = 0; + for (const [index, plugin] of this.plugins.entries()) { + // Ignore the copy redirected plugin when determining what to do. + if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) { + continue; + } + // Save the default plugin's index, in case it needs to be removed. + if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) { + defaultPluginIndex = index; + } + if (plugin.cacheWillUpdate) { + cacheWillUpdatePluginCount++; + } + } + if (cacheWillUpdatePluginCount === 0) { + this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin); + } else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) { + // Only remove the default plugin; multiple custom plugins are allowed. + this.plugins.splice(defaultPluginIndex, 1); + } + // Nothing needs to be done if cacheWillUpdatePluginCount is 1 + } + } + PrecacheStrategy.defaultPrecacheCacheabilityPlugin = { + async cacheWillUpdate({ + response + }) { + if (!response || response.status >= 400) { + return null; + } + return response; + } + }; + PrecacheStrategy.copyRedirectedCacheableResponsesPlugin = { + async cacheWillUpdate({ + response + }) { + return response.redirected ? await copyResponse(response) : response; + } + }; + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Performs efficient precaching of assets. + * + * @memberof workbox-precaching + */ + class PrecacheController { + /** + * Create a new PrecacheController. + * + * @param {Object} [options] + * @param {string} [options.cacheName] The cache to use for precaching. + * @param {string} [options.plugins] Plugins to use when precaching as well + * as responding to fetch events for precached assets. + * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to + * get the response from the network if there's a precache miss. + */ + constructor({ + cacheName, + plugins = [], + fallbackToNetwork = true + } = {}) { + this._urlsToCacheKeys = new Map(); + this._urlsToCacheModes = new Map(); + this._cacheKeysToIntegrities = new Map(); + this._strategy = new PrecacheStrategy({ + cacheName: cacheNames.getPrecacheName(cacheName), + plugins: [...plugins, new PrecacheCacheKeyPlugin({ + precacheController: this + })], + fallbackToNetwork + }); + // Bind the install and activate methods to the instance. + this.install = this.install.bind(this); + this.activate = this.activate.bind(this); + } + /** + * @type {workbox-precaching.PrecacheStrategy} The strategy created by this controller and + * used to cache assets and respond to fetch events. + */ + get strategy() { + return this._strategy; + } + /** + * Adds items to the precache list, removing any duplicates and + * stores the files in the + * {@link workbox-core.cacheNames|"precache cache"} when the service + * worker installs. + * + * This method can be called multiple times. + * + * @param {Array} [entries=[]] Array of entries to precache. + */ + precache(entries) { + this.addToCacheList(entries); + if (!this._installAndActiveListenersAdded) { + self.addEventListener('install', this.install); + self.addEventListener('activate', this.activate); + this._installAndActiveListenersAdded = true; + } + } + /** + * This method will add items to the precache list, removing duplicates + * and ensuring the information is valid. + * + * @param {Array} entries + * Array of entries to precache. + */ + addToCacheList(entries) { + { + finalAssertExports.isArray(entries, { + moduleName: 'workbox-precaching', + className: 'PrecacheController', + funcName: 'addToCacheList', + paramName: 'entries' + }); + } + const urlsToWarnAbout = []; + for (const entry of entries) { + // See https://github.com/GoogleChrome/workbox/issues/2259 + if (typeof entry === 'string') { + urlsToWarnAbout.push(entry); + } else if (entry && entry.revision === undefined) { + urlsToWarnAbout.push(entry.url); + } + const { + cacheKey, + url + } = createCacheKey(entry); + const cacheMode = typeof entry !== 'string' && entry.revision ? 'reload' : 'default'; + if (this._urlsToCacheKeys.has(url) && this._urlsToCacheKeys.get(url) !== cacheKey) { + throw new WorkboxError('add-to-cache-list-conflicting-entries', { + firstEntry: this._urlsToCacheKeys.get(url), + secondEntry: cacheKey + }); + } + if (typeof entry !== 'string' && entry.integrity) { + if (this._cacheKeysToIntegrities.has(cacheKey) && this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) { + throw new WorkboxError('add-to-cache-list-conflicting-integrities', { + url + }); + } + this._cacheKeysToIntegrities.set(cacheKey, entry.integrity); + } + this._urlsToCacheKeys.set(url, cacheKey); + this._urlsToCacheModes.set(url, cacheMode); + if (urlsToWarnAbout.length > 0) { + const warningMessage = `Workbox is precaching URLs without revision ` + `info: ${urlsToWarnAbout.join(', ')}\nThis is generally NOT safe. ` + `Learn more at https://bit.ly/wb-precache`; + { + logger.warn(warningMessage); + } + } + } + } + /** + * Precaches new and updated assets. Call this method from the service worker + * install event. + * + * Note: this method calls `event.waitUntil()` for you, so you do not need + * to call it yourself in your event handlers. + * + * @param {ExtendableEvent} event + * @return {Promise} + */ + install(event) { + // waitUntil returns Promise + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return waitUntil(event, async () => { + const installReportPlugin = new PrecacheInstallReportPlugin(); + this.strategy.plugins.push(installReportPlugin); + // Cache entries one at a time. + // See https://github.com/GoogleChrome/workbox/issues/2528 + for (const [url, cacheKey] of this._urlsToCacheKeys) { + const integrity = this._cacheKeysToIntegrities.get(cacheKey); + const cacheMode = this._urlsToCacheModes.get(url); + const request = new Request(url, { + integrity, + cache: cacheMode, + credentials: 'same-origin' + }); + await Promise.all(this.strategy.handleAll({ + params: { + cacheKey + }, + request, + event + })); + } + const { + updatedURLs, + notUpdatedURLs + } = installReportPlugin; + { + printInstallDetails(updatedURLs, notUpdatedURLs); + } + return { + updatedURLs, + notUpdatedURLs + }; + }); + } + /** + * Deletes assets that are no longer present in the current precache manifest. + * Call this method from the service worker activate event. + * + * Note: this method calls `event.waitUntil()` for you, so you do not need + * to call it yourself in your event handlers. + * + * @param {ExtendableEvent} event + * @return {Promise} + */ + activate(event) { + // waitUntil returns Promise + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return waitUntil(event, async () => { + const cache = await self.caches.open(this.strategy.cacheName); + const currentlyCachedRequests = await cache.keys(); + const expectedCacheKeys = new Set(this._urlsToCacheKeys.values()); + const deletedURLs = []; + for (const request of currentlyCachedRequests) { + if (!expectedCacheKeys.has(request.url)) { + await cache.delete(request); + deletedURLs.push(request.url); + } + } + { + printCleanupDetails(deletedURLs); + } + return { + deletedURLs + }; + }); + } + /** + * Returns a mapping of a precached URL to the corresponding cache key, taking + * into account the revision information for the URL. + * + * @return {Map} A URL to cache key mapping. + */ + getURLsToCacheKeys() { + return this._urlsToCacheKeys; + } + /** + * Returns a list of all the URLs that have been precached by the current + * service worker. + * + * @return {Array} The precached URLs. + */ + getCachedURLs() { + return [...this._urlsToCacheKeys.keys()]; + } + /** + * Returns the cache key used for storing a given URL. If that URL is + * unversioned, like `/index.html', then the cache key will be the original + * URL with a search parameter appended to it. + * + * @param {string} url A URL whose cache key you want to look up. + * @return {string} The versioned URL that corresponds to a cache key + * for the original URL, or undefined if that URL isn't precached. + */ + getCacheKeyForURL(url) { + const urlObject = new URL(url, location.href); + return this._urlsToCacheKeys.get(urlObject.href); + } + /** + * @param {string} url A cache key whose SRI you want to look up. + * @return {string} The subresource integrity associated with the cache key, + * or undefined if it's not set. + */ + getIntegrityForCacheKey(cacheKey) { + return this._cacheKeysToIntegrities.get(cacheKey); + } + /** + * This acts as a drop-in replacement for + * [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match) + * with the following differences: + * + * - It knows what the name of the precache is, and only checks in that cache. + * - It allows you to pass in an "original" URL without versioning parameters, + * and it will automatically look up the correct cache key for the currently + * active revision of that URL. + * + * E.g., `matchPrecache('index.html')` will find the correct precached + * response for the currently active service worker, even if the actual cache + * key is `'/index.html?__WB_REVISION__=1234abcd'`. + * + * @param {string|Request} request The key (without revisioning parameters) + * to look up in the precache. + * @return {Promise} + */ + async matchPrecache(request) { + const url = request instanceof Request ? request.url : request; + const cacheKey = this.getCacheKeyForURL(url); + if (cacheKey) { + const cache = await self.caches.open(this.strategy.cacheName); + return cache.match(cacheKey); + } + return undefined; + } + /** + * Returns a function that looks up `url` in the precache (taking into + * account revision information), and returns the corresponding `Response`. + * + * @param {string} url The precached URL which will be used to lookup the + * `Response`. + * @return {workbox-routing~handlerCallback} + */ + createHandlerBoundToURL(url) { + const cacheKey = this.getCacheKeyForURL(url); + if (!cacheKey) { + throw new WorkboxError('non-precached-url', { + url + }); + } + return options => { + options.request = new Request(url); + options.params = Object.assign({ + cacheKey + }, options.params); + return this.strategy.handle(options); + }; + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + let precacheController; + /** + * @return {PrecacheController} + * @private + */ + const getOrCreatePrecacheController = () => { + if (!precacheController) { + precacheController = new PrecacheController(); + } + return precacheController; + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Removes any URL search parameters that should be ignored. + * + * @param {URL} urlObject The original URL. + * @param {Array} ignoreURLParametersMatching RegExps to test against + * each search parameter name. Matches mean that the search parameter should be + * ignored. + * @return {URL} The URL with any ignored search parameters removed. + * + * @private + * @memberof workbox-precaching + */ + function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) { + // Convert the iterable into an array at the start of the loop to make sure + // deletion doesn't mess up iteration. + for (const paramName of [...urlObject.searchParams.keys()]) { + if (ignoreURLParametersMatching.some(regExp => regExp.test(paramName))) { + urlObject.searchParams.delete(paramName); + } + } + return urlObject; + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Generator function that yields possible variations on the original URL to + * check, one at a time. + * + * @param {string} url + * @param {Object} options + * + * @private + * @memberof workbox-precaching + */ + function* generateURLVariations(url, { + ignoreURLParametersMatching = [/^utm_/, /^fbclid$/], + directoryIndex = 'index.html', + cleanURLs = true, + urlManipulation + } = {}) { + const urlObject = new URL(url, location.href); + urlObject.hash = ''; + yield urlObject.href; + const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching); + yield urlWithoutIgnoredParams.href; + if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) { + const directoryURL = new URL(urlWithoutIgnoredParams.href); + directoryURL.pathname += directoryIndex; + yield directoryURL.href; + } + if (cleanURLs) { + const cleanURL = new URL(urlWithoutIgnoredParams.href); + cleanURL.pathname += '.html'; + yield cleanURL.href; + } + if (urlManipulation) { + const additionalURLs = urlManipulation({ + url: urlObject + }); + for (const urlToAttempt of additionalURLs) { + yield urlToAttempt.href; + } + } + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A subclass of {@link workbox-routing.Route} that takes a + * {@link workbox-precaching.PrecacheController} + * instance and uses it to match incoming requests and handle fetching + * responses from the precache. + * + * @memberof workbox-precaching + * @extends workbox-routing.Route + */ + class PrecacheRoute extends Route { + /** + * @param {PrecacheController} precacheController A `PrecacheController` + * instance used to both match requests and respond to fetch events. + * @param {Object} [options] Options to control how requests are matched + * against the list of precached URLs. + * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will + * check cache entries for a URLs ending with '/' to see if there is a hit when + * appending the `directoryIndex` value. + * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An + * array of regex's to remove search params when looking for a cache match. + * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will + * check the cache for the URL with a `.html` added to the end of the end. + * @param {workbox-precaching~urlManipulation} [options.urlManipulation] + * This is a function that should take a URL and return an array of + * alternative URLs that should be checked for precache matches. + */ + constructor(precacheController, options) { + const match = ({ + request + }) => { + const urlsToCacheKeys = precacheController.getURLsToCacheKeys(); + for (const possibleURL of generateURLVariations(request.url, options)) { + const cacheKey = urlsToCacheKeys.get(possibleURL); + if (cacheKey) { + const integrity = precacheController.getIntegrityForCacheKey(cacheKey); + return { + cacheKey, + integrity + }; + } + } + { + logger.debug(`Precaching did not find a match for ` + getFriendlyURL(request.url)); + } + return; + }; + super(match, precacheController.strategy); + } + } + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Add a `fetch` listener to the service worker that will + * respond to + * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests} + * with precached assets. + * + * Requests for assets that aren't precached, the `FetchEvent` will not be + * responded to, allowing the event to fall through to other `fetch` event + * listeners. + * + * @param {Object} [options] See the {@link workbox-precaching.PrecacheRoute} + * options. + * + * @memberof workbox-precaching + */ + function addRoute(options) { + const precacheController = getOrCreatePrecacheController(); + const precacheRoute = new PrecacheRoute(precacheController, options); + registerRoute(precacheRoute); + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Adds items to the precache list, removing any duplicates and + * stores the files in the + * {@link workbox-core.cacheNames|"precache cache"} when the service + * worker installs. + * + * This method can be called multiple times. + * + * Please note: This method **will not** serve any of the cached files for you. + * It only precaches files. To respond to a network request you call + * {@link workbox-precaching.addRoute}. + * + * If you have a single array of files to precache, you can just call + * {@link workbox-precaching.precacheAndRoute}. + * + * @param {Array} [entries=[]] Array of entries to precache. + * + * @memberof workbox-precaching + */ + function precache(entries) { + const precacheController = getOrCreatePrecacheController(); + precacheController.precache(entries); + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * This method will add entries to the precache list and add a route to + * respond to fetch events. + * + * This is a convenience method that will call + * {@link workbox-precaching.precache} and + * {@link workbox-precaching.addRoute} in a single call. + * + * @param {Array} entries Array of entries to precache. + * @param {Object} [options] See the + * {@link workbox-precaching.PrecacheRoute} options. + * + * @memberof workbox-precaching + */ + function precacheAndRoute(entries, options) { + precache(entries); + addRoute(options); + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const SUBSTRING_TO_FIND = '-precache-'; + /** + * Cleans up incompatible precaches that were created by older versions of + * Workbox, by a service worker registered under the current scope. + * + * This is meant to be called as part of the `activate` event. + * + * This should be safe to use as long as you don't include `substringToFind` + * (defaulting to `-precache-`) in your non-precache cache names. + * + * @param {string} currentPrecacheName The cache name currently in use for + * precaching. This cache won't be deleted. + * @param {string} [substringToFind='-precache-'] Cache names which include this + * substring will be deleted (excluding `currentPrecacheName`). + * @return {Array} A list of all the cache names that were deleted. + * + * @private + * @memberof workbox-precaching + */ + const deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBSTRING_TO_FIND) => { + const cacheNames = await self.caches.keys(); + const cacheNamesToDelete = cacheNames.filter(cacheName => { + return cacheName.includes(substringToFind) && cacheName.includes(self.registration.scope) && cacheName !== currentPrecacheName; + }); + await Promise.all(cacheNamesToDelete.map(cacheName => self.caches.delete(cacheName))); + return cacheNamesToDelete; + }; + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Adds an `activate` event listener which will clean up incompatible + * precaches that were created by older versions of Workbox. + * + * @memberof workbox-precaching + */ + function cleanupOutdatedCaches() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('activate', event => { + const cacheName = cacheNames.getPrecacheName(); + event.waitUntil(deleteOutdatedCaches(cacheName).then(cachesDeleted => { + { + if (cachesDeleted.length > 0) { + logger.log(`The following out-of-date precaches were cleaned up ` + `automatically:`, cachesDeleted); + } + } + })); + }); + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * NavigationRoute makes it easy to create a + * {@link workbox-routing.Route} that matches for browser + * [navigation requests]{@link https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests}. + * + * It will only match incoming Requests whose + * {@link https://fetch.spec.whatwg.org/#concept-request-mode|mode} + * is set to `navigate`. + * + * You can optionally only apply this route to a subset of navigation requests + * by using one or both of the `denylist` and `allowlist` parameters. + * + * @memberof workbox-routing + * @extends workbox-routing.Route + */ + class NavigationRoute extends Route { + /** + * If both `denylist` and `allowlist` are provided, the `denylist` will + * take precedence and the request will not match this route. + * + * The regular expressions in `allowlist` and `denylist` + * are matched against the concatenated + * [`pathname`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname} + * and [`search`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search} + * portions of the requested URL. + * + * *Note*: These RegExps may be evaluated against every destination URL during + * a navigation. Avoid using + * [complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077), + * or else your users may see delays when navigating your site. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {Object} options + * @param {Array} [options.denylist] If any of these patterns match, + * the route will not handle the request (even if a allowlist RegExp matches). + * @param {Array} [options.allowlist=[/./]] If any of these patterns + * match the URL's pathname and search parameter, the route will handle the + * request (assuming the denylist doesn't match). + */ + constructor(handler, { + allowlist = [/./], + denylist = [] + } = {}) { + { + finalAssertExports.isArrayOfClass(allowlist, RegExp, { + moduleName: 'workbox-routing', + className: 'NavigationRoute', + funcName: 'constructor', + paramName: 'options.allowlist' + }); + finalAssertExports.isArrayOfClass(denylist, RegExp, { + moduleName: 'workbox-routing', + className: 'NavigationRoute', + funcName: 'constructor', + paramName: 'options.denylist' + }); + } + super(options => this._match(options), handler); + this._allowlist = allowlist; + this._denylist = denylist; + } + /** + * Routes match handler. + * + * @param {Object} options + * @param {URL} options.url + * @param {Request} options.request + * @return {boolean} + * + * @private + */ + _match({ + url, + request + }) { + if (request && request.mode !== 'navigate') { + return false; + } + const pathnameAndSearch = url.pathname + url.search; + for (const regExp of this._denylist) { + if (regExp.test(pathnameAndSearch)) { + { + logger.log(`The navigation route ${pathnameAndSearch} is not ` + `being used, since the URL matches this denylist pattern: ` + `${regExp.toString()}`); + } + return false; + } + } + if (this._allowlist.some(regExp => regExp.test(pathnameAndSearch))) { + { + logger.debug(`The navigation route ${pathnameAndSearch} ` + `is being used.`); + } + return true; + } + { + logger.log(`The navigation route ${pathnameAndSearch} is not ` + `being used, since the URL being navigated to doesn't ` + `match the allowlist.`); + } + return false; + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Helper function that calls + * {@link PrecacheController#createHandlerBoundToURL} on the default + * {@link PrecacheController} instance. + * + * If you are creating your own {@link PrecacheController}, then call the + * {@link PrecacheController#createHandlerBoundToURL} on that instance, + * instead of using this function. + * + * @param {string} url The precached URL which will be used to lookup the + * `Response`. + * @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the + * response from the network if there's a precache miss. + * @return {workbox-routing~handlerCallback} + * + * @memberof workbox-precaching + */ + function createHandlerBoundToURL(url) { + const precacheController = getOrCreatePrecacheController(); + return precacheController.createHandlerBoundToURL(url); + } + + exports.NavigationRoute = NavigationRoute; + exports.cleanupOutdatedCaches = cleanupOutdatedCaches; + exports.clientsClaim = clientsClaim; + exports.createHandlerBoundToURL = createHandlerBoundToURL; + exports.precacheAndRoute = precacheAndRoute; + exports.registerRoute = registerRoute; + +})); diff --git a/dev-dist/workbox-e755d862.js b/dev-dist/workbox-e755d862.js new file mode 100644 index 0000000..e5f3f74 --- /dev/null +++ b/dev-dist/workbox-e755d862.js @@ -0,0 +1,4702 @@ +define(['exports'], (function (exports) { 'use strict'; + + // @ts-ignore + try { + self['workbox:core:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const logger = (() => { + // Don't overwrite this value if it's already set. + // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923 + if (!('__WB_DISABLE_DEV_LOGS' in globalThis)) { + self.__WB_DISABLE_DEV_LOGS = false; + } + let inGroup = false; + const methodToColorMap = { + debug: `#7f8c8d`, + log: `#2ecc71`, + warn: `#f39c12`, + error: `#c0392b`, + groupCollapsed: `#3498db`, + groupEnd: null // No colored prefix on groupEnd + }; + const print = function (method, args) { + if (self.__WB_DISABLE_DEV_LOGS) { + return; + } + if (method === 'groupCollapsed') { + // Safari doesn't print all console.groupCollapsed() arguments: + // https://bugs.webkit.org/show_bug.cgi?id=182754 + if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { + console[method](...args); + return; + } + } + const styles = [`background: ${methodToColorMap[method]}`, `border-radius: 0.5em`, `color: white`, `font-weight: bold`, `padding: 2px 0.5em`]; + // When in a group, the workbox prefix is not displayed. + const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')]; + console[method](...logPrefix, ...args); + if (method === 'groupCollapsed') { + inGroup = true; + } + if (method === 'groupEnd') { + inGroup = false; + } + }; + // eslint-disable-next-line @typescript-eslint/ban-types + const api = {}; + const loggerMethods = Object.keys(methodToColorMap); + for (const key of loggerMethods) { + const method = key; + api[method] = (...args) => { + print(method, args); + }; + } + return api; + })(); + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const messages$1 = { + 'invalid-value': ({ + paramName, + validValueDescription, + value + }) => { + if (!paramName || !validValueDescription) { + throw new Error(`Unexpected input to 'invalid-value' error.`); + } + return `The '${paramName}' parameter was given a value with an ` + `unexpected value. ${validValueDescription} Received a value of ` + `${JSON.stringify(value)}.`; + }, + 'not-an-array': ({ + moduleName, + className, + funcName, + paramName + }) => { + if (!moduleName || !className || !funcName || !paramName) { + throw new Error(`Unexpected input to 'not-an-array' error.`); + } + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${className}.${funcName}()' must be an array.`; + }, + 'incorrect-type': ({ + expectedType, + paramName, + moduleName, + className, + funcName + }) => { + if (!expectedType || !paramName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'incorrect-type' error.`); + } + const classNameStr = className ? `${className}.` : ''; + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}` + `${funcName}()' must be of type ${expectedType}.`; + }, + 'incorrect-class': ({ + expectedClassName, + paramName, + moduleName, + className, + funcName, + isReturnValueProblem + }) => { + if (!expectedClassName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'incorrect-class' error.`); + } + const classNameStr = className ? `${className}.` : ''; + if (isReturnValueProblem) { + return `The return value from ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`; + } + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`; + }, + 'missing-a-method': ({ + expectedMethod, + paramName, + moduleName, + className, + funcName + }) => { + if (!expectedMethod || !paramName || !moduleName || !className || !funcName) { + throw new Error(`Unexpected input to 'missing-a-method' error.`); + } + return `${moduleName}.${className}.${funcName}() expected the ` + `'${paramName}' parameter to expose a '${expectedMethod}' method.`; + }, + 'add-to-cache-list-unexpected-type': ({ + entry + }) => { + return `An unexpected entry was passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' The entry ` + `'${JSON.stringify(entry)}' isn't supported. You must supply an array of ` + `strings with one or more characters, objects with a url property or ` + `Request objects.`; + }, + 'add-to-cache-list-conflicting-entries': ({ + firstEntry, + secondEntry + }) => { + if (!firstEntry || !secondEntry) { + throw new Error(`Unexpected input to ` + `'add-to-cache-list-duplicate-entries' error.`); + } + return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + `${firstEntry} but different revision details. Workbox is ` + `unable to cache and version the asset correctly. Please remove one ` + `of the entries.`; + }, + 'plugin-error-request-will-fetch': ({ + thrownErrorMessage + }) => { + if (!thrownErrorMessage) { + throw new Error(`Unexpected input to ` + `'plugin-error-request-will-fetch', error.`); + } + return `An error was thrown by a plugins 'requestWillFetch()' method. ` + `The thrown error message was: '${thrownErrorMessage}'.`; + }, + 'invalid-cache-name': ({ + cacheNameId, + value + }) => { + if (!cacheNameId) { + throw new Error(`Expected a 'cacheNameId' for error 'invalid-cache-name'`); + } + return `You must provide a name containing at least one character for ` + `setCacheDetails({${cacheNameId}: '...'}). Received a value of ` + `'${JSON.stringify(value)}'`; + }, + 'unregister-route-but-not-found-with-method': ({ + method + }) => { + if (!method) { + throw new Error(`Unexpected input to ` + `'unregister-route-but-not-found-with-method' error.`); + } + return `The route you're trying to unregister was not previously ` + `registered for the method type '${method}'.`; + }, + 'unregister-route-route-not-registered': () => { + return `The route you're trying to unregister was not previously ` + `registered.`; + }, + 'queue-replay-failed': ({ + name + }) => { + return `Replaying the background sync queue '${name}' failed.`; + }, + 'duplicate-queue-name': ({ + name + }) => { + return `The Queue name '${name}' is already being used. ` + `All instances of backgroundSync.Queue must be given unique names.`; + }, + 'expired-test-without-max-age': ({ + methodName, + paramName + }) => { + return `The '${methodName}()' method can only be used when the ` + `'${paramName}' is used in the constructor.`; + }, + 'unsupported-route-type': ({ + moduleName, + className, + funcName, + paramName + }) => { + return `The supplied '${paramName}' parameter was an unsupported type. ` + `Please check the docs for ${moduleName}.${className}.${funcName} for ` + `valid input types.`; + }, + 'not-array-of-class': ({ + value, + expectedClass, + moduleName, + className, + funcName, + paramName + }) => { + return `The supplied '${paramName}' parameter must be an array of ` + `'${expectedClass}' objects. Received '${JSON.stringify(value)},'. ` + `Please check the call to ${moduleName}.${className}.${funcName}() ` + `to fix the issue.`; + }, + 'max-entries-or-age-required': ({ + moduleName, + className, + funcName + }) => { + return `You must define either config.maxEntries or config.maxAgeSeconds` + `in ${moduleName}.${className}.${funcName}`; + }, + 'statuses-or-headers-required': ({ + moduleName, + className, + funcName + }) => { + return `You must define either config.statuses or config.headers` + `in ${moduleName}.${className}.${funcName}`; + }, + 'invalid-string': ({ + moduleName, + funcName, + paramName + }) => { + if (!paramName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'invalid-string' error.`); + } + return `When using strings, the '${paramName}' parameter must start with ` + `'http' (for cross-origin matches) or '/' (for same-origin matches). ` + `Please see the docs for ${moduleName}.${funcName}() for ` + `more info.`; + }, + 'channel-name-required': () => { + return `You must provide a channelName to construct a ` + `BroadcastCacheUpdate instance.`; + }, + 'invalid-responses-are-same-args': () => { + return `The arguments passed into responsesAreSame() appear to be ` + `invalid. Please ensure valid Responses are used.`; + }, + 'expire-custom-caches-only': () => { + return `You must provide a 'cacheName' property when using the ` + `expiration plugin with a runtime caching strategy.`; + }, + 'unit-must-be-bytes': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'unit-must-be-bytes' error.`); + } + return `The 'unit' portion of the Range header must be set to 'bytes'. ` + `The Range header provided was "${normalizedRangeHeader}"`; + }, + 'single-range-only': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'single-range-only' error.`); + } + return `Multiple ranges are not supported. Please use a single start ` + `value, and optional end value. The Range header provided was ` + `"${normalizedRangeHeader}"`; + }, + 'invalid-range-values': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'invalid-range-values' error.`); + } + return `The Range header is missing both start and end values. At least ` + `one of those values is needed. The Range header provided was ` + `"${normalizedRangeHeader}"`; + }, + 'no-range-header': () => { + return `No Range header was found in the Request provided.`; + }, + 'range-not-satisfiable': ({ + size, + start, + end + }) => { + return `The start (${start}) and end (${end}) values in the Range are ` + `not satisfiable by the cached response, which is ${size} bytes.`; + }, + 'attempt-to-cache-non-get-request': ({ + url, + method + }) => { + return `Unable to cache '${url}' because it is a '${method}' request and ` + `only 'GET' requests can be cached.`; + }, + 'cache-put-with-no-response': ({ + url + }) => { + return `There was an attempt to cache '${url}' but the response was not ` + `defined.`; + }, + 'no-response': ({ + url, + error + }) => { + let message = `The strategy could not generate a response for '${url}'.`; + if (error) { + message += ` The underlying error is ${error}.`; + } + return message; + }, + 'bad-precaching-response': ({ + url, + status + }) => { + return `The precaching request for '${url}' failed` + (status ? ` with an HTTP status of ${status}.` : `.`); + }, + 'non-precached-url': ({ + url + }) => { + return `createHandlerBoundToURL('${url}') was called, but that URL is ` + `not precached. Please pass in a URL that is precached instead.`; + }, + 'add-to-cache-list-conflicting-integrities': ({ + url + }) => { + return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + `${url} with different integrity values. Please remove one of them.`; + }, + 'missing-precache-entry': ({ + cacheName, + url + }) => { + return `Unable to find a precached response in ${cacheName} for ${url}.`; + }, + 'cross-origin-copy-response': ({ + origin + }) => { + return `workbox-core.copyResponse() can only be used with same-origin ` + `responses. It was passed a response with origin ${origin}.`; + }, + 'opaque-streams-source': ({ + type + }) => { + const message = `One of the workbox-streams sources resulted in an ` + `'${type}' response.`; + if (type === 'opaqueredirect') { + return `${message} Please do not use a navigation request that results ` + `in a redirect as a source.`; + } + return `${message} Please ensure your sources are CORS-enabled.`; + } + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const generatorFunction = (code, details = {}) => { + const message = messages$1[code]; + if (!message) { + throw new Error(`Unable to find message for code '${code}'.`); + } + return message(details); + }; + const messageGenerator = generatorFunction; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Workbox errors should be thrown with this class. + * This allows use to ensure the type easily in tests, + * helps developers identify errors from workbox + * easily and allows use to optimise error + * messages correctly. + * + * @private + */ + class WorkboxError extends Error { + /** + * + * @param {string} errorCode The error code that + * identifies this particular error. + * @param {Object=} details Any relevant arguments + * that will help developers identify issues should + * be added as a key on the context object. + */ + constructor(errorCode, details) { + const message = messageGenerator(errorCode, details); + super(message); + this.name = errorCode; + this.details = details; + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /* + * This method throws if the supplied value is not an array. + * The destructed values are required to produce a meaningful error for users. + * The destructed and restructured object is so it's clear what is + * needed. + */ + const isArray = (value, details) => { + if (!Array.isArray(value)) { + throw new WorkboxError('not-an-array', details); + } + }; + const hasMethod = (object, expectedMethod, details) => { + const type = typeof object[expectedMethod]; + if (type !== 'function') { + details['expectedMethod'] = expectedMethod; + throw new WorkboxError('missing-a-method', details); + } + }; + const isType = (object, expectedType, details) => { + if (typeof object !== expectedType) { + details['expectedType'] = expectedType; + throw new WorkboxError('incorrect-type', details); + } + }; + const isInstance = (object, + // Need the general type to do the check later. + // eslint-disable-next-line @typescript-eslint/ban-types + expectedClass, details) => { + if (!(object instanceof expectedClass)) { + details['expectedClassName'] = expectedClass.name; + throw new WorkboxError('incorrect-class', details); + } + }; + const isOneOf = (value, validValues, details) => { + if (!validValues.includes(value)) { + details['validValueDescription'] = `Valid values are ${JSON.stringify(validValues)}.`; + throw new WorkboxError('invalid-value', details); + } + }; + const isArrayOfClass = (value, + // Need general type to do check later. + expectedClass, + // eslint-disable-line + details) => { + const error = new WorkboxError('not-array-of-class', details); + if (!Array.isArray(value)) { + throw error; + } + for (const item of value) { + if (!(item instanceof expectedClass)) { + throw error; + } + } + }; + const finalAssertExports = { + hasMethod, + isArray, + isInstance, + isOneOf, + isType, + isArrayOfClass + }; + + // @ts-ignore + try { + self['workbox:routing:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The default HTTP method, 'GET', used when there's no specific method + * configured for a route. + * + * @type {string} + * + * @private + */ + const defaultMethod = 'GET'; + /** + * The list of valid HTTP methods associated with requests that could be routed. + * + * @type {Array} + * + * @private + */ + const validMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT']; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * @param {function()|Object} handler Either a function, or an object with a + * 'handle' method. + * @return {Object} An object with a handle method. + * + * @private + */ + const normalizeHandler = handler => { + if (handler && typeof handler === 'object') { + { + finalAssertExports.hasMethod(handler, 'handle', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'handler' + }); + } + return handler; + } else { + { + finalAssertExports.isType(handler, 'function', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'handler' + }); + } + return { + handle: handler + }; + } + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A `Route` consists of a pair of callback functions, "match" and "handler". + * The "match" callback determine if a route should be used to "handle" a + * request by returning a non-falsy value if it can. The "handler" callback + * is called when there is a match and should return a Promise that resolves + * to a `Response`. + * + * @memberof workbox-routing + */ + class Route { + /** + * Constructor for Route class. + * + * @param {workbox-routing~matchCallback} match + * A callback function that determines whether the route matches a given + * `fetch` event by returning a non-falsy value. + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resolving to a Response. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + */ + constructor(match, handler, method = defaultMethod) { + { + finalAssertExports.isType(match, 'function', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'match' + }); + if (method) { + finalAssertExports.isOneOf(method, validMethods, { + paramName: 'method' + }); + } + } + // These values are referenced directly by Router so cannot be + // altered by minificaton. + this.handler = normalizeHandler(handler); + this.match = match; + this.method = method; + } + /** + * + * @param {workbox-routing-handlerCallback} handler A callback + * function that returns a Promise resolving to a Response + */ + setCatchHandler(handler) { + this.catchHandler = normalizeHandler(handler); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * RegExpRoute makes it easy to create a regular expression based + * {@link workbox-routing.Route}. + * + * For same-origin requests the RegExp only needs to match part of the URL. For + * requests against third-party servers, you must define a RegExp that matches + * the start of the URL. + * + * @memberof workbox-routing + * @extends workbox-routing.Route + */ + class RegExpRoute extends Route { + /** + * If the regular expression contains + * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references}, + * the captured values will be passed to the + * {@link workbox-routing~handlerCallback} `params` + * argument. + * + * @param {RegExp} regExp The regular expression to match against URLs. + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + */ + constructor(regExp, handler, method) { + { + finalAssertExports.isInstance(regExp, RegExp, { + moduleName: 'workbox-routing', + className: 'RegExpRoute', + funcName: 'constructor', + paramName: 'pattern' + }); + } + const match = ({ + url + }) => { + const result = regExp.exec(url.href); + // Return immediately if there's no match. + if (!result) { + return; + } + // Require that the match start at the first character in the URL string + // if it's a cross-origin request. + // See https://github.com/GoogleChrome/workbox/issues/281 for the context + // behind this behavior. + if (url.origin !== location.origin && result.index !== 0) { + { + logger.debug(`The regular expression '${regExp.toString()}' only partially matched ` + `against the cross-origin URL '${url.toString()}'. RegExpRoute's will only ` + `handle cross-origin requests if they match the entire URL.`); + } + return; + } + // If the route matches, but there aren't any capture groups defined, then + // this will return [], which is truthy and therefore sufficient to + // indicate a match. + // If there are capture groups, then it will return their values. + return result.slice(1); + }; + super(match, handler, method); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const getFriendlyURL = url => { + const urlObj = new URL(String(url), location.href); + // See https://github.com/GoogleChrome/workbox/issues/2323 + // We want to include everything, except for the origin if it's same-origin. + return urlObj.href.replace(new RegExp(`^${location.origin}`), ''); + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The Router can be used to process a `FetchEvent` using one or more + * {@link workbox-routing.Route}, responding with a `Response` if + * a matching route exists. + * + * If no route matches a given a request, the Router will use a "default" + * handler if one is defined. + * + * Should the matching Route throw an error, the Router will use a "catch" + * handler if one is defined to gracefully deal with issues and respond with a + * Request. + * + * If a request matches multiple routes, the **earliest** registered route will + * be used to respond to the request. + * + * @memberof workbox-routing + */ + class Router { + /** + * Initializes a new Router. + */ + constructor() { + this._routes = new Map(); + this._defaultHandlerMap = new Map(); + } + /** + * @return {Map>} routes A `Map` of HTTP + * method name ('GET', etc.) to an array of all the corresponding `Route` + * instances that are registered. + */ + get routes() { + return this._routes; + } + /** + * Adds a fetch event listener to respond to events when a route matches + * the event's request. + */ + addFetchListener() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('fetch', event => { + const { + request + } = event; + const responsePromise = this.handleRequest({ + request, + event + }); + if (responsePromise) { + event.respondWith(responsePromise); + } + }); + } + /** + * Adds a message event listener for URLs to cache from the window. + * This is useful to cache resources loaded on the page prior to when the + * service worker started controlling it. + * + * The format of the message data sent from the window should be as follows. + * Where the `urlsToCache` array may consist of URL strings or an array of + * URL string + `requestInit` object (the same as you'd pass to `fetch()`). + * + * ``` + * { + * type: 'CACHE_URLS', + * payload: { + * urlsToCache: [ + * './script1.js', + * './script2.js', + * ['./script3.js', {mode: 'no-cors'}], + * ], + * }, + * } + * ``` + */ + addCacheListener() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('message', event => { + // event.data is type 'any' + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (event.data && event.data.type === 'CACHE_URLS') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const { + payload + } = event.data; + { + logger.debug(`Caching URLs from the window`, payload.urlsToCache); + } + const requestPromises = Promise.all(payload.urlsToCache.map(entry => { + if (typeof entry === 'string') { + entry = [entry]; + } + const request = new Request(...entry); + return this.handleRequest({ + request, + event + }); + // TODO(philipwalton): TypeScript errors without this typecast for + // some reason (probably a bug). The real type here should work but + // doesn't: `Array | undefined>`. + })); // TypeScript + event.waitUntil(requestPromises); + // If a MessageChannel was used, reply to the message on success. + if (event.ports && event.ports[0]) { + void requestPromises.then(() => event.ports[0].postMessage(true)); + } + } + }); + } + /** + * Apply the routing rules to a FetchEvent object to get a Response from an + * appropriate Route's handler. + * + * @param {Object} options + * @param {Request} options.request The request to handle. + * @param {ExtendableEvent} options.event The event that triggered the + * request. + * @return {Promise|undefined} A promise is returned if a + * registered route can handle the request. If there is no matching + * route and there's no `defaultHandler`, `undefined` is returned. + */ + handleRequest({ + request, + event + }) { + { + finalAssertExports.isInstance(request, Request, { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'handleRequest', + paramName: 'options.request' + }); + } + const url = new URL(request.url, location.href); + if (!url.protocol.startsWith('http')) { + { + logger.debug(`Workbox Router only supports URLs that start with 'http'.`); + } + return; + } + const sameOrigin = url.origin === location.origin; + const { + params, + route + } = this.findMatchingRoute({ + event, + request, + sameOrigin, + url + }); + let handler = route && route.handler; + const debugMessages = []; + { + if (handler) { + debugMessages.push([`Found a route to handle this request:`, route]); + if (params) { + debugMessages.push([`Passing the following params to the route's handler:`, params]); + } + } + } + // If we don't have a handler because there was no matching route, then + // fall back to defaultHandler if that's defined. + const method = request.method; + if (!handler && this._defaultHandlerMap.has(method)) { + { + debugMessages.push(`Failed to find a matching route. Falling ` + `back to the default handler for ${method}.`); + } + handler = this._defaultHandlerMap.get(method); + } + if (!handler) { + { + // No handler so Workbox will do nothing. If logs is set of debug + // i.e. verbose, we should print out this information. + logger.debug(`No route found for: ${getFriendlyURL(url)}`); + } + return; + } + { + // We have a handler, meaning Workbox is going to handle the route. + // print the routing details to the console. + logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`); + debugMessages.forEach(msg => { + if (Array.isArray(msg)) { + logger.log(...msg); + } else { + logger.log(msg); + } + }); + logger.groupEnd(); + } + // Wrap in try and catch in case the handle method throws a synchronous + // error. It should still callback to the catch handler. + let responsePromise; + try { + responsePromise = handler.handle({ + url, + request, + event, + params + }); + } catch (err) { + responsePromise = Promise.reject(err); + } + // Get route's catch handler, if it exists + const catchHandler = route && route.catchHandler; + if (responsePromise instanceof Promise && (this._catchHandler || catchHandler)) { + responsePromise = responsePromise.catch(async err => { + // If there's a route catch handler, process that first + if (catchHandler) { + { + // Still include URL here as it will be async from the console group + // and may not make sense without the URL + logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL(url)}. Falling back to route's Catch Handler.`); + logger.error(`Error thrown by:`, route); + logger.error(err); + logger.groupEnd(); + } + try { + return await catchHandler.handle({ + url, + request, + event, + params + }); + } catch (catchErr) { + if (catchErr instanceof Error) { + err = catchErr; + } + } + } + if (this._catchHandler) { + { + // Still include URL here as it will be async from the console group + // and may not make sense without the URL + logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL(url)}. Falling back to global Catch Handler.`); + logger.error(`Error thrown by:`, route); + logger.error(err); + logger.groupEnd(); + } + return this._catchHandler.handle({ + url, + request, + event + }); + } + throw err; + }); + } + return responsePromise; + } + /** + * Checks a request and URL (and optionally an event) against the list of + * registered routes, and if there's a match, returns the corresponding + * route along with any params generated by the match. + * + * @param {Object} options + * @param {URL} options.url + * @param {boolean} options.sameOrigin The result of comparing `url.origin` + * against the current origin. + * @param {Request} options.request The request to match. + * @param {Event} options.event The corresponding event. + * @return {Object} An object with `route` and `params` properties. + * They are populated if a matching route was found or `undefined` + * otherwise. + */ + findMatchingRoute({ + url, + sameOrigin, + request, + event + }) { + const routes = this._routes.get(request.method) || []; + for (const route of routes) { + let params; + // route.match returns type any, not possible to change right now. + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const matchResult = route.match({ + url, + sameOrigin, + request, + event + }); + if (matchResult) { + { + // Warn developers that using an async matchCallback is almost always + // not the right thing to do. + if (matchResult instanceof Promise) { + logger.warn(`While routing ${getFriendlyURL(url)}, an async ` + `matchCallback function was used. Please convert the ` + `following route to use a synchronous matchCallback function:`, route); + } + } + // See https://github.com/GoogleChrome/workbox/issues/2079 + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + params = matchResult; + if (Array.isArray(params) && params.length === 0) { + // Instead of passing an empty array in as params, use undefined. + params = undefined; + } else if (matchResult.constructor === Object && + // eslint-disable-line + Object.keys(matchResult).length === 0) { + // Instead of passing an empty object in as params, use undefined. + params = undefined; + } else if (typeof matchResult === 'boolean') { + // For the boolean value true (rather than just something truth-y), + // don't set params. + // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353 + params = undefined; + } + // Return early if have a match. + return { + route, + params + }; + } + } + // If no match was found above, return and empty object. + return {}; + } + /** + * Define a default `handler` that's called when no routes explicitly + * match the incoming request. + * + * Each HTTP method ('GET', 'POST', etc.) gets its own default handler. + * + * Without a default handler, unmatched requests will go against the + * network as if there were no service worker present. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {string} [method='GET'] The HTTP method to associate with this + * default handler. Each method has its own default. + */ + setDefaultHandler(handler, method = defaultMethod) { + this._defaultHandlerMap.set(method, normalizeHandler(handler)); + } + /** + * If a Route throws an error while handling a request, this `handler` + * will be called and given a chance to provide a response. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + */ + setCatchHandler(handler) { + this._catchHandler = normalizeHandler(handler); + } + /** + * Registers a route with the router. + * + * @param {workbox-routing.Route} route The route to register. + */ + registerRoute(route) { + { + finalAssertExports.isType(route, 'object', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.hasMethod(route, 'match', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.isType(route.handler, 'object', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.hasMethod(route.handler, 'handle', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route.handler' + }); + finalAssertExports.isType(route.method, 'string', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route.method' + }); + } + if (!this._routes.has(route.method)) { + this._routes.set(route.method, []); + } + // Give precedence to all of the earlier routes by adding this additional + // route to the end of the array. + this._routes.get(route.method).push(route); + } + /** + * Unregisters a route with the router. + * + * @param {workbox-routing.Route} route The route to unregister. + */ + unregisterRoute(route) { + if (!this._routes.has(route.method)) { + throw new WorkboxError('unregister-route-but-not-found-with-method', { + method: route.method + }); + } + const routeIndex = this._routes.get(route.method).indexOf(route); + if (routeIndex > -1) { + this._routes.get(route.method).splice(routeIndex, 1); + } else { + throw new WorkboxError('unregister-route-route-not-registered'); + } + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + let defaultRouter; + /** + * Creates a new, singleton Router instance if one does not exist. If one + * does already exist, that instance is returned. + * + * @private + * @return {Router} + */ + const getOrCreateDefaultRouter = () => { + if (!defaultRouter) { + defaultRouter = new Router(); + // The helpers that use the default Router assume these listeners exist. + defaultRouter.addFetchListener(); + defaultRouter.addCacheListener(); + } + return defaultRouter; + }; + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Easily register a RegExp, string, or function with a caching + * strategy to a singleton Router instance. + * + * This method will generate a Route for you if needed and + * call {@link workbox-routing.Router#registerRoute}. + * + * @param {RegExp|string|workbox-routing.Route~matchCallback|workbox-routing.Route} capture + * If the capture param is a `Route`, all other arguments will be ignored. + * @param {workbox-routing~handlerCallback} [handler] A callback + * function that returns a Promise resulting in a Response. This parameter + * is required if `capture` is not a `Route` object. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + * @return {workbox-routing.Route} The generated `Route`. + * + * @memberof workbox-routing + */ + function registerRoute(capture, handler, method) { + let route; + if (typeof capture === 'string') { + const captureUrl = new URL(capture, location.href); + { + if (!(capture.startsWith('/') || capture.startsWith('http'))) { + throw new WorkboxError('invalid-string', { + moduleName: 'workbox-routing', + funcName: 'registerRoute', + paramName: 'capture' + }); + } + // We want to check if Express-style wildcards are in the pathname only. + // TODO: Remove this log message in v4. + const valueToCheck = capture.startsWith('http') ? captureUrl.pathname : capture; + // See https://github.com/pillarjs/path-to-regexp#parameters + const wildcards = '[*:?+]'; + if (new RegExp(`${wildcards}`).exec(valueToCheck)) { + logger.debug(`The '$capture' parameter contains an Express-style wildcard ` + `character (${wildcards}). Strings are now always interpreted as ` + `exact matches; use a RegExp for partial or wildcard matches.`); + } + } + const matchCallback = ({ + url + }) => { + { + if (url.pathname === captureUrl.pathname && url.origin !== captureUrl.origin) { + logger.debug(`${capture} only partially matches the cross-origin URL ` + `${url.toString()}. This route will only handle cross-origin requests ` + `if they match the entire URL.`); + } + } + return url.href === captureUrl.href; + }; + // If `capture` is a string then `handler` and `method` must be present. + route = new Route(matchCallback, handler, method); + } else if (capture instanceof RegExp) { + // If `capture` is a `RegExp` then `handler` and `method` must be present. + route = new RegExpRoute(capture, handler, method); + } else if (typeof capture === 'function') { + // If `capture` is a function then `handler` and `method` must be present. + route = new Route(capture, handler, method); + } else if (capture instanceof Route) { + route = capture; + } else { + throw new WorkboxError('unsupported-route-type', { + moduleName: 'workbox-routing', + funcName: 'registerRoute', + paramName: 'capture' + }); + } + const defaultRouter = getOrCreateDefaultRouter(); + defaultRouter.registerRoute(route); + return route; + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const _cacheNameDetails = { + googleAnalytics: 'googleAnalytics', + precache: 'precache-v2', + prefix: 'workbox', + runtime: 'runtime', + suffix: typeof registration !== 'undefined' ? registration.scope : '' + }; + const _createCacheName = cacheName => { + return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix].filter(value => value && value.length > 0).join('-'); + }; + const eachCacheNameDetail = fn => { + for (const key of Object.keys(_cacheNameDetails)) { + fn(key); + } + }; + const cacheNames = { + updateDetails: details => { + eachCacheNameDetail(key => { + if (typeof details[key] === 'string') { + _cacheNameDetails[key] = details[key]; + } + }); + }, + getGoogleAnalyticsName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics); + }, + getPrecacheName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.precache); + }, + getPrefix: () => { + return _cacheNameDetails.prefix; + }, + getRuntimeName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.runtime); + }, + getSuffix: () => { + return _cacheNameDetails.suffix; + } + }; + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A helper function that prevents a promise from being flagged as unused. + * + * @private + **/ + function dontWaitFor(promise) { + // Effective no-op. + void promise.then(() => {}); + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + // Callbacks to be executed whenever there's a quota error. + // Can't change Function type right now. + // eslint-disable-next-line @typescript-eslint/ban-types + const quotaErrorCallbacks = new Set(); + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Adds a function to the set of quotaErrorCallbacks that will be executed if + * there's a quota error. + * + * @param {Function} callback + * @memberof workbox-core + */ + // Can't change Function type + // eslint-disable-next-line @typescript-eslint/ban-types + function registerQuotaErrorCallback(callback) { + { + finalAssertExports.isType(callback, 'function', { + moduleName: 'workbox-core', + funcName: 'register', + paramName: 'callback' + }); + } + quotaErrorCallbacks.add(callback); + { + logger.log('Registered a callback to respond to quota errors.', callback); + } + } + + function _extends() { + return _extends = Object.assign ? Object.assign.bind() : function (n) { + for (var e = 1; e < arguments.length; e++) { + var t = arguments[e]; + for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); + } + return n; + }, _extends.apply(null, arguments); + } + + const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c); + let idbProxyableTypes; + let cursorAdvanceMethods; + // This is a function to prevent it throwing up in node environments. + function getIdbProxyableTypes() { + return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]); + } + // This is a function to prevent it throwing up in node environments. + function getCursorAdvanceMethods() { + return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]); + } + const cursorRequestMap = new WeakMap(); + const transactionDoneMap = new WeakMap(); + const transactionStoreNamesMap = new WeakMap(); + const transformCache = new WeakMap(); + const reverseTransformCache = new WeakMap(); + function promisifyRequest(request) { + const promise = new Promise((resolve, reject) => { + const unlisten = () => { + request.removeEventListener('success', success); + request.removeEventListener('error', error); + }; + const success = () => { + resolve(wrap(request.result)); + unlisten(); + }; + const error = () => { + reject(request.error); + unlisten(); + }; + request.addEventListener('success', success); + request.addEventListener('error', error); + }); + promise.then(value => { + // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval + // (see wrapFunction). + if (value instanceof IDBCursor) { + cursorRequestMap.set(value, request); + } + // Catching to avoid "Uncaught Promise exceptions" + }).catch(() => {}); + // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This + // is because we create many promises from a single IDBRequest. + reverseTransformCache.set(promise, request); + return promise; + } + function cacheDonePromiseForTransaction(tx) { + // Early bail if we've already created a done promise for this transaction. + if (transactionDoneMap.has(tx)) return; + const done = new Promise((resolve, reject) => { + const unlisten = () => { + tx.removeEventListener('complete', complete); + tx.removeEventListener('error', error); + tx.removeEventListener('abort', error); + }; + const complete = () => { + resolve(); + unlisten(); + }; + const error = () => { + reject(tx.error || new DOMException('AbortError', 'AbortError')); + unlisten(); + }; + tx.addEventListener('complete', complete); + tx.addEventListener('error', error); + tx.addEventListener('abort', error); + }); + // Cache it for later retrieval. + transactionDoneMap.set(tx, done); + } + let idbProxyTraps = { + get(target, prop, receiver) { + if (target instanceof IDBTransaction) { + // Special handling for transaction.done. + if (prop === 'done') return transactionDoneMap.get(target); + // Polyfill for objectStoreNames because of Edge. + if (prop === 'objectStoreNames') { + return target.objectStoreNames || transactionStoreNamesMap.get(target); + } + // Make tx.store return the only store in the transaction, or undefined if there are many. + if (prop === 'store') { + return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]); + } + } + // Else transform whatever we get back. + return wrap(target[prop]); + }, + set(target, prop, value) { + target[prop] = value; + return true; + }, + has(target, prop) { + if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) { + return true; + } + return prop in target; + } + }; + function replaceTraps(callback) { + idbProxyTraps = callback(idbProxyTraps); + } + function wrapFunction(func) { + // Due to expected object equality (which is enforced by the caching in `wrap`), we + // only create one new func per func. + // Edge doesn't support objectStoreNames (booo), so we polyfill it here. + if (func === IDBDatabase.prototype.transaction && !('objectStoreNames' in IDBTransaction.prototype)) { + return function (storeNames, ...args) { + const tx = func.call(unwrap(this), storeNames, ...args); + transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]); + return wrap(tx); + }; + } + // Cursor methods are special, as the behaviour is a little more different to standard IDB. In + // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the + // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense + // with real promises, so each advance methods returns a new promise for the cursor object, or + // undefined if the end of the cursor has been reached. + if (getCursorAdvanceMethods().includes(func)) { + return function (...args) { + // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use + // the original object. + func.apply(unwrap(this), args); + return wrap(cursorRequestMap.get(this)); + }; + } + return function (...args) { + // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use + // the original object. + return wrap(func.apply(unwrap(this), args)); + }; + } + function transformCachableValue(value) { + if (typeof value === 'function') return wrapFunction(value); + // This doesn't return, it just creates a 'done' promise for the transaction, + // which is later returned for transaction.done (see idbObjectHandler). + if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value); + if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps); + // Return the same value back if we're not going to transform it. + return value; + } + function wrap(value) { + // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because + // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached. + if (value instanceof IDBRequest) return promisifyRequest(value); + // If we've already transformed this value before, reuse the transformed value. + // This is faster, but it also provides object equality. + if (transformCache.has(value)) return transformCache.get(value); + const newValue = transformCachableValue(value); + // Not all types are transformed. + // These may be primitive types, so they can't be WeakMap keys. + if (newValue !== value) { + transformCache.set(value, newValue); + reverseTransformCache.set(newValue, value); + } + return newValue; + } + const unwrap = value => reverseTransformCache.get(value); + + /** + * Open a database. + * + * @param name Name of the database. + * @param version Schema version. + * @param callbacks Additional callbacks. + */ + function openDB(name, version, { + blocked, + upgrade, + blocking, + terminated + } = {}) { + const request = indexedDB.open(name, version); + const openPromise = wrap(request); + if (upgrade) { + request.addEventListener('upgradeneeded', event => { + upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event); + }); + } + if (blocked) { + request.addEventListener('blocked', event => blocked( + // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405 + event.oldVersion, event.newVersion, event)); + } + openPromise.then(db => { + if (terminated) db.addEventListener('close', () => terminated()); + if (blocking) { + db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event)); + } + }).catch(() => {}); + return openPromise; + } + /** + * Delete a database. + * + * @param name Name of the database. + */ + function deleteDB(name, { + blocked + } = {}) { + const request = indexedDB.deleteDatabase(name); + if (blocked) { + request.addEventListener('blocked', event => blocked( + // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405 + event.oldVersion, event)); + } + return wrap(request).then(() => undefined); + } + const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count']; + const writeMethods = ['put', 'add', 'delete', 'clear']; + const cachedMethods = new Map(); + function getMethod(target, prop) { + if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) { + return; + } + if (cachedMethods.get(prop)) return cachedMethods.get(prop); + const targetFuncName = prop.replace(/FromIndex$/, ''); + const useIndex = prop !== targetFuncName; + const isWrite = writeMethods.includes(targetFuncName); + if ( + // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge. + !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) { + return; + } + const method = async function (storeName, ...args) { + // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :( + const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly'); + let target = tx.store; + if (useIndex) target = target.index(args.shift()); + // Must reject if op rejects. + // If it's a write operation, must reject if tx.done rejects. + // Must reject with op rejection first. + // Must resolve with op value. + // Must handle both promises (no unhandled rejections) + return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0]; + }; + cachedMethods.set(prop, method); + return method; + } + replaceTraps(oldTraps => _extends({}, oldTraps, { + get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver), + has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop) + })); + + // @ts-ignore + try { + self['workbox:expiration:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const DB_NAME = 'workbox-expiration'; + const CACHE_OBJECT_STORE = 'cache-entries'; + const normalizeURL = unNormalizedUrl => { + const url = new URL(unNormalizedUrl, location.href); + url.hash = ''; + return url.href; + }; + /** + * Returns the timestamp model. + * + * @private + */ + class CacheTimestampsModel { + /** + * + * @param {string} cacheName + * + * @private + */ + constructor(cacheName) { + this._db = null; + this._cacheName = cacheName; + } + /** + * Performs an upgrade of indexedDB. + * + * @param {IDBPDatabase} db + * + * @private + */ + _upgradeDb(db) { + // TODO(philipwalton): EdgeHTML doesn't support arrays as a keyPath, so we + // have to use the `id` keyPath here and create our own values (a + // concatenation of `url + cacheName`) instead of simply using + // `keyPath: ['url', 'cacheName']`, which is supported in other browsers. + const objStore = db.createObjectStore(CACHE_OBJECT_STORE, { + keyPath: 'id' + }); + // TODO(philipwalton): once we don't have to support EdgeHTML, we can + // create a single index with the keyPath `['cacheName', 'timestamp']` + // instead of doing both these indexes. + objStore.createIndex('cacheName', 'cacheName', { + unique: false + }); + objStore.createIndex('timestamp', 'timestamp', { + unique: false + }); + } + /** + * Performs an upgrade of indexedDB and deletes deprecated DBs. + * + * @param {IDBPDatabase} db + * + * @private + */ + _upgradeDbAndDeleteOldDbs(db) { + this._upgradeDb(db); + if (this._cacheName) { + void deleteDB(this._cacheName); + } + } + /** + * @param {string} url + * @param {number} timestamp + * + * @private + */ + async setTimestamp(url, timestamp) { + url = normalizeURL(url); + const entry = { + url, + timestamp, + cacheName: this._cacheName, + // Creating an ID from the URL and cache name won't be necessary once + // Edge switches to Chromium and all browsers we support work with + // array keyPaths. + id: this._getId(url) + }; + const db = await this.getDb(); + const tx = db.transaction(CACHE_OBJECT_STORE, 'readwrite', { + durability: 'relaxed' + }); + await tx.store.put(entry); + await tx.done; + } + /** + * Returns the timestamp stored for a given URL. + * + * @param {string} url + * @return {number | undefined} + * + * @private + */ + async getTimestamp(url) { + const db = await this.getDb(); + const entry = await db.get(CACHE_OBJECT_STORE, this._getId(url)); + return entry === null || entry === void 0 ? void 0 : entry.timestamp; + } + /** + * Iterates through all the entries in the object store (from newest to + * oldest) and removes entries once either `maxCount` is reached or the + * entry's timestamp is less than `minTimestamp`. + * + * @param {number} minTimestamp + * @param {number} maxCount + * @return {Array} + * + * @private + */ + async expireEntries(minTimestamp, maxCount) { + const db = await this.getDb(); + let cursor = await db.transaction(CACHE_OBJECT_STORE).store.index('timestamp').openCursor(null, 'prev'); + const entriesToDelete = []; + let entriesNotDeletedCount = 0; + while (cursor) { + const result = cursor.value; + // TODO(philipwalton): once we can use a multi-key index, we + // won't have to check `cacheName` here. + if (result.cacheName === this._cacheName) { + // Delete an entry if it's older than the max age or + // if we already have the max number allowed. + if (minTimestamp && result.timestamp < minTimestamp || maxCount && entriesNotDeletedCount >= maxCount) { + // TODO(philipwalton): we should be able to delete the + // entry right here, but doing so causes an iteration + // bug in Safari stable (fixed in TP). Instead we can + // store the keys of the entries to delete, and then + // delete the separate transactions. + // https://github.com/GoogleChrome/workbox/issues/1978 + // cursor.delete(); + // We only need to return the URL, not the whole entry. + entriesToDelete.push(cursor.value); + } else { + entriesNotDeletedCount++; + } + } + cursor = await cursor.continue(); + } + // TODO(philipwalton): once the Safari bug in the following issue is fixed, + // we should be able to remove this loop and do the entry deletion in the + // cursor loop above: + // https://github.com/GoogleChrome/workbox/issues/1978 + const urlsDeleted = []; + for (const entry of entriesToDelete) { + await db.delete(CACHE_OBJECT_STORE, entry.id); + urlsDeleted.push(entry.url); + } + return urlsDeleted; + } + /** + * Takes a URL and returns an ID that will be unique in the object store. + * + * @param {string} url + * @return {string} + * + * @private + */ + _getId(url) { + // Creating an ID from the URL and cache name won't be necessary once + // Edge switches to Chromium and all browsers we support work with + // array keyPaths. + return this._cacheName + '|' + normalizeURL(url); + } + /** + * Returns an open connection to the database. + * + * @private + */ + async getDb() { + if (!this._db) { + this._db = await openDB(DB_NAME, 1, { + upgrade: this._upgradeDbAndDeleteOldDbs.bind(this) + }); + } + return this._db; + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The `CacheExpiration` class allows you define an expiration and / or + * limit on the number of responses stored in a + * [`Cache`](https://developer.mozilla.org/en-US/docs/Web/API/Cache). + * + * @memberof workbox-expiration + */ + class CacheExpiration { + /** + * To construct a new CacheExpiration instance you must provide at least + * one of the `config` properties. + * + * @param {string} cacheName Name of the cache to apply restrictions to. + * @param {Object} config + * @param {number} [config.maxEntries] The maximum number of entries to cache. + * Entries used the least will be removed as the maximum is reached. + * @param {number} [config.maxAgeSeconds] The maximum age of an entry before + * it's treated as stale and removed. + * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters) + * that will be used when calling `delete()` on the cache. + */ + constructor(cacheName, config = {}) { + this._isRunning = false; + this._rerunRequested = false; + { + finalAssertExports.isType(cacheName, 'string', { + moduleName: 'workbox-expiration', + className: 'CacheExpiration', + funcName: 'constructor', + paramName: 'cacheName' + }); + if (!(config.maxEntries || config.maxAgeSeconds)) { + throw new WorkboxError('max-entries-or-age-required', { + moduleName: 'workbox-expiration', + className: 'CacheExpiration', + funcName: 'constructor' + }); + } + if (config.maxEntries) { + finalAssertExports.isType(config.maxEntries, 'number', { + moduleName: 'workbox-expiration', + className: 'CacheExpiration', + funcName: 'constructor', + paramName: 'config.maxEntries' + }); + } + if (config.maxAgeSeconds) { + finalAssertExports.isType(config.maxAgeSeconds, 'number', { + moduleName: 'workbox-expiration', + className: 'CacheExpiration', + funcName: 'constructor', + paramName: 'config.maxAgeSeconds' + }); + } + } + this._maxEntries = config.maxEntries; + this._maxAgeSeconds = config.maxAgeSeconds; + this._matchOptions = config.matchOptions; + this._cacheName = cacheName; + this._timestampModel = new CacheTimestampsModel(cacheName); + } + /** + * Expires entries for the given cache and given criteria. + */ + async expireEntries() { + if (this._isRunning) { + this._rerunRequested = true; + return; + } + this._isRunning = true; + const minTimestamp = this._maxAgeSeconds ? Date.now() - this._maxAgeSeconds * 1000 : 0; + const urlsExpired = await this._timestampModel.expireEntries(minTimestamp, this._maxEntries); + // Delete URLs from the cache + const cache = await self.caches.open(this._cacheName); + for (const url of urlsExpired) { + await cache.delete(url, this._matchOptions); + } + { + if (urlsExpired.length > 0) { + logger.groupCollapsed(`Expired ${urlsExpired.length} ` + `${urlsExpired.length === 1 ? 'entry' : 'entries'} and removed ` + `${urlsExpired.length === 1 ? 'it' : 'them'} from the ` + `'${this._cacheName}' cache.`); + logger.log(`Expired the following ${urlsExpired.length === 1 ? 'URL' : 'URLs'}:`); + urlsExpired.forEach(url => logger.log(` ${url}`)); + logger.groupEnd(); + } else { + logger.debug(`Cache expiration ran and found no entries to remove.`); + } + } + this._isRunning = false; + if (this._rerunRequested) { + this._rerunRequested = false; + dontWaitFor(this.expireEntries()); + } + } + /** + * Update the timestamp for the given URL. This ensures the when + * removing entries based on maximum entries, most recently used + * is accurate or when expiring, the timestamp is up-to-date. + * + * @param {string} url + */ + async updateTimestamp(url) { + { + finalAssertExports.isType(url, 'string', { + moduleName: 'workbox-expiration', + className: 'CacheExpiration', + funcName: 'updateTimestamp', + paramName: 'url' + }); + } + await this._timestampModel.setTimestamp(url, Date.now()); + } + /** + * Can be used to check if a URL has expired or not before it's used. + * + * This requires a look up from IndexedDB, so can be slow. + * + * Note: This method will not remove the cached entry, call + * `expireEntries()` to remove indexedDB and Cache entries. + * + * @param {string} url + * @return {boolean} + */ + async isURLExpired(url) { + if (!this._maxAgeSeconds) { + { + throw new WorkboxError(`expired-test-without-max-age`, { + methodName: 'isURLExpired', + paramName: 'maxAgeSeconds' + }); + } + } else { + const timestamp = await this._timestampModel.getTimestamp(url); + const expireOlderThan = Date.now() - this._maxAgeSeconds * 1000; + return timestamp !== undefined ? timestamp < expireOlderThan : true; + } + } + /** + * Removes the IndexedDB object store used to keep track of cache expiration + * metadata. + */ + async delete() { + // Make sure we don't attempt another rerun if we're called in the middle of + // a cache expiration. + this._rerunRequested = false; + await this._timestampModel.expireEntries(Infinity); // Expires all. + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * This plugin can be used in a `workbox-strategy` to regularly enforce a + * limit on the age and / or the number of cached requests. + * + * It can only be used with `workbox-strategy` instances that have a + * [custom `cacheName` property set](/web/tools/workbox/guides/configure-workbox#custom_cache_names_in_strategies). + * In other words, it can't be used to expire entries in strategy that uses the + * default runtime cache name. + * + * Whenever a cached response is used or updated, this plugin will look + * at the associated cache and remove any old or extra responses. + * + * When using `maxAgeSeconds`, responses may be used *once* after expiring + * because the expiration clean up will not have occurred until *after* the + * cached response has been used. If the response has a "Date" header, then + * a light weight expiration check is performed and the response will not be + * used immediately. + * + * When using `maxEntries`, the entry least-recently requested will be removed + * from the cache first. + * + * @memberof workbox-expiration + */ + class ExpirationPlugin { + /** + * @param {ExpirationPluginOptions} config + * @param {number} [config.maxEntries] The maximum number of entries to cache. + * Entries used the least will be removed as the maximum is reached. + * @param {number} [config.maxAgeSeconds] The maximum age of an entry before + * it's treated as stale and removed. + * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters) + * that will be used when calling `delete()` on the cache. + * @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to + * automatic deletion if the available storage quota has been exceeded. + */ + constructor(config = {}) { + /** + * A "lifecycle" callback that will be triggered automatically by the + * `workbox-strategies` handlers when a `Response` is about to be returned + * from a [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) to + * the handler. It allows the `Response` to be inspected for freshness and + * prevents it from being used if the `Response`'s `Date` header value is + * older than the configured `maxAgeSeconds`. + * + * @param {Object} options + * @param {string} options.cacheName Name of the cache the response is in. + * @param {Response} options.cachedResponse The `Response` object that's been + * read from a cache and whose freshness should be checked. + * @return {Response} Either the `cachedResponse`, if it's + * fresh, or `null` if the `Response` is older than `maxAgeSeconds`. + * + * @private + */ + this.cachedResponseWillBeUsed = async ({ + event, + request, + cacheName, + cachedResponse + }) => { + if (!cachedResponse) { + return null; + } + const isFresh = this._isResponseDateFresh(cachedResponse); + // Expire entries to ensure that even if the expiration date has + // expired, it'll only be used once. + const cacheExpiration = this._getCacheExpiration(cacheName); + dontWaitFor(cacheExpiration.expireEntries()); + // Update the metadata for the request URL to the current timestamp, + // but don't `await` it as we don't want to block the response. + const updateTimestampDone = cacheExpiration.updateTimestamp(request.url); + if (event) { + try { + event.waitUntil(updateTimestampDone); + } catch (error) { + { + // The event may not be a fetch event; only log the URL if it is. + if ('request' in event) { + logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache entry for ` + `'${getFriendlyURL(event.request.url)}'.`); + } + } + } + } + return isFresh ? cachedResponse : null; + }; + /** + * A "lifecycle" callback that will be triggered automatically by the + * `workbox-strategies` handlers when an entry is added to a cache. + * + * @param {Object} options + * @param {string} options.cacheName Name of the cache that was updated. + * @param {string} options.request The Request for the cached entry. + * + * @private + */ + this.cacheDidUpdate = async ({ + cacheName, + request + }) => { + { + finalAssertExports.isType(cacheName, 'string', { + moduleName: 'workbox-expiration', + className: 'Plugin', + funcName: 'cacheDidUpdate', + paramName: 'cacheName' + }); + finalAssertExports.isInstance(request, Request, { + moduleName: 'workbox-expiration', + className: 'Plugin', + funcName: 'cacheDidUpdate', + paramName: 'request' + }); + } + const cacheExpiration = this._getCacheExpiration(cacheName); + await cacheExpiration.updateTimestamp(request.url); + await cacheExpiration.expireEntries(); + }; + { + if (!(config.maxEntries || config.maxAgeSeconds)) { + throw new WorkboxError('max-entries-or-age-required', { + moduleName: 'workbox-expiration', + className: 'Plugin', + funcName: 'constructor' + }); + } + if (config.maxEntries) { + finalAssertExports.isType(config.maxEntries, 'number', { + moduleName: 'workbox-expiration', + className: 'Plugin', + funcName: 'constructor', + paramName: 'config.maxEntries' + }); + } + if (config.maxAgeSeconds) { + finalAssertExports.isType(config.maxAgeSeconds, 'number', { + moduleName: 'workbox-expiration', + className: 'Plugin', + funcName: 'constructor', + paramName: 'config.maxAgeSeconds' + }); + } + } + this._config = config; + this._maxAgeSeconds = config.maxAgeSeconds; + this._cacheExpirations = new Map(); + if (config.purgeOnQuotaError) { + registerQuotaErrorCallback(() => this.deleteCacheAndMetadata()); + } + } + /** + * A simple helper method to return a CacheExpiration instance for a given + * cache name. + * + * @param {string} cacheName + * @return {CacheExpiration} + * + * @private + */ + _getCacheExpiration(cacheName) { + if (cacheName === cacheNames.getRuntimeName()) { + throw new WorkboxError('expire-custom-caches-only'); + } + let cacheExpiration = this._cacheExpirations.get(cacheName); + if (!cacheExpiration) { + cacheExpiration = new CacheExpiration(cacheName, this._config); + this._cacheExpirations.set(cacheName, cacheExpiration); + } + return cacheExpiration; + } + /** + * @param {Response} cachedResponse + * @return {boolean} + * + * @private + */ + _isResponseDateFresh(cachedResponse) { + if (!this._maxAgeSeconds) { + // We aren't expiring by age, so return true, it's fresh + return true; + } + // Check if the 'date' header will suffice a quick expiration check. + // See https://github.com/GoogleChromeLabs/sw-toolbox/issues/164 for + // discussion. + const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse); + if (dateHeaderTimestamp === null) { + // Unable to parse date, so assume it's fresh. + return true; + } + // If we have a valid headerTime, then our response is fresh iff the + // headerTime plus maxAgeSeconds is greater than the current time. + const now = Date.now(); + return dateHeaderTimestamp >= now - this._maxAgeSeconds * 1000; + } + /** + * This method will extract the data header and parse it into a useful + * value. + * + * @param {Response} cachedResponse + * @return {number|null} + * + * @private + */ + _getDateHeaderTimestamp(cachedResponse) { + if (!cachedResponse.headers.has('date')) { + return null; + } + const dateHeader = cachedResponse.headers.get('date'); + const parsedDate = new Date(dateHeader); + const headerTime = parsedDate.getTime(); + // If the Date header was invalid for some reason, parsedDate.getTime() + // will return NaN. + if (isNaN(headerTime)) { + return null; + } + return headerTime; + } + /** + * This is a helper method that performs two operations: + * + * - Deletes *all* the underlying Cache instances associated with this plugin + * instance, by calling caches.delete() on your behalf. + * - Deletes the metadata from IndexedDB used to keep track of expiration + * details for each Cache instance. + * + * When using cache expiration, calling this method is preferable to calling + * `caches.delete()` directly, since this will ensure that the IndexedDB + * metadata is also cleanly removed and open IndexedDB instances are deleted. + * + * Note that if you're *not* using cache expiration for a given cache, calling + * `caches.delete()` and passing in the cache's name should be sufficient. + * There is no Workbox-specific method needed for cleanup in that case. + */ + async deleteCacheAndMetadata() { + // Do this one at a time instead of all at once via `Promise.all()` to + // reduce the chance of inconsistency if a promise rejects. + for (const [cacheName, cacheExpiration] of this._cacheExpirations) { + await self.caches.delete(cacheName); + await cacheExpiration.delete(); + } + // Reset this._cacheExpirations to its initial state. + this._cacheExpirations = new Map(); + } + } + + // @ts-ignore + try { + self['workbox:cacheable-response:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * This class allows you to set up rules determining what + * status codes and/or headers need to be present in order for a + * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) + * to be considered cacheable. + * + * @memberof workbox-cacheable-response + */ + class CacheableResponse { + /** + * To construct a new CacheableResponse instance you must provide at least + * one of the `config` properties. + * + * If both `statuses` and `headers` are specified, then both conditions must + * be met for the `Response` to be considered cacheable. + * + * @param {Object} config + * @param {Array} [config.statuses] One or more status codes that a + * `Response` can have and be considered cacheable. + * @param {Object} [config.headers] A mapping of header names + * and expected values that a `Response` can have and be considered cacheable. + * If multiple headers are provided, only one needs to be present. + */ + constructor(config = {}) { + { + if (!(config.statuses || config.headers)) { + throw new WorkboxError('statuses-or-headers-required', { + moduleName: 'workbox-cacheable-response', + className: 'CacheableResponse', + funcName: 'constructor' + }); + } + if (config.statuses) { + finalAssertExports.isArray(config.statuses, { + moduleName: 'workbox-cacheable-response', + className: 'CacheableResponse', + funcName: 'constructor', + paramName: 'config.statuses' + }); + } + if (config.headers) { + finalAssertExports.isType(config.headers, 'object', { + moduleName: 'workbox-cacheable-response', + className: 'CacheableResponse', + funcName: 'constructor', + paramName: 'config.headers' + }); + } + } + this._statuses = config.statuses; + this._headers = config.headers; + } + /** + * Checks a response to see whether it's cacheable or not, based on this + * object's configuration. + * + * @param {Response} response The response whose cacheability is being + * checked. + * @return {boolean} `true` if the `Response` is cacheable, and `false` + * otherwise. + */ + isResponseCacheable(response) { + { + finalAssertExports.isInstance(response, Response, { + moduleName: 'workbox-cacheable-response', + className: 'CacheableResponse', + funcName: 'isResponseCacheable', + paramName: 'response' + }); + } + let cacheable = true; + if (this._statuses) { + cacheable = this._statuses.includes(response.status); + } + if (this._headers && cacheable) { + cacheable = Object.keys(this._headers).some(headerName => { + return response.headers.get(headerName) === this._headers[headerName]; + }); + } + { + if (!cacheable) { + logger.groupCollapsed(`The request for ` + `'${getFriendlyURL(response.url)}' returned a response that does ` + `not meet the criteria for being cached.`); + logger.groupCollapsed(`View cacheability criteria here.`); + logger.log(`Cacheable statuses: ` + JSON.stringify(this._statuses)); + logger.log(`Cacheable headers: ` + JSON.stringify(this._headers, null, 2)); + logger.groupEnd(); + const logFriendlyHeaders = {}; + response.headers.forEach((value, key) => { + logFriendlyHeaders[key] = value; + }); + logger.groupCollapsed(`View response status and headers here.`); + logger.log(`Response status: ${response.status}`); + logger.log(`Response headers: ` + JSON.stringify(logFriendlyHeaders, null, 2)); + logger.groupEnd(); + logger.groupCollapsed(`View full response details here.`); + logger.log(response.headers); + logger.log(response); + logger.groupEnd(); + logger.groupEnd(); + } + } + return cacheable; + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it + * easier to add in cacheability checks to requests made via Workbox's built-in + * strategies. + * + * @memberof workbox-cacheable-response + */ + class CacheableResponsePlugin { + /** + * To construct a new CacheableResponsePlugin instance you must provide at + * least one of the `config` properties. + * + * If both `statuses` and `headers` are specified, then both conditions must + * be met for the `Response` to be considered cacheable. + * + * @param {Object} config + * @param {Array} [config.statuses] One or more status codes that a + * `Response` can have and be considered cacheable. + * @param {Object} [config.headers] A mapping of header names + * and expected values that a `Response` can have and be considered cacheable. + * If multiple headers are provided, only one needs to be present. + */ + constructor(config) { + /** + * @param {Object} options + * @param {Response} options.response + * @return {Response|null} + * @private + */ + this.cacheWillUpdate = async ({ + response + }) => { + if (this._cacheableResponse.isResponseCacheable(response)) { + return response; + } + return null; + }; + this._cacheableResponse = new CacheableResponse(config); + } + } + + // @ts-ignore + try { + self['workbox:strategies:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const cacheOkAndOpaquePlugin = { + /** + * Returns a valid response (to allow caching) if the status is 200 (OK) or + * 0 (opaque). + * + * @param {Object} options + * @param {Response} options.response + * @return {Response|null} + * + * @private + */ + cacheWillUpdate: async ({ + response + }) => { + if (response.status === 200 || response.status === 0) { + return response; + } + return null; + } + }; + + /* + Copyright 2020 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + function stripParams(fullURL, ignoreParams) { + const strippedURL = new URL(fullURL); + for (const param of ignoreParams) { + strippedURL.searchParams.delete(param); + } + return strippedURL.href; + } + /** + * Matches an item in the cache, ignoring specific URL params. This is similar + * to the `ignoreSearch` option, but it allows you to ignore just specific + * params (while continuing to match on the others). + * + * @private + * @param {Cache} cache + * @param {Request} request + * @param {Object} matchOptions + * @param {Array} ignoreParams + * @return {Promise} + */ + async function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) { + const strippedRequestURL = stripParams(request.url, ignoreParams); + // If the request doesn't include any ignored params, match as normal. + if (request.url === strippedRequestURL) { + return cache.match(request, matchOptions); + } + // Otherwise, match by comparing keys + const keysOptions = Object.assign(Object.assign({}, matchOptions), { + ignoreSearch: true + }); + const cacheKeys = await cache.keys(request, keysOptions); + for (const cacheKey of cacheKeys) { + const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams); + if (strippedRequestURL === strippedCacheKeyURL) { + return cache.match(cacheKey, matchOptions); + } + } + return; + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The Deferred class composes Promises in a way that allows for them to be + * resolved or rejected from outside the constructor. In most cases promises + * should be used directly, but Deferreds can be necessary when the logic to + * resolve a promise must be separate. + * + * @private + */ + class Deferred { + /** + * Creates a promise and exposes its resolve and reject functions as methods. + */ + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Runs all of the callback functions, one at a time sequentially, in the order + * in which they were registered. + * + * @memberof workbox-core + * @private + */ + async function executeQuotaErrorCallbacks() { + { + logger.log(`About to run ${quotaErrorCallbacks.size} ` + `callbacks to clean up caches.`); + } + for (const callback of quotaErrorCallbacks) { + await callback(); + { + logger.log(callback, 'is complete.'); + } + } + { + logger.log('Finished running callbacks.'); + } + } + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Returns a promise that resolves and the passed number of milliseconds. + * This utility is an async/await-friendly version of `setTimeout`. + * + * @param {number} ms + * @return {Promise} + * @private + */ + function timeout(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + function toRequest(input) { + return typeof input === 'string' ? new Request(input) : input; + } + /** + * A class created every time a Strategy instance instance calls + * {@link workbox-strategies.Strategy~handle} or + * {@link workbox-strategies.Strategy~handleAll} that wraps all fetch and + * cache actions around plugin callbacks and keeps track of when the strategy + * is "done" (i.e. all added `event.waitUntil()` promises have resolved). + * + * @memberof workbox-strategies + */ + class StrategyHandler { + /** + * Creates a new instance associated with the passed strategy and event + * that's handling the request. + * + * The constructor also initializes the state that will be passed to each of + * the plugins handling this request. + * + * @param {workbox-strategies.Strategy} strategy + * @param {Object} options + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] The return value from the + * {@link workbox-routing~matchCallback} (if applicable). + */ + constructor(strategy, options) { + this._cacheKeys = {}; + /** + * The request the strategy is performing (passed to the strategy's + * `handle()` or `handleAll()` method). + * @name request + * @instance + * @type {Request} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * The event associated with this request. + * @name event + * @instance + * @type {ExtendableEvent} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * A `URL` instance of `request.url` (if passed to the strategy's + * `handle()` or `handleAll()` method). + * Note: the `url` param will be present if the strategy was invoked + * from a workbox `Route` object. + * @name url + * @instance + * @type {URL|undefined} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * A `param` value (if passed to the strategy's + * `handle()` or `handleAll()` method). + * Note: the `param` param will be present if the strategy was invoked + * from a workbox `Route` object and the + * {@link workbox-routing~matchCallback} returned + * a truthy value (it will be that value). + * @name params + * @instance + * @type {*|undefined} + * @memberof workbox-strategies.StrategyHandler + */ + { + finalAssertExports.isInstance(options.event, ExtendableEvent, { + moduleName: 'workbox-strategies', + className: 'StrategyHandler', + funcName: 'constructor', + paramName: 'options.event' + }); + } + Object.assign(this, options); + this.event = options.event; + this._strategy = strategy; + this._handlerDeferred = new Deferred(); + this._extendLifetimePromises = []; + // Copy the plugins list (since it's mutable on the strategy), + // so any mutations don't affect this handler instance. + this._plugins = [...strategy.plugins]; + this._pluginStateMap = new Map(); + for (const plugin of this._plugins) { + this._pluginStateMap.set(plugin, {}); + } + this.event.waitUntil(this._handlerDeferred.promise); + } + /** + * Fetches a given request (and invokes any applicable plugin callback + * methods) using the `fetchOptions` (for non-navigation requests) and + * `plugins` defined on the `Strategy` object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - `requestWillFetch()` + * - `fetchDidSucceed()` + * - `fetchDidFail()` + * + * @param {Request|string} input The URL or request to fetch. + * @return {Promise} + */ + async fetch(input) { + const { + event + } = this; + let request = toRequest(input); + if (request.mode === 'navigate' && event instanceof FetchEvent && event.preloadResponse) { + const possiblePreloadResponse = await event.preloadResponse; + if (possiblePreloadResponse) { + { + logger.log(`Using a preloaded navigation response for ` + `'${getFriendlyURL(request.url)}'`); + } + return possiblePreloadResponse; + } + } + // If there is a fetchDidFail plugin, we need to save a clone of the + // original request before it's either modified by a requestWillFetch + // plugin or before the original request's body is consumed via fetch(). + const originalRequest = this.hasCallback('fetchDidFail') ? request.clone() : null; + try { + for (const cb of this.iterateCallbacks('requestWillFetch')) { + request = await cb({ + request: request.clone(), + event + }); + } + } catch (err) { + if (err instanceof Error) { + throw new WorkboxError('plugin-error-request-will-fetch', { + thrownErrorMessage: err.message + }); + } + } + // The request can be altered by plugins with `requestWillFetch` making + // the original request (most likely from a `fetch` event) different + // from the Request we make. Pass both to `fetchDidFail` to aid debugging. + const pluginFilteredRequest = request.clone(); + try { + let fetchResponse; + // See https://github.com/GoogleChrome/workbox/issues/1796 + fetchResponse = await fetch(request, request.mode === 'navigate' ? undefined : this._strategy.fetchOptions); + if ("development" !== 'production') { + logger.debug(`Network request for ` + `'${getFriendlyURL(request.url)}' returned a response with ` + `status '${fetchResponse.status}'.`); + } + for (const callback of this.iterateCallbacks('fetchDidSucceed')) { + fetchResponse = await callback({ + event, + request: pluginFilteredRequest, + response: fetchResponse + }); + } + return fetchResponse; + } catch (error) { + { + logger.log(`Network request for ` + `'${getFriendlyURL(request.url)}' threw an error.`, error); + } + // `originalRequest` will only exist if a `fetchDidFail` callback + // is being used (see above). + if (originalRequest) { + await this.runCallbacks('fetchDidFail', { + error: error, + event, + originalRequest: originalRequest.clone(), + request: pluginFilteredRequest.clone() + }); + } + throw error; + } + } + /** + * Calls `this.fetch()` and (in the background) runs `this.cachePut()` on + * the response generated by `this.fetch()`. + * + * The call to `this.cachePut()` automatically invokes `this.waitUntil()`, + * so you do not have to manually call `waitUntil()` on the event. + * + * @param {Request|string} input The request or URL to fetch and cache. + * @return {Promise} + */ + async fetchAndCachePut(input) { + const response = await this.fetch(input); + const responseClone = response.clone(); + void this.waitUntil(this.cachePut(input, responseClone)); + return response; + } + /** + * Matches a request from the cache (and invokes any applicable plugin + * callback methods) using the `cacheName`, `matchOptions`, and `plugins` + * defined on the strategy object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - cacheKeyWillBeUsed() + * - cachedResponseWillBeUsed() + * + * @param {Request|string} key The Request or URL to use as the cache key. + * @return {Promise} A matching response, if found. + */ + async cacheMatch(key) { + const request = toRequest(key); + let cachedResponse; + const { + cacheName, + matchOptions + } = this._strategy; + const effectiveRequest = await this.getCacheKey(request, 'read'); + const multiMatchOptions = Object.assign(Object.assign({}, matchOptions), { + cacheName + }); + cachedResponse = await caches.match(effectiveRequest, multiMatchOptions); + { + if (cachedResponse) { + logger.debug(`Found a cached response in '${cacheName}'.`); + } else { + logger.debug(`No cached response found in '${cacheName}'.`); + } + } + for (const callback of this.iterateCallbacks('cachedResponseWillBeUsed')) { + cachedResponse = (await callback({ + cacheName, + matchOptions, + cachedResponse, + request: effectiveRequest, + event: this.event + })) || undefined; + } + return cachedResponse; + } + /** + * Puts a request/response pair in the cache (and invokes any applicable + * plugin callback methods) using the `cacheName` and `plugins` defined on + * the strategy object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - cacheKeyWillBeUsed() + * - cacheWillUpdate() + * - cacheDidUpdate() + * + * @param {Request|string} key The request or URL to use as the cache key. + * @param {Response} response The response to cache. + * @return {Promise} `false` if a cacheWillUpdate caused the response + * not be cached, and `true` otherwise. + */ + async cachePut(key, response) { + const request = toRequest(key); + // Run in the next task to avoid blocking other cache reads. + // https://github.com/w3c/ServiceWorker/issues/1397 + await timeout(0); + const effectiveRequest = await this.getCacheKey(request, 'write'); + { + if (effectiveRequest.method && effectiveRequest.method !== 'GET') { + throw new WorkboxError('attempt-to-cache-non-get-request', { + url: getFriendlyURL(effectiveRequest.url), + method: effectiveRequest.method + }); + } + // See https://github.com/GoogleChrome/workbox/issues/2818 + const vary = response.headers.get('Vary'); + if (vary) { + logger.debug(`The response for ${getFriendlyURL(effectiveRequest.url)} ` + `has a 'Vary: ${vary}' header. ` + `Consider setting the {ignoreVary: true} option on your strategy ` + `to ensure cache matching and deletion works as expected.`); + } + } + if (!response) { + { + logger.error(`Cannot cache non-existent response for ` + `'${getFriendlyURL(effectiveRequest.url)}'.`); + } + throw new WorkboxError('cache-put-with-no-response', { + url: getFriendlyURL(effectiveRequest.url) + }); + } + const responseToCache = await this._ensureResponseSafeToCache(response); + if (!responseToCache) { + { + logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' ` + `will not be cached.`, responseToCache); + } + return false; + } + const { + cacheName, + matchOptions + } = this._strategy; + const cache = await self.caches.open(cacheName); + const hasCacheUpdateCallback = this.hasCallback('cacheDidUpdate'); + const oldResponse = hasCacheUpdateCallback ? await cacheMatchIgnoreParams( + // TODO(philipwalton): the `__WB_REVISION__` param is a precaching + // feature. Consider into ways to only add this behavior if using + // precaching. + cache, effectiveRequest.clone(), ['__WB_REVISION__'], matchOptions) : null; + { + logger.debug(`Updating the '${cacheName}' cache with a new Response ` + `for ${getFriendlyURL(effectiveRequest.url)}.`); + } + try { + await cache.put(effectiveRequest, hasCacheUpdateCallback ? responseToCache.clone() : responseToCache); + } catch (error) { + if (error instanceof Error) { + // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError + if (error.name === 'QuotaExceededError') { + await executeQuotaErrorCallbacks(); + } + throw error; + } + } + for (const callback of this.iterateCallbacks('cacheDidUpdate')) { + await callback({ + cacheName, + oldResponse, + newResponse: responseToCache.clone(), + request: effectiveRequest, + event: this.event + }); + } + return true; + } + /** + * Checks the list of plugins for the `cacheKeyWillBeUsed` callback, and + * executes any of those callbacks found in sequence. The final `Request` + * object returned by the last plugin is treated as the cache key for cache + * reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have + * been registered, the passed request is returned unmodified + * + * @param {Request} request + * @param {string} mode + * @return {Promise} + */ + async getCacheKey(request, mode) { + const key = `${request.url} | ${mode}`; + if (!this._cacheKeys[key]) { + let effectiveRequest = request; + for (const callback of this.iterateCallbacks('cacheKeyWillBeUsed')) { + effectiveRequest = toRequest(await callback({ + mode, + request: effectiveRequest, + event: this.event, + // params has a type any can't change right now. + params: this.params // eslint-disable-line + })); + } + this._cacheKeys[key] = effectiveRequest; + } + return this._cacheKeys[key]; + } + /** + * Returns true if the strategy has at least one plugin with the given + * callback. + * + * @param {string} name The name of the callback to check for. + * @return {boolean} + */ + hasCallback(name) { + for (const plugin of this._strategy.plugins) { + if (name in plugin) { + return true; + } + } + return false; + } + /** + * Runs all plugin callbacks matching the given name, in order, passing the + * given param object (merged ith the current plugin state) as the only + * argument. + * + * Note: since this method runs all plugins, it's not suitable for cases + * where the return value of a callback needs to be applied prior to calling + * the next callback. See + * {@link workbox-strategies.StrategyHandler#iterateCallbacks} + * below for how to handle that case. + * + * @param {string} name The name of the callback to run within each plugin. + * @param {Object} param The object to pass as the first (and only) param + * when executing each callback. This object will be merged with the + * current plugin state prior to callback execution. + */ + async runCallbacks(name, param) { + for (const callback of this.iterateCallbacks(name)) { + // TODO(philipwalton): not sure why `any` is needed. It seems like + // this should work with `as WorkboxPluginCallbackParam[C]`. + await callback(param); + } + } + /** + * Accepts a callback and returns an iterable of matching plugin callbacks, + * where each callback is wrapped with the current handler state (i.e. when + * you call each callback, whatever object parameter you pass it will + * be merged with the plugin's current state). + * + * @param {string} name The name fo the callback to run + * @return {Array} + */ + *iterateCallbacks(name) { + for (const plugin of this._strategy.plugins) { + if (typeof plugin[name] === 'function') { + const state = this._pluginStateMap.get(plugin); + const statefulCallback = param => { + const statefulParam = Object.assign(Object.assign({}, param), { + state + }); + // TODO(philipwalton): not sure why `any` is needed. It seems like + // this should work with `as WorkboxPluginCallbackParam[C]`. + return plugin[name](statefulParam); + }; + yield statefulCallback; + } + } + } + /** + * Adds a promise to the + * [extend lifetime promises]{@link https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises} + * of the event event associated with the request being handled (usually a + * `FetchEvent`). + * + * Note: you can await + * {@link workbox-strategies.StrategyHandler~doneWaiting} + * to know when all added promises have settled. + * + * @param {Promise} promise A promise to add to the extend lifetime promises + * of the event that triggered the request. + */ + waitUntil(promise) { + this._extendLifetimePromises.push(promise); + return promise; + } + /** + * Returns a promise that resolves once all promises passed to + * {@link workbox-strategies.StrategyHandler~waitUntil} + * have settled. + * + * Note: any work done after `doneWaiting()` settles should be manually + * passed to an event's `waitUntil()` method (not this handler's + * `waitUntil()` method), otherwise the service worker thread my be killed + * prior to your work completing. + */ + async doneWaiting() { + let promise; + while (promise = this._extendLifetimePromises.shift()) { + await promise; + } + } + /** + * Stops running the strategy and immediately resolves any pending + * `waitUntil()` promises. + */ + destroy() { + this._handlerDeferred.resolve(null); + } + /** + * This method will call cacheWillUpdate on the available plugins (or use + * status === 200) to determine if the Response is safe and valid to cache. + * + * @param {Request} options.request + * @param {Response} options.response + * @return {Promise} + * + * @private + */ + async _ensureResponseSafeToCache(response) { + let responseToCache = response; + let pluginsUsed = false; + for (const callback of this.iterateCallbacks('cacheWillUpdate')) { + responseToCache = (await callback({ + request: this.request, + response: responseToCache, + event: this.event + })) || undefined; + pluginsUsed = true; + if (!responseToCache) { + break; + } + } + if (!pluginsUsed) { + if (responseToCache && responseToCache.status !== 200) { + responseToCache = undefined; + } + { + if (responseToCache) { + if (responseToCache.status !== 200) { + if (responseToCache.status === 0) { + logger.warn(`The response for '${this.request.url}' ` + `is an opaque response. The caching strategy that you're ` + `using will not cache opaque responses by default.`); + } else { + logger.debug(`The response for '${this.request.url}' ` + `returned a status code of '${response.status}' and won't ` + `be cached as a result.`); + } + } + } + } + } + return responseToCache; + } + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * An abstract base class that all other strategy classes must extend from: + * + * @memberof workbox-strategies + */ + class Strategy { + /** + * Creates a new instance of the strategy and sets all documented option + * properties as public instance properties. + * + * Note: if a custom strategy class extends the base Strategy class and does + * not need more than these properties, it does not need to define its own + * constructor. + * + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) + * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) + * `fetch()` requests made by this strategy. + * @param {Object} [options.matchOptions] The + * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + */ + constructor(options = {}) { + /** + * Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * + * @type {string} + */ + this.cacheName = cacheNames.getRuntimeName(options.cacheName); + /** + * The list + * [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * used by this strategy. + * + * @type {Array} + */ + this.plugins = options.plugins || []; + /** + * Values passed along to the + * [`init`]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters} + * of all fetch() requests made by this strategy. + * + * @type {Object} + */ + this.fetchOptions = options.fetchOptions; + /** + * The + * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + * + * @type {Object} + */ + this.matchOptions = options.matchOptions; + } + /** + * Perform a request strategy and returns a `Promise` that will resolve with + * a `Response`, invoking all relevant plugin callbacks. + * + * When a strategy instance is registered with a Workbox + * {@link workbox-routing.Route}, this method is automatically + * called when the route matches. + * + * Alternatively, this method can be used in a standalone `FetchEvent` + * listener by passing it to `event.respondWith()`. + * + * @param {FetchEvent|Object} options A `FetchEvent` or an object with the + * properties listed below. + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] + */ + handle(options) { + const [responseDone] = this.handleAll(options); + return responseDone; + } + /** + * Similar to {@link workbox-strategies.Strategy~handle}, but + * instead of just returning a `Promise` that resolves to a `Response` it + * it will return an tuple of `[response, done]` promises, where the former + * (`response`) is equivalent to what `handle()` returns, and the latter is a + * Promise that will resolve once any promises that were added to + * `event.waitUntil()` as part of performing the strategy have completed. + * + * You can await the `done` promise to ensure any extra work performed by + * the strategy (usually caching responses) completes successfully. + * + * @param {FetchEvent|Object} options A `FetchEvent` or an object with the + * properties listed below. + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] + * @return {Array} A tuple of [response, done] + * promises that can be used to determine when the response resolves as + * well as when the handler has completed all its work. + */ + handleAll(options) { + // Allow for flexible options to be passed. + if (options instanceof FetchEvent) { + options = { + event: options, + request: options.request + }; + } + const event = options.event; + const request = typeof options.request === 'string' ? new Request(options.request) : options.request; + const params = 'params' in options ? options.params : undefined; + const handler = new StrategyHandler(this, { + event, + request, + params + }); + const responseDone = this._getResponse(handler, request, event); + const handlerDone = this._awaitComplete(responseDone, handler, request, event); + // Return an array of promises, suitable for use with Promise.all(). + return [responseDone, handlerDone]; + } + async _getResponse(handler, request, event) { + await handler.runCallbacks('handlerWillStart', { + event, + request + }); + let response = undefined; + try { + response = await this._handle(request, handler); + // The "official" Strategy subclasses all throw this error automatically, + // but in case a third-party Strategy doesn't, ensure that we have a + // consistent failure when there's no response or an error response. + if (!response || response.type === 'error') { + throw new WorkboxError('no-response', { + url: request.url + }); + } + } catch (error) { + if (error instanceof Error) { + for (const callback of handler.iterateCallbacks('handlerDidError')) { + response = await callback({ + error, + event, + request + }); + if (response) { + break; + } + } + } + if (!response) { + throw error; + } else { + logger.log(`While responding to '${getFriendlyURL(request.url)}', ` + `an ${error instanceof Error ? error.toString() : ''} error occurred. Using a fallback response provided by ` + `a handlerDidError plugin.`); + } + } + for (const callback of handler.iterateCallbacks('handlerWillRespond')) { + response = await callback({ + event, + request, + response + }); + } + return response; + } + async _awaitComplete(responseDone, handler, request, event) { + let response; + let error; + try { + response = await responseDone; + } catch (error) { + // Ignore errors, as response errors should be caught via the `response` + // promise above. The `done` promise will only throw for errors in + // promises passed to `handler.waitUntil()`. + } + try { + await handler.runCallbacks('handlerDidRespond', { + event, + request, + response + }); + await handler.doneWaiting(); + } catch (waitUntilError) { + if (waitUntilError instanceof Error) { + error = waitUntilError; + } + } + await handler.runCallbacks('handlerDidComplete', { + event, + request, + response, + error: error + }); + handler.destroy(); + if (error) { + throw error; + } + } + } + /** + * Classes extending the `Strategy` based class should implement this method, + * and leverage the {@link workbox-strategies.StrategyHandler} + * arg to perform all fetching and cache logic, which will ensure all relevant + * cache, cache options, fetch options and plugins are used (per the current + * strategy instance). + * + * @name _handle + * @instance + * @abstract + * @function + * @param {Request} request + * @param {workbox-strategies.StrategyHandler} handler + * @return {Promise} + * + * @memberof workbox-strategies.Strategy + */ + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const messages = { + strategyStart: (strategyName, request) => `Using ${strategyName} to respond to '${getFriendlyURL(request.url)}'`, + printFinalResponse: response => { + if (response) { + logger.groupCollapsed(`View the final response here.`); + logger.log(response || '[No response returned]'); + logger.groupEnd(); + } + } + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * An implementation of a + * [network first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-first-falling-back-to-cache) + * request strategy. + * + * By default, this strategy will cache responses with a 200 status code as + * well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses). + * Opaque responses are are cross-origin requests where the response doesn't + * support [CORS](https://enable-cors.org/). + * + * If the network request fails, and there is no cache match, this will throw + * a `WorkboxError` exception. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-strategies + */ + class NetworkFirst extends Strategy { + /** + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) + * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) + * `fetch()` requests made by this strategy. + * @param {Object} [options.matchOptions] [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions) + * @param {number} [options.networkTimeoutSeconds] If set, any network requests + * that fail to respond within the timeout will fallback to the cache. + * + * This option can be used to combat + * "[lie-fi]{@link https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi}" + * scenarios. + */ + constructor(options = {}) { + super(options); + // If this instance contains no plugins with a 'cacheWillUpdate' callback, + // prepend the `cacheOkAndOpaquePlugin` plugin to the plugins list. + if (!this.plugins.some(p => 'cacheWillUpdate' in p)) { + this.plugins.unshift(cacheOkAndOpaquePlugin); + } + this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0; + { + if (this._networkTimeoutSeconds) { + finalAssertExports.isType(this._networkTimeoutSeconds, 'number', { + moduleName: 'workbox-strategies', + className: this.constructor.name, + funcName: 'constructor', + paramName: 'networkTimeoutSeconds' + }); + } + } + } + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request, handler) { + const logs = []; + { + finalAssertExports.isInstance(request, Request, { + moduleName: 'workbox-strategies', + className: this.constructor.name, + funcName: 'handle', + paramName: 'makeRequest' + }); + } + const promises = []; + let timeoutId; + if (this._networkTimeoutSeconds) { + const { + id, + promise + } = this._getTimeoutPromise({ + request, + logs, + handler + }); + timeoutId = id; + promises.push(promise); + } + const networkPromise = this._getNetworkPromise({ + timeoutId, + request, + logs, + handler + }); + promises.push(networkPromise); + const response = await handler.waitUntil((async () => { + // Promise.race() will resolve as soon as the first promise resolves. + return (await handler.waitUntil(Promise.race(promises))) || ( + // If Promise.race() resolved with null, it might be due to a network + // timeout + a cache miss. If that were to happen, we'd rather wait until + // the networkPromise resolves instead of returning null. + // Note that it's fine to await an already-resolved promise, so we don't + // have to check to see if it's still "in flight". + await networkPromise); + })()); + { + logger.groupCollapsed(messages.strategyStart(this.constructor.name, request)); + for (const log of logs) { + logger.log(log); + } + messages.printFinalResponse(response); + logger.groupEnd(); + } + if (!response) { + throw new WorkboxError('no-response', { + url: request.url + }); + } + return response; + } + /** + * @param {Object} options + * @param {Request} options.request + * @param {Array} options.logs A reference to the logs array + * @param {Event} options.event + * @return {Promise} + * + * @private + */ + _getTimeoutPromise({ + request, + logs, + handler + }) { + let timeoutId; + const timeoutPromise = new Promise(resolve => { + const onNetworkTimeout = async () => { + { + logs.push(`Timing out the network response at ` + `${this._networkTimeoutSeconds} seconds.`); + } + resolve(await handler.cacheMatch(request)); + }; + timeoutId = setTimeout(onNetworkTimeout, this._networkTimeoutSeconds * 1000); + }); + return { + promise: timeoutPromise, + id: timeoutId + }; + } + /** + * @param {Object} options + * @param {number|undefined} options.timeoutId + * @param {Request} options.request + * @param {Array} options.logs A reference to the logs Array. + * @param {Event} options.event + * @return {Promise} + * + * @private + */ + async _getNetworkPromise({ + timeoutId, + request, + logs, + handler + }) { + let error; + let response; + try { + response = await handler.fetchAndCachePut(request); + } catch (fetchError) { + if (fetchError instanceof Error) { + error = fetchError; + } + } + if (timeoutId) { + clearTimeout(timeoutId); + } + { + if (response) { + logs.push(`Got response from network.`); + } else { + logs.push(`Unable to get a response from the network. Will respond ` + `with a cached response.`); + } + } + if (error || !response) { + response = await handler.cacheMatch(request); + { + if (response) { + logs.push(`Found a cached response in the '${this.cacheName}'` + ` cache.`); + } else { + logs.push(`No response found in the '${this.cacheName}' cache.`); + } + } + } + return response; + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Claim any currently available clients once the service worker + * becomes active. This is normally used in conjunction with `skipWaiting()`. + * + * @memberof workbox-core + */ + function clientsClaim() { + self.addEventListener('activate', () => self.clients.claim()); + } + + /* + Copyright 2020 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A utility method that makes it easier to use `event.waitUntil` with + * async functions and return the result. + * + * @param {ExtendableEvent} event + * @param {Function} asyncFn + * @return {Function} + * @private + */ + function waitUntil(event, asyncFn) { + const returnPromise = asyncFn(); + event.waitUntil(returnPromise); + return returnPromise; + } + + // @ts-ignore + try { + self['workbox:precaching:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + // Name of the search parameter used to store revision info. + const REVISION_SEARCH_PARAM = '__WB_REVISION__'; + /** + * Converts a manifest entry into a versioned URL suitable for precaching. + * + * @param {Object|string} entry + * @return {string} A URL with versioning info. + * + * @private + * @memberof workbox-precaching + */ + function createCacheKey(entry) { + if (!entry) { + throw new WorkboxError('add-to-cache-list-unexpected-type', { + entry + }); + } + // If a precache manifest entry is a string, it's assumed to be a versioned + // URL, like '/app.abcd1234.js'. Return as-is. + if (typeof entry === 'string') { + const urlObject = new URL(entry, location.href); + return { + cacheKey: urlObject.href, + url: urlObject.href + }; + } + const { + revision, + url + } = entry; + if (!url) { + throw new WorkboxError('add-to-cache-list-unexpected-type', { + entry + }); + } + // If there's just a URL and no revision, then it's also assumed to be a + // versioned URL. + if (!revision) { + const urlObject = new URL(url, location.href); + return { + cacheKey: urlObject.href, + url: urlObject.href + }; + } + // Otherwise, construct a properly versioned URL using the custom Workbox + // search parameter along with the revision info. + const cacheKeyURL = new URL(url, location.href); + const originalURL = new URL(url, location.href); + cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision); + return { + cacheKey: cacheKeyURL.href, + url: originalURL.href + }; + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A plugin, designed to be used with PrecacheController, to determine the + * of assets that were updated (or not updated) during the install event. + * + * @private + */ + class PrecacheInstallReportPlugin { + constructor() { + this.updatedURLs = []; + this.notUpdatedURLs = []; + this.handlerWillStart = async ({ + request, + state + }) => { + // TODO: `state` should never be undefined... + if (state) { + state.originalRequest = request; + } + }; + this.cachedResponseWillBeUsed = async ({ + event, + state, + cachedResponse + }) => { + if (event.type === 'install') { + if (state && state.originalRequest && state.originalRequest instanceof Request) { + // TODO: `state` should never be undefined... + const url = state.originalRequest.url; + if (cachedResponse) { + this.notUpdatedURLs.push(url); + } else { + this.updatedURLs.push(url); + } + } + } + return cachedResponse; + }; + } + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A plugin, designed to be used with PrecacheController, to translate URLs into + * the corresponding cache key, based on the current revision info. + * + * @private + */ + class PrecacheCacheKeyPlugin { + constructor({ + precacheController + }) { + this.cacheKeyWillBeUsed = async ({ + request, + params + }) => { + // Params is type any, can't change right now. + /* eslint-disable */ + const cacheKey = (params === null || params === void 0 ? void 0 : params.cacheKey) || this._precacheController.getCacheKeyForURL(request.url); + /* eslint-enable */ + return cacheKey ? new Request(cacheKey, { + headers: request.headers + }) : request; + }; + this._precacheController = precacheController; + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * @param {string} groupTitle + * @param {Array} deletedURLs + * + * @private + */ + const logGroup = (groupTitle, deletedURLs) => { + logger.groupCollapsed(groupTitle); + for (const url of deletedURLs) { + logger.log(url); + } + logger.groupEnd(); + }; + /** + * @param {Array} deletedURLs + * + * @private + * @memberof workbox-precaching + */ + function printCleanupDetails(deletedURLs) { + const deletionCount = deletedURLs.length; + if (deletionCount > 0) { + logger.groupCollapsed(`During precaching cleanup, ` + `${deletionCount} cached ` + `request${deletionCount === 1 ? ' was' : 's were'} deleted.`); + logGroup('Deleted Cache Requests', deletedURLs); + logger.groupEnd(); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * @param {string} groupTitle + * @param {Array} urls + * + * @private + */ + function _nestedGroup(groupTitle, urls) { + if (urls.length === 0) { + return; + } + logger.groupCollapsed(groupTitle); + for (const url of urls) { + logger.log(url); + } + logger.groupEnd(); + } + /** + * @param {Array} urlsToPrecache + * @param {Array} urlsAlreadyPrecached + * + * @private + * @memberof workbox-precaching + */ + function printInstallDetails(urlsToPrecache, urlsAlreadyPrecached) { + const precachedCount = urlsToPrecache.length; + const alreadyPrecachedCount = urlsAlreadyPrecached.length; + if (precachedCount || alreadyPrecachedCount) { + let message = `Precaching ${precachedCount} file${precachedCount === 1 ? '' : 's'}.`; + if (alreadyPrecachedCount > 0) { + message += ` ${alreadyPrecachedCount} ` + `file${alreadyPrecachedCount === 1 ? ' is' : 's are'} already cached.`; + } + logger.groupCollapsed(message); + _nestedGroup(`View newly precached URLs.`, urlsToPrecache); + _nestedGroup(`View previously precached URLs.`, urlsAlreadyPrecached); + logger.groupEnd(); + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + let supportStatus; + /** + * A utility function that determines whether the current browser supports + * constructing a new `Response` from a `response.body` stream. + * + * @return {boolean} `true`, if the current browser can successfully + * construct a `Response` from a `response.body` stream, `false` otherwise. + * + * @private + */ + function canConstructResponseFromBodyStream() { + if (supportStatus === undefined) { + const testResponse = new Response(''); + if ('body' in testResponse) { + try { + new Response(testResponse.body); + supportStatus = true; + } catch (error) { + supportStatus = false; + } + } + supportStatus = false; + } + return supportStatus; + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Allows developers to copy a response and modify its `headers`, `status`, + * or `statusText` values (the values settable via a + * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax} + * object in the constructor). + * To modify these values, pass a function as the second argument. That + * function will be invoked with a single object with the response properties + * `{headers, status, statusText}`. The return value of this function will + * be used as the `ResponseInit` for the new `Response`. To change the values + * either modify the passed parameter(s) and return it, or return a totally + * new object. + * + * This method is intentionally limited to same-origin responses, regardless of + * whether CORS was used or not. + * + * @param {Response} response + * @param {Function} modifier + * @memberof workbox-core + */ + async function copyResponse(response, modifier) { + let origin = null; + // If response.url isn't set, assume it's cross-origin and keep origin null. + if (response.url) { + const responseURL = new URL(response.url); + origin = responseURL.origin; + } + if (origin !== self.location.origin) { + throw new WorkboxError('cross-origin-copy-response', { + origin + }); + } + const clonedResponse = response.clone(); + // Create a fresh `ResponseInit` object by cloning the headers. + const responseInit = { + headers: new Headers(clonedResponse.headers), + status: clonedResponse.status, + statusText: clonedResponse.statusText + }; + // Apply any user modifications. + const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit; + // Create the new response from the body stream and `ResponseInit` + // modifications. Note: not all browsers support the Response.body stream, + // so fall back to reading the entire body into memory as a blob. + const body = canConstructResponseFromBodyStream() ? clonedResponse.body : await clonedResponse.blob(); + return new Response(body, modifiedResponseInit); + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A {@link workbox-strategies.Strategy} implementation + * specifically designed to work with + * {@link workbox-precaching.PrecacheController} + * to both cache and fetch precached assets. + * + * Note: an instance of this class is created automatically when creating a + * `PrecacheController`; it's generally not necessary to create this yourself. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-precaching + */ + class PrecacheStrategy extends Strategy { + /** + * + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] {@link https://developers.google.com/web/tools/workbox/guides/using-plugins|Plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init} + * of all fetch() requests made by this strategy. + * @param {Object} [options.matchOptions] The + * {@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions|CacheQueryOptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to + * get the response from the network if there's a precache miss. + */ + constructor(options = {}) { + options.cacheName = cacheNames.getPrecacheName(options.cacheName); + super(options); + this._fallbackToNetwork = options.fallbackToNetwork === false ? false : true; + // Redirected responses cannot be used to satisfy a navigation request, so + // any redirected response must be "copied" rather than cloned, so the new + // response doesn't contain the `redirected` flag. See: + // https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1 + this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin); + } + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request, handler) { + const response = await handler.cacheMatch(request); + if (response) { + return response; + } + // If this is an `install` event for an entry that isn't already cached, + // then populate the cache. + if (handler.event && handler.event.type === 'install') { + return await this._handleInstall(request, handler); + } + // Getting here means something went wrong. An entry that should have been + // precached wasn't found in the cache. + return await this._handleFetch(request, handler); + } + async _handleFetch(request, handler) { + let response; + const params = handler.params || {}; + // Fall back to the network if we're configured to do so. + if (this._fallbackToNetwork) { + { + logger.warn(`The precached response for ` + `${getFriendlyURL(request.url)} in ${this.cacheName} was not ` + `found. Falling back to the network.`); + } + const integrityInManifest = params.integrity; + const integrityInRequest = request.integrity; + const noIntegrityConflict = !integrityInRequest || integrityInRequest === integrityInManifest; + // Do not add integrity if the original request is no-cors + // See https://github.com/GoogleChrome/workbox/issues/3096 + response = await handler.fetch(new Request(request, { + integrity: request.mode !== 'no-cors' ? integrityInRequest || integrityInManifest : undefined + })); + // It's only "safe" to repair the cache if we're using SRI to guarantee + // that the response matches the precache manifest's expectations, + // and there's either a) no integrity property in the incoming request + // or b) there is an integrity, and it matches the precache manifest. + // See https://github.com/GoogleChrome/workbox/issues/2858 + // Also if the original request users no-cors we don't use integrity. + // See https://github.com/GoogleChrome/workbox/issues/3096 + if (integrityInManifest && noIntegrityConflict && request.mode !== 'no-cors') { + this._useDefaultCacheabilityPluginIfNeeded(); + const wasCached = await handler.cachePut(request, response.clone()); + { + if (wasCached) { + logger.log(`A response for ${getFriendlyURL(request.url)} ` + `was used to "repair" the precache.`); + } + } + } + } else { + // This shouldn't normally happen, but there are edge cases: + // https://github.com/GoogleChrome/workbox/issues/1441 + throw new WorkboxError('missing-precache-entry', { + cacheName: this.cacheName, + url: request.url + }); + } + { + const cacheKey = params.cacheKey || (await handler.getCacheKey(request, 'read')); + // Workbox is going to handle the route. + // print the routing details to the console. + logger.groupCollapsed(`Precaching is responding to: ` + getFriendlyURL(request.url)); + logger.log(`Serving the precached url: ${getFriendlyURL(cacheKey instanceof Request ? cacheKey.url : cacheKey)}`); + logger.groupCollapsed(`View request details here.`); + logger.log(request); + logger.groupEnd(); + logger.groupCollapsed(`View response details here.`); + logger.log(response); + logger.groupEnd(); + logger.groupEnd(); + } + return response; + } + async _handleInstall(request, handler) { + this._useDefaultCacheabilityPluginIfNeeded(); + const response = await handler.fetch(request); + // Make sure we defer cachePut() until after we know the response + // should be cached; see https://github.com/GoogleChrome/workbox/issues/2737 + const wasCached = await handler.cachePut(request, response.clone()); + if (!wasCached) { + // Throwing here will lead to the `install` handler failing, which + // we want to do if *any* of the responses aren't safe to cache. + throw new WorkboxError('bad-precaching-response', { + url: request.url, + status: response.status + }); + } + return response; + } + /** + * This method is complex, as there a number of things to account for: + * + * The `plugins` array can be set at construction, and/or it might be added to + * to at any time before the strategy is used. + * + * At the time the strategy is used (i.e. during an `install` event), there + * needs to be at least one plugin that implements `cacheWillUpdate` in the + * array, other than `copyRedirectedCacheableResponsesPlugin`. + * + * - If this method is called and there are no suitable `cacheWillUpdate` + * plugins, we need to add `defaultPrecacheCacheabilityPlugin`. + * + * - If this method is called and there is exactly one `cacheWillUpdate`, then + * we don't have to do anything (this might be a previously added + * `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin). + * + * - If this method is called and there is more than one `cacheWillUpdate`, + * then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so, + * we need to remove it. (This situation is unlikely, but it could happen if + * the strategy is used multiple times, the first without a `cacheWillUpdate`, + * and then later on after manually adding a custom `cacheWillUpdate`.) + * + * See https://github.com/GoogleChrome/workbox/issues/2737 for more context. + * + * @private + */ + _useDefaultCacheabilityPluginIfNeeded() { + let defaultPluginIndex = null; + let cacheWillUpdatePluginCount = 0; + for (const [index, plugin] of this.plugins.entries()) { + // Ignore the copy redirected plugin when determining what to do. + if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) { + continue; + } + // Save the default plugin's index, in case it needs to be removed. + if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) { + defaultPluginIndex = index; + } + if (plugin.cacheWillUpdate) { + cacheWillUpdatePluginCount++; + } + } + if (cacheWillUpdatePluginCount === 0) { + this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin); + } else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) { + // Only remove the default plugin; multiple custom plugins are allowed. + this.plugins.splice(defaultPluginIndex, 1); + } + // Nothing needs to be done if cacheWillUpdatePluginCount is 1 + } + } + PrecacheStrategy.defaultPrecacheCacheabilityPlugin = { + async cacheWillUpdate({ + response + }) { + if (!response || response.status >= 400) { + return null; + } + return response; + } + }; + PrecacheStrategy.copyRedirectedCacheableResponsesPlugin = { + async cacheWillUpdate({ + response + }) { + return response.redirected ? await copyResponse(response) : response; + } + }; + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Performs efficient precaching of assets. + * + * @memberof workbox-precaching + */ + class PrecacheController { + /** + * Create a new PrecacheController. + * + * @param {Object} [options] + * @param {string} [options.cacheName] The cache to use for precaching. + * @param {string} [options.plugins] Plugins to use when precaching as well + * as responding to fetch events for precached assets. + * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to + * get the response from the network if there's a precache miss. + */ + constructor({ + cacheName, + plugins = [], + fallbackToNetwork = true + } = {}) { + this._urlsToCacheKeys = new Map(); + this._urlsToCacheModes = new Map(); + this._cacheKeysToIntegrities = new Map(); + this._strategy = new PrecacheStrategy({ + cacheName: cacheNames.getPrecacheName(cacheName), + plugins: [...plugins, new PrecacheCacheKeyPlugin({ + precacheController: this + })], + fallbackToNetwork + }); + // Bind the install and activate methods to the instance. + this.install = this.install.bind(this); + this.activate = this.activate.bind(this); + } + /** + * @type {workbox-precaching.PrecacheStrategy} The strategy created by this controller and + * used to cache assets and respond to fetch events. + */ + get strategy() { + return this._strategy; + } + /** + * Adds items to the precache list, removing any duplicates and + * stores the files in the + * {@link workbox-core.cacheNames|"precache cache"} when the service + * worker installs. + * + * This method can be called multiple times. + * + * @param {Array} [entries=[]] Array of entries to precache. + */ + precache(entries) { + this.addToCacheList(entries); + if (!this._installAndActiveListenersAdded) { + self.addEventListener('install', this.install); + self.addEventListener('activate', this.activate); + this._installAndActiveListenersAdded = true; + } + } + /** + * This method will add items to the precache list, removing duplicates + * and ensuring the information is valid. + * + * @param {Array} entries + * Array of entries to precache. + */ + addToCacheList(entries) { + { + finalAssertExports.isArray(entries, { + moduleName: 'workbox-precaching', + className: 'PrecacheController', + funcName: 'addToCacheList', + paramName: 'entries' + }); + } + const urlsToWarnAbout = []; + for (const entry of entries) { + // See https://github.com/GoogleChrome/workbox/issues/2259 + if (typeof entry === 'string') { + urlsToWarnAbout.push(entry); + } else if (entry && entry.revision === undefined) { + urlsToWarnAbout.push(entry.url); + } + const { + cacheKey, + url + } = createCacheKey(entry); + const cacheMode = typeof entry !== 'string' && entry.revision ? 'reload' : 'default'; + if (this._urlsToCacheKeys.has(url) && this._urlsToCacheKeys.get(url) !== cacheKey) { + throw new WorkboxError('add-to-cache-list-conflicting-entries', { + firstEntry: this._urlsToCacheKeys.get(url), + secondEntry: cacheKey + }); + } + if (typeof entry !== 'string' && entry.integrity) { + if (this._cacheKeysToIntegrities.has(cacheKey) && this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) { + throw new WorkboxError('add-to-cache-list-conflicting-integrities', { + url + }); + } + this._cacheKeysToIntegrities.set(cacheKey, entry.integrity); + } + this._urlsToCacheKeys.set(url, cacheKey); + this._urlsToCacheModes.set(url, cacheMode); + if (urlsToWarnAbout.length > 0) { + const warningMessage = `Workbox is precaching URLs without revision ` + `info: ${urlsToWarnAbout.join(', ')}\nThis is generally NOT safe. ` + `Learn more at https://bit.ly/wb-precache`; + { + logger.warn(warningMessage); + } + } + } + } + /** + * Precaches new and updated assets. Call this method from the service worker + * install event. + * + * Note: this method calls `event.waitUntil()` for you, so you do not need + * to call it yourself in your event handlers. + * + * @param {ExtendableEvent} event + * @return {Promise} + */ + install(event) { + // waitUntil returns Promise + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return waitUntil(event, async () => { + const installReportPlugin = new PrecacheInstallReportPlugin(); + this.strategy.plugins.push(installReportPlugin); + // Cache entries one at a time. + // See https://github.com/GoogleChrome/workbox/issues/2528 + for (const [url, cacheKey] of this._urlsToCacheKeys) { + const integrity = this._cacheKeysToIntegrities.get(cacheKey); + const cacheMode = this._urlsToCacheModes.get(url); + const request = new Request(url, { + integrity, + cache: cacheMode, + credentials: 'same-origin' + }); + await Promise.all(this.strategy.handleAll({ + params: { + cacheKey + }, + request, + event + })); + } + const { + updatedURLs, + notUpdatedURLs + } = installReportPlugin; + { + printInstallDetails(updatedURLs, notUpdatedURLs); + } + return { + updatedURLs, + notUpdatedURLs + }; + }); + } + /** + * Deletes assets that are no longer present in the current precache manifest. + * Call this method from the service worker activate event. + * + * Note: this method calls `event.waitUntil()` for you, so you do not need + * to call it yourself in your event handlers. + * + * @param {ExtendableEvent} event + * @return {Promise} + */ + activate(event) { + // waitUntil returns Promise + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return waitUntil(event, async () => { + const cache = await self.caches.open(this.strategy.cacheName); + const currentlyCachedRequests = await cache.keys(); + const expectedCacheKeys = new Set(this._urlsToCacheKeys.values()); + const deletedURLs = []; + for (const request of currentlyCachedRequests) { + if (!expectedCacheKeys.has(request.url)) { + await cache.delete(request); + deletedURLs.push(request.url); + } + } + { + printCleanupDetails(deletedURLs); + } + return { + deletedURLs + }; + }); + } + /** + * Returns a mapping of a precached URL to the corresponding cache key, taking + * into account the revision information for the URL. + * + * @return {Map} A URL to cache key mapping. + */ + getURLsToCacheKeys() { + return this._urlsToCacheKeys; + } + /** + * Returns a list of all the URLs that have been precached by the current + * service worker. + * + * @return {Array} The precached URLs. + */ + getCachedURLs() { + return [...this._urlsToCacheKeys.keys()]; + } + /** + * Returns the cache key used for storing a given URL. If that URL is + * unversioned, like `/index.html', then the cache key will be the original + * URL with a search parameter appended to it. + * + * @param {string} url A URL whose cache key you want to look up. + * @return {string} The versioned URL that corresponds to a cache key + * for the original URL, or undefined if that URL isn't precached. + */ + getCacheKeyForURL(url) { + const urlObject = new URL(url, location.href); + return this._urlsToCacheKeys.get(urlObject.href); + } + /** + * @param {string} url A cache key whose SRI you want to look up. + * @return {string} The subresource integrity associated with the cache key, + * or undefined if it's not set. + */ + getIntegrityForCacheKey(cacheKey) { + return this._cacheKeysToIntegrities.get(cacheKey); + } + /** + * This acts as a drop-in replacement for + * [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match) + * with the following differences: + * + * - It knows what the name of the precache is, and only checks in that cache. + * - It allows you to pass in an "original" URL without versioning parameters, + * and it will automatically look up the correct cache key for the currently + * active revision of that URL. + * + * E.g., `matchPrecache('index.html')` will find the correct precached + * response for the currently active service worker, even if the actual cache + * key is `'/index.html?__WB_REVISION__=1234abcd'`. + * + * @param {string|Request} request The key (without revisioning parameters) + * to look up in the precache. + * @return {Promise} + */ + async matchPrecache(request) { + const url = request instanceof Request ? request.url : request; + const cacheKey = this.getCacheKeyForURL(url); + if (cacheKey) { + const cache = await self.caches.open(this.strategy.cacheName); + return cache.match(cacheKey); + } + return undefined; + } + /** + * Returns a function that looks up `url` in the precache (taking into + * account revision information), and returns the corresponding `Response`. + * + * @param {string} url The precached URL which will be used to lookup the + * `Response`. + * @return {workbox-routing~handlerCallback} + */ + createHandlerBoundToURL(url) { + const cacheKey = this.getCacheKeyForURL(url); + if (!cacheKey) { + throw new WorkboxError('non-precached-url', { + url + }); + } + return options => { + options.request = new Request(url); + options.params = Object.assign({ + cacheKey + }, options.params); + return this.strategy.handle(options); + }; + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + let precacheController; + /** + * @return {PrecacheController} + * @private + */ + const getOrCreatePrecacheController = () => { + if (!precacheController) { + precacheController = new PrecacheController(); + } + return precacheController; + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Removes any URL search parameters that should be ignored. + * + * @param {URL} urlObject The original URL. + * @param {Array} ignoreURLParametersMatching RegExps to test against + * each search parameter name. Matches mean that the search parameter should be + * ignored. + * @return {URL} The URL with any ignored search parameters removed. + * + * @private + * @memberof workbox-precaching + */ + function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) { + // Convert the iterable into an array at the start of the loop to make sure + // deletion doesn't mess up iteration. + for (const paramName of [...urlObject.searchParams.keys()]) { + if (ignoreURLParametersMatching.some(regExp => regExp.test(paramName))) { + urlObject.searchParams.delete(paramName); + } + } + return urlObject; + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Generator function that yields possible variations on the original URL to + * check, one at a time. + * + * @param {string} url + * @param {Object} options + * + * @private + * @memberof workbox-precaching + */ + function* generateURLVariations(url, { + ignoreURLParametersMatching = [/^utm_/, /^fbclid$/], + directoryIndex = 'index.html', + cleanURLs = true, + urlManipulation + } = {}) { + const urlObject = new URL(url, location.href); + urlObject.hash = ''; + yield urlObject.href; + const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching); + yield urlWithoutIgnoredParams.href; + if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) { + const directoryURL = new URL(urlWithoutIgnoredParams.href); + directoryURL.pathname += directoryIndex; + yield directoryURL.href; + } + if (cleanURLs) { + const cleanURL = new URL(urlWithoutIgnoredParams.href); + cleanURL.pathname += '.html'; + yield cleanURL.href; + } + if (urlManipulation) { + const additionalURLs = urlManipulation({ + url: urlObject + }); + for (const urlToAttempt of additionalURLs) { + yield urlToAttempt.href; + } + } + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A subclass of {@link workbox-routing.Route} that takes a + * {@link workbox-precaching.PrecacheController} + * instance and uses it to match incoming requests and handle fetching + * responses from the precache. + * + * @memberof workbox-precaching + * @extends workbox-routing.Route + */ + class PrecacheRoute extends Route { + /** + * @param {PrecacheController} precacheController A `PrecacheController` + * instance used to both match requests and respond to fetch events. + * @param {Object} [options] Options to control how requests are matched + * against the list of precached URLs. + * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will + * check cache entries for a URLs ending with '/' to see if there is a hit when + * appending the `directoryIndex` value. + * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An + * array of regex's to remove search params when looking for a cache match. + * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will + * check the cache for the URL with a `.html` added to the end of the end. + * @param {workbox-precaching~urlManipulation} [options.urlManipulation] + * This is a function that should take a URL and return an array of + * alternative URLs that should be checked for precache matches. + */ + constructor(precacheController, options) { + const match = ({ + request + }) => { + const urlsToCacheKeys = precacheController.getURLsToCacheKeys(); + for (const possibleURL of generateURLVariations(request.url, options)) { + const cacheKey = urlsToCacheKeys.get(possibleURL); + if (cacheKey) { + const integrity = precacheController.getIntegrityForCacheKey(cacheKey); + return { + cacheKey, + integrity + }; + } + } + { + logger.debug(`Precaching did not find a match for ` + getFriendlyURL(request.url)); + } + return; + }; + super(match, precacheController.strategy); + } + } + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Add a `fetch` listener to the service worker that will + * respond to + * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests} + * with precached assets. + * + * Requests for assets that aren't precached, the `FetchEvent` will not be + * responded to, allowing the event to fall through to other `fetch` event + * listeners. + * + * @param {Object} [options] See the {@link workbox-precaching.PrecacheRoute} + * options. + * + * @memberof workbox-precaching + */ + function addRoute(options) { + const precacheController = getOrCreatePrecacheController(); + const precacheRoute = new PrecacheRoute(precacheController, options); + registerRoute(precacheRoute); + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Adds items to the precache list, removing any duplicates and + * stores the files in the + * {@link workbox-core.cacheNames|"precache cache"} when the service + * worker installs. + * + * This method can be called multiple times. + * + * Please note: This method **will not** serve any of the cached files for you. + * It only precaches files. To respond to a network request you call + * {@link workbox-precaching.addRoute}. + * + * If you have a single array of files to precache, you can just call + * {@link workbox-precaching.precacheAndRoute}. + * + * @param {Array} [entries=[]] Array of entries to precache. + * + * @memberof workbox-precaching + */ + function precache(entries) { + const precacheController = getOrCreatePrecacheController(); + precacheController.precache(entries); + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * This method will add entries to the precache list and add a route to + * respond to fetch events. + * + * This is a convenience method that will call + * {@link workbox-precaching.precache} and + * {@link workbox-precaching.addRoute} in a single call. + * + * @param {Array} entries Array of entries to precache. + * @param {Object} [options] See the + * {@link workbox-precaching.PrecacheRoute} options. + * + * @memberof workbox-precaching + */ + function precacheAndRoute(entries, options) { + precache(entries); + addRoute(options); + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const SUBSTRING_TO_FIND = '-precache-'; + /** + * Cleans up incompatible precaches that were created by older versions of + * Workbox, by a service worker registered under the current scope. + * + * This is meant to be called as part of the `activate` event. + * + * This should be safe to use as long as you don't include `substringToFind` + * (defaulting to `-precache-`) in your non-precache cache names. + * + * @param {string} currentPrecacheName The cache name currently in use for + * precaching. This cache won't be deleted. + * @param {string} [substringToFind='-precache-'] Cache names which include this + * substring will be deleted (excluding `currentPrecacheName`). + * @return {Array} A list of all the cache names that were deleted. + * + * @private + * @memberof workbox-precaching + */ + const deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBSTRING_TO_FIND) => { + const cacheNames = await self.caches.keys(); + const cacheNamesToDelete = cacheNames.filter(cacheName => { + return cacheName.includes(substringToFind) && cacheName.includes(self.registration.scope) && cacheName !== currentPrecacheName; + }); + await Promise.all(cacheNamesToDelete.map(cacheName => self.caches.delete(cacheName))); + return cacheNamesToDelete; + }; + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Adds an `activate` event listener which will clean up incompatible + * precaches that were created by older versions of Workbox. + * + * @memberof workbox-precaching + */ + function cleanupOutdatedCaches() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('activate', event => { + const cacheName = cacheNames.getPrecacheName(); + event.waitUntil(deleteOutdatedCaches(cacheName).then(cachesDeleted => { + { + if (cachesDeleted.length > 0) { + logger.log(`The following out-of-date precaches were cleaned up ` + `automatically:`, cachesDeleted); + } + } + })); + }); + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * NavigationRoute makes it easy to create a + * {@link workbox-routing.Route} that matches for browser + * [navigation requests]{@link https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests}. + * + * It will only match incoming Requests whose + * {@link https://fetch.spec.whatwg.org/#concept-request-mode|mode} + * is set to `navigate`. + * + * You can optionally only apply this route to a subset of navigation requests + * by using one or both of the `denylist` and `allowlist` parameters. + * + * @memberof workbox-routing + * @extends workbox-routing.Route + */ + class NavigationRoute extends Route { + /** + * If both `denylist` and `allowlist` are provided, the `denylist` will + * take precedence and the request will not match this route. + * + * The regular expressions in `allowlist` and `denylist` + * are matched against the concatenated + * [`pathname`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname} + * and [`search`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search} + * portions of the requested URL. + * + * *Note*: These RegExps may be evaluated against every destination URL during + * a navigation. Avoid using + * [complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077), + * or else your users may see delays when navigating your site. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {Object} options + * @param {Array} [options.denylist] If any of these patterns match, + * the route will not handle the request (even if a allowlist RegExp matches). + * @param {Array} [options.allowlist=[/./]] If any of these patterns + * match the URL's pathname and search parameter, the route will handle the + * request (assuming the denylist doesn't match). + */ + constructor(handler, { + allowlist = [/./], + denylist = [] + } = {}) { + { + finalAssertExports.isArrayOfClass(allowlist, RegExp, { + moduleName: 'workbox-routing', + className: 'NavigationRoute', + funcName: 'constructor', + paramName: 'options.allowlist' + }); + finalAssertExports.isArrayOfClass(denylist, RegExp, { + moduleName: 'workbox-routing', + className: 'NavigationRoute', + funcName: 'constructor', + paramName: 'options.denylist' + }); + } + super(options => this._match(options), handler); + this._allowlist = allowlist; + this._denylist = denylist; + } + /** + * Routes match handler. + * + * @param {Object} options + * @param {URL} options.url + * @param {Request} options.request + * @return {boolean} + * + * @private + */ + _match({ + url, + request + }) { + if (request && request.mode !== 'navigate') { + return false; + } + const pathnameAndSearch = url.pathname + url.search; + for (const regExp of this._denylist) { + if (regExp.test(pathnameAndSearch)) { + { + logger.log(`The navigation route ${pathnameAndSearch} is not ` + `being used, since the URL matches this denylist pattern: ` + `${regExp.toString()}`); + } + return false; + } + } + if (this._allowlist.some(regExp => regExp.test(pathnameAndSearch))) { + { + logger.debug(`The navigation route ${pathnameAndSearch} ` + `is being used.`); + } + return true; + } + { + logger.log(`The navigation route ${pathnameAndSearch} is not ` + `being used, since the URL being navigated to doesn't ` + `match the allowlist.`); + } + return false; + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Helper function that calls + * {@link PrecacheController#createHandlerBoundToURL} on the default + * {@link PrecacheController} instance. + * + * If you are creating your own {@link PrecacheController}, then call the + * {@link PrecacheController#createHandlerBoundToURL} on that instance, + * instead of using this function. + * + * @param {string} url The precached URL which will be used to lookup the + * `Response`. + * @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the + * response from the network if there's a precache miss. + * @return {workbox-routing~handlerCallback} + * + * @memberof workbox-precaching + */ + function createHandlerBoundToURL(url) { + const precacheController = getOrCreatePrecacheController(); + return precacheController.createHandlerBoundToURL(url); + } + + exports.CacheableResponsePlugin = CacheableResponsePlugin; + exports.ExpirationPlugin = ExpirationPlugin; + exports.NavigationRoute = NavigationRoute; + exports.NetworkFirst = NetworkFirst; + exports.cleanupOutdatedCaches = cleanupOutdatedCaches; + exports.clientsClaim = clientsClaim; + exports.createHandlerBoundToURL = createHandlerBoundToURL; + exports.precacheAndRoute = precacheAndRoute; + exports.registerRoute = registerRoute; + +})); +//# sourceMappingURL=workbox-e755d862.js.map diff --git a/dev-dist/workbox-e755d862.js.map b/dev-dist/workbox-e755d862.js.map new file mode 100644 index 0000000..d38d3a2 --- /dev/null +++ b/dev-dist/workbox-e755d862.js.map @@ -0,0 +1 @@ +{"version":3,"file":"workbox-e755d862.js","sources":["node_modules/workbox-core/_version.js","node_modules/workbox-core/_private/logger.js","node_modules/workbox-core/models/messages/messages.js","node_modules/workbox-core/models/messages/messageGenerator.js","node_modules/workbox-core/_private/WorkboxError.js","node_modules/workbox-core/_private/assert.js","node_modules/workbox-routing/_version.js","node_modules/workbox-routing/utils/constants.js","node_modules/workbox-routing/utils/normalizeHandler.js","node_modules/workbox-routing/Route.js","node_modules/workbox-routing/RegExpRoute.js","node_modules/workbox-core/_private/getFriendlyURL.js","node_modules/workbox-routing/Router.js","node_modules/workbox-routing/utils/getOrCreateDefaultRouter.js","node_modules/workbox-routing/registerRoute.js","node_modules/workbox-core/_private/cacheNames.js","node_modules/workbox-core/_private/dontWaitFor.js","node_modules/workbox-core/models/quotaErrorCallbacks.js","node_modules/workbox-core/registerQuotaErrorCallback.js","node_modules/idb/build/wrap-idb-value.js","node_modules/idb/build/index.js","node_modules/workbox-expiration/_version.js","node_modules/workbox-expiration/models/CacheTimestampsModel.js","node_modules/workbox-expiration/CacheExpiration.js","node_modules/workbox-expiration/ExpirationPlugin.js","node_modules/workbox-cacheable-response/_version.js","node_modules/workbox-cacheable-response/CacheableResponse.js","node_modules/workbox-cacheable-response/CacheableResponsePlugin.js","node_modules/workbox-strategies/_version.js","node_modules/workbox-strategies/plugins/cacheOkAndOpaquePlugin.js","node_modules/workbox-core/_private/cacheMatchIgnoreParams.js","node_modules/workbox-core/_private/Deferred.js","node_modules/workbox-core/_private/executeQuotaErrorCallbacks.js","node_modules/workbox-core/_private/timeout.js","node_modules/workbox-strategies/StrategyHandler.js","node_modules/workbox-strategies/Strategy.js","node_modules/workbox-strategies/utils/messages.js","node_modules/workbox-strategies/NetworkFirst.js","node_modules/workbox-core/clientsClaim.js","node_modules/workbox-core/_private/waitUntil.js","node_modules/workbox-precaching/_version.js","node_modules/workbox-precaching/utils/createCacheKey.js","node_modules/workbox-precaching/utils/PrecacheInstallReportPlugin.js","node_modules/workbox-precaching/utils/PrecacheCacheKeyPlugin.js","node_modules/workbox-precaching/utils/printCleanupDetails.js","node_modules/workbox-precaching/utils/printInstallDetails.js","node_modules/workbox-core/_private/canConstructResponseFromBodyStream.js","node_modules/workbox-core/copyResponse.js","node_modules/workbox-precaching/PrecacheStrategy.js","node_modules/workbox-precaching/PrecacheController.js","node_modules/workbox-precaching/utils/getOrCreatePrecacheController.js","node_modules/workbox-precaching/utils/removeIgnoredSearchParams.js","node_modules/workbox-precaching/utils/generateURLVariations.js","node_modules/workbox-precaching/PrecacheRoute.js","node_modules/workbox-precaching/addRoute.js","node_modules/workbox-precaching/precache.js","node_modules/workbox-precaching/precacheAndRoute.js","node_modules/workbox-precaching/utils/deleteOutdatedCaches.js","node_modules/workbox-precaching/cleanupOutdatedCaches.js","node_modules/workbox-routing/NavigationRoute.js","node_modules/workbox-precaching/createHandlerBoundToURL.js"],"sourcesContent":["\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:core:7.2.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst logger = (process.env.NODE_ENV === 'production'\n ? null\n : (() => {\n // Don't overwrite this value if it's already set.\n // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923\n if (!('__WB_DISABLE_DEV_LOGS' in globalThis)) {\n self.__WB_DISABLE_DEV_LOGS = false;\n }\n let inGroup = false;\n const methodToColorMap = {\n debug: `#7f8c8d`,\n log: `#2ecc71`,\n warn: `#f39c12`,\n error: `#c0392b`,\n groupCollapsed: `#3498db`,\n groupEnd: null, // No colored prefix on groupEnd\n };\n const print = function (method, args) {\n if (self.__WB_DISABLE_DEV_LOGS) {\n return;\n }\n if (method === 'groupCollapsed') {\n // Safari doesn't print all console.groupCollapsed() arguments:\n // https://bugs.webkit.org/show_bug.cgi?id=182754\n if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {\n console[method](...args);\n return;\n }\n }\n const styles = [\n `background: ${methodToColorMap[method]}`,\n `border-radius: 0.5em`,\n `color: white`,\n `font-weight: bold`,\n `padding: 2px 0.5em`,\n ];\n // When in a group, the workbox prefix is not displayed.\n const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')];\n console[method](...logPrefix, ...args);\n if (method === 'groupCollapsed') {\n inGroup = true;\n }\n if (method === 'groupEnd') {\n inGroup = false;\n }\n };\n // eslint-disable-next-line @typescript-eslint/ban-types\n const api = {};\n const loggerMethods = Object.keys(methodToColorMap);\n for (const key of loggerMethods) {\n const method = key;\n api[method] = (...args) => {\n print(method, args);\n };\n }\n return api;\n })());\nexport { logger };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../../_version.js';\nexport const messages = {\n 'invalid-value': ({ paramName, validValueDescription, value }) => {\n if (!paramName || !validValueDescription) {\n throw new Error(`Unexpected input to 'invalid-value' error.`);\n }\n return (`The '${paramName}' parameter was given a value with an ` +\n `unexpected value. ${validValueDescription} Received a value of ` +\n `${JSON.stringify(value)}.`);\n },\n 'not-an-array': ({ moduleName, className, funcName, paramName }) => {\n if (!moduleName || !className || !funcName || !paramName) {\n throw new Error(`Unexpected input to 'not-an-array' error.`);\n }\n return (`The parameter '${paramName}' passed into ` +\n `'${moduleName}.${className}.${funcName}()' must be an array.`);\n },\n 'incorrect-type': ({ expectedType, paramName, moduleName, className, funcName, }) => {\n if (!expectedType || !paramName || !moduleName || !funcName) {\n throw new Error(`Unexpected input to 'incorrect-type' error.`);\n }\n const classNameStr = className ? `${className}.` : '';\n return (`The parameter '${paramName}' passed into ` +\n `'${moduleName}.${classNameStr}` +\n `${funcName}()' must be of type ${expectedType}.`);\n },\n 'incorrect-class': ({ expectedClassName, paramName, moduleName, className, funcName, isReturnValueProblem, }) => {\n if (!expectedClassName || !moduleName || !funcName) {\n throw new Error(`Unexpected input to 'incorrect-class' error.`);\n }\n const classNameStr = className ? `${className}.` : '';\n if (isReturnValueProblem) {\n return (`The return value from ` +\n `'${moduleName}.${classNameStr}${funcName}()' ` +\n `must be an instance of class ${expectedClassName}.`);\n }\n return (`The parameter '${paramName}' passed into ` +\n `'${moduleName}.${classNameStr}${funcName}()' ` +\n `must be an instance of class ${expectedClassName}.`);\n },\n 'missing-a-method': ({ expectedMethod, paramName, moduleName, className, funcName, }) => {\n if (!expectedMethod ||\n !paramName ||\n !moduleName ||\n !className ||\n !funcName) {\n throw new Error(`Unexpected input to 'missing-a-method' error.`);\n }\n return (`${moduleName}.${className}.${funcName}() expected the ` +\n `'${paramName}' parameter to expose a '${expectedMethod}' method.`);\n },\n 'add-to-cache-list-unexpected-type': ({ entry }) => {\n return (`An unexpected entry was passed to ` +\n `'workbox-precaching.PrecacheController.addToCacheList()' The entry ` +\n `'${JSON.stringify(entry)}' isn't supported. You must supply an array of ` +\n `strings with one or more characters, objects with a url property or ` +\n `Request objects.`);\n },\n 'add-to-cache-list-conflicting-entries': ({ firstEntry, secondEntry }) => {\n if (!firstEntry || !secondEntry) {\n throw new Error(`Unexpected input to ` + `'add-to-cache-list-duplicate-entries' error.`);\n }\n return (`Two of the entries passed to ` +\n `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` +\n `${firstEntry} but different revision details. Workbox is ` +\n `unable to cache and version the asset correctly. Please remove one ` +\n `of the entries.`);\n },\n 'plugin-error-request-will-fetch': ({ thrownErrorMessage }) => {\n if (!thrownErrorMessage) {\n throw new Error(`Unexpected input to ` + `'plugin-error-request-will-fetch', error.`);\n }\n return (`An error was thrown by a plugins 'requestWillFetch()' method. ` +\n `The thrown error message was: '${thrownErrorMessage}'.`);\n },\n 'invalid-cache-name': ({ cacheNameId, value }) => {\n if (!cacheNameId) {\n throw new Error(`Expected a 'cacheNameId' for error 'invalid-cache-name'`);\n }\n return (`You must provide a name containing at least one character for ` +\n `setCacheDetails({${cacheNameId}: '...'}). Received a value of ` +\n `'${JSON.stringify(value)}'`);\n },\n 'unregister-route-but-not-found-with-method': ({ method }) => {\n if (!method) {\n throw new Error(`Unexpected input to ` +\n `'unregister-route-but-not-found-with-method' error.`);\n }\n return (`The route you're trying to unregister was not previously ` +\n `registered for the method type '${method}'.`);\n },\n 'unregister-route-route-not-registered': () => {\n return (`The route you're trying to unregister was not previously ` +\n `registered.`);\n },\n 'queue-replay-failed': ({ name }) => {\n return `Replaying the background sync queue '${name}' failed.`;\n },\n 'duplicate-queue-name': ({ name }) => {\n return (`The Queue name '${name}' is already being used. ` +\n `All instances of backgroundSync.Queue must be given unique names.`);\n },\n 'expired-test-without-max-age': ({ methodName, paramName }) => {\n return (`The '${methodName}()' method can only be used when the ` +\n `'${paramName}' is used in the constructor.`);\n },\n 'unsupported-route-type': ({ moduleName, className, funcName, paramName }) => {\n return (`The supplied '${paramName}' parameter was an unsupported type. ` +\n `Please check the docs for ${moduleName}.${className}.${funcName} for ` +\n `valid input types.`);\n },\n 'not-array-of-class': ({ value, expectedClass, moduleName, className, funcName, paramName, }) => {\n return (`The supplied '${paramName}' parameter must be an array of ` +\n `'${expectedClass}' objects. Received '${JSON.stringify(value)},'. ` +\n `Please check the call to ${moduleName}.${className}.${funcName}() ` +\n `to fix the issue.`);\n },\n 'max-entries-or-age-required': ({ moduleName, className, funcName }) => {\n return (`You must define either config.maxEntries or config.maxAgeSeconds` +\n `in ${moduleName}.${className}.${funcName}`);\n },\n 'statuses-or-headers-required': ({ moduleName, className, funcName }) => {\n return (`You must define either config.statuses or config.headers` +\n `in ${moduleName}.${className}.${funcName}`);\n },\n 'invalid-string': ({ moduleName, funcName, paramName }) => {\n if (!paramName || !moduleName || !funcName) {\n throw new Error(`Unexpected input to 'invalid-string' error.`);\n }\n return (`When using strings, the '${paramName}' parameter must start with ` +\n `'http' (for cross-origin matches) or '/' (for same-origin matches). ` +\n `Please see the docs for ${moduleName}.${funcName}() for ` +\n `more info.`);\n },\n 'channel-name-required': () => {\n return (`You must provide a channelName to construct a ` +\n `BroadcastCacheUpdate instance.`);\n },\n 'invalid-responses-are-same-args': () => {\n return (`The arguments passed into responsesAreSame() appear to be ` +\n `invalid. Please ensure valid Responses are used.`);\n },\n 'expire-custom-caches-only': () => {\n return (`You must provide a 'cacheName' property when using the ` +\n `expiration plugin with a runtime caching strategy.`);\n },\n 'unit-must-be-bytes': ({ normalizedRangeHeader }) => {\n if (!normalizedRangeHeader) {\n throw new Error(`Unexpected input to 'unit-must-be-bytes' error.`);\n }\n return (`The 'unit' portion of the Range header must be set to 'bytes'. ` +\n `The Range header provided was \"${normalizedRangeHeader}\"`);\n },\n 'single-range-only': ({ normalizedRangeHeader }) => {\n if (!normalizedRangeHeader) {\n throw new Error(`Unexpected input to 'single-range-only' error.`);\n }\n return (`Multiple ranges are not supported. Please use a single start ` +\n `value, and optional end value. The Range header provided was ` +\n `\"${normalizedRangeHeader}\"`);\n },\n 'invalid-range-values': ({ normalizedRangeHeader }) => {\n if (!normalizedRangeHeader) {\n throw new Error(`Unexpected input to 'invalid-range-values' error.`);\n }\n return (`The Range header is missing both start and end values. At least ` +\n `one of those values is needed. The Range header provided was ` +\n `\"${normalizedRangeHeader}\"`);\n },\n 'no-range-header': () => {\n return `No Range header was found in the Request provided.`;\n },\n 'range-not-satisfiable': ({ size, start, end }) => {\n return (`The start (${start}) and end (${end}) values in the Range are ` +\n `not satisfiable by the cached response, which is ${size} bytes.`);\n },\n 'attempt-to-cache-non-get-request': ({ url, method }) => {\n return (`Unable to cache '${url}' because it is a '${method}' request and ` +\n `only 'GET' requests can be cached.`);\n },\n 'cache-put-with-no-response': ({ url }) => {\n return (`There was an attempt to cache '${url}' but the response was not ` +\n `defined.`);\n },\n 'no-response': ({ url, error }) => {\n let message = `The strategy could not generate a response for '${url}'.`;\n if (error) {\n message += ` The underlying error is ${error}.`;\n }\n return message;\n },\n 'bad-precaching-response': ({ url, status }) => {\n return (`The precaching request for '${url}' failed` +\n (status ? ` with an HTTP status of ${status}.` : `.`));\n },\n 'non-precached-url': ({ url }) => {\n return (`createHandlerBoundToURL('${url}') was called, but that URL is ` +\n `not precached. Please pass in a URL that is precached instead.`);\n },\n 'add-to-cache-list-conflicting-integrities': ({ url }) => {\n return (`Two of the entries passed to ` +\n `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` +\n `${url} with different integrity values. Please remove one of them.`);\n },\n 'missing-precache-entry': ({ cacheName, url }) => {\n return `Unable to find a precached response in ${cacheName} for ${url}.`;\n },\n 'cross-origin-copy-response': ({ origin }) => {\n return (`workbox-core.copyResponse() can only be used with same-origin ` +\n `responses. It was passed a response with origin ${origin}.`);\n },\n 'opaque-streams-source': ({ type }) => {\n const message = `One of the workbox-streams sources resulted in an ` +\n `'${type}' response.`;\n if (type === 'opaqueredirect') {\n return (`${message} Please do not use a navigation request that results ` +\n `in a redirect as a source.`);\n }\n return `${message} Please ensure your sources are CORS-enabled.`;\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { messages } from './messages.js';\nimport '../../_version.js';\nconst fallback = (code, ...args) => {\n let msg = code;\n if (args.length > 0) {\n msg += ` :: ${JSON.stringify(args)}`;\n }\n return msg;\n};\nconst generatorFunction = (code, details = {}) => {\n const message = messages[code];\n if (!message) {\n throw new Error(`Unable to find message for code '${code}'.`);\n }\n return message(details);\n};\nexport const messageGenerator = process.env.NODE_ENV === 'production' ? fallback : generatorFunction;\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { messageGenerator } from '../models/messages/messageGenerator.js';\nimport '../_version.js';\n/**\n * Workbox errors should be thrown with this class.\n * This allows use to ensure the type easily in tests,\n * helps developers identify errors from workbox\n * easily and allows use to optimise error\n * messages correctly.\n *\n * @private\n */\nclass WorkboxError extends Error {\n /**\n *\n * @param {string} errorCode The error code that\n * identifies this particular error.\n * @param {Object=} details Any relevant arguments\n * that will help developers identify issues should\n * be added as a key on the context object.\n */\n constructor(errorCode, details) {\n const message = messageGenerator(errorCode, details);\n super(message);\n this.name = errorCode;\n this.details = details;\n }\n}\nexport { WorkboxError };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from '../_private/WorkboxError.js';\nimport '../_version.js';\n/*\n * This method throws if the supplied value is not an array.\n * The destructed values are required to produce a meaningful error for users.\n * The destructed and restructured object is so it's clear what is\n * needed.\n */\nconst isArray = (value, details) => {\n if (!Array.isArray(value)) {\n throw new WorkboxError('not-an-array', details);\n }\n};\nconst hasMethod = (object, expectedMethod, details) => {\n const type = typeof object[expectedMethod];\n if (type !== 'function') {\n details['expectedMethod'] = expectedMethod;\n throw new WorkboxError('missing-a-method', details);\n }\n};\nconst isType = (object, expectedType, details) => {\n if (typeof object !== expectedType) {\n details['expectedType'] = expectedType;\n throw new WorkboxError('incorrect-type', details);\n }\n};\nconst isInstance = (object, \n// Need the general type to do the check later.\n// eslint-disable-next-line @typescript-eslint/ban-types\nexpectedClass, details) => {\n if (!(object instanceof expectedClass)) {\n details['expectedClassName'] = expectedClass.name;\n throw new WorkboxError('incorrect-class', details);\n }\n};\nconst isOneOf = (value, validValues, details) => {\n if (!validValues.includes(value)) {\n details['validValueDescription'] = `Valid values are ${JSON.stringify(validValues)}.`;\n throw new WorkboxError('invalid-value', details);\n }\n};\nconst isArrayOfClass = (value, \n// Need general type to do check later.\nexpectedClass, // eslint-disable-line\ndetails) => {\n const error = new WorkboxError('not-array-of-class', details);\n if (!Array.isArray(value)) {\n throw error;\n }\n for (const item of value) {\n if (!(item instanceof expectedClass)) {\n throw error;\n }\n }\n};\nconst finalAssertExports = process.env.NODE_ENV === 'production'\n ? null\n : {\n hasMethod,\n isArray,\n isInstance,\n isOneOf,\n isType,\n isArrayOfClass,\n };\nexport { finalAssertExports as assert };\n","\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:routing:7.2.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * The default HTTP method, 'GET', used when there's no specific method\n * configured for a route.\n *\n * @type {string}\n *\n * @private\n */\nexport const defaultMethod = 'GET';\n/**\n * The list of valid HTTP methods associated with requests that could be routed.\n *\n * @type {Array}\n *\n * @private\n */\nexport const validMethods = [\n 'DELETE',\n 'GET',\n 'HEAD',\n 'PATCH',\n 'POST',\n 'PUT',\n];\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {function()|Object} handler Either a function, or an object with a\n * 'handle' method.\n * @return {Object} An object with a handle method.\n *\n * @private\n */\nexport const normalizeHandler = (handler) => {\n if (handler && typeof handler === 'object') {\n if (process.env.NODE_ENV !== 'production') {\n assert.hasMethod(handler, 'handle', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'handler',\n });\n }\n return handler;\n }\n else {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(handler, 'function', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'handler',\n });\n }\n return { handle: handler };\n }\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { defaultMethod, validMethods } from './utils/constants.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport './_version.js';\n/**\n * A `Route` consists of a pair of callback functions, \"match\" and \"handler\".\n * The \"match\" callback determine if a route should be used to \"handle\" a\n * request by returning a non-falsy value if it can. The \"handler\" callback\n * is called when there is a match and should return a Promise that resolves\n * to a `Response`.\n *\n * @memberof workbox-routing\n */\nclass Route {\n /**\n * Constructor for Route class.\n *\n * @param {workbox-routing~matchCallback} match\n * A callback function that determines whether the route matches a given\n * `fetch` event by returning a non-falsy value.\n * @param {workbox-routing~handlerCallback} handler A callback\n * function that returns a Promise resolving to a Response.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n */\n constructor(match, handler, method = defaultMethod) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(match, 'function', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'match',\n });\n if (method) {\n assert.isOneOf(method, validMethods, { paramName: 'method' });\n }\n }\n // These values are referenced directly by Router so cannot be\n // altered by minificaton.\n this.handler = normalizeHandler(handler);\n this.match = match;\n this.method = method;\n }\n /**\n *\n * @param {workbox-routing-handlerCallback} handler A callback\n * function that returns a Promise resolving to a Response\n */\n setCatchHandler(handler) {\n this.catchHandler = normalizeHandler(handler);\n }\n}\nexport { Route };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { Route } from './Route.js';\nimport './_version.js';\n/**\n * RegExpRoute makes it easy to create a regular expression based\n * {@link workbox-routing.Route}.\n *\n * For same-origin requests the RegExp only needs to match part of the URL. For\n * requests against third-party servers, you must define a RegExp that matches\n * the start of the URL.\n *\n * @memberof workbox-routing\n * @extends workbox-routing.Route\n */\nclass RegExpRoute extends Route {\n /**\n * If the regular expression contains\n * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references},\n * the captured values will be passed to the\n * {@link workbox-routing~handlerCallback} `params`\n * argument.\n *\n * @param {RegExp} regExp The regular expression to match against URLs.\n * @param {workbox-routing~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n */\n constructor(regExp, handler, method) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(regExp, RegExp, {\n moduleName: 'workbox-routing',\n className: 'RegExpRoute',\n funcName: 'constructor',\n paramName: 'pattern',\n });\n }\n const match = ({ url }) => {\n const result = regExp.exec(url.href);\n // Return immediately if there's no match.\n if (!result) {\n return;\n }\n // Require that the match start at the first character in the URL string\n // if it's a cross-origin request.\n // See https://github.com/GoogleChrome/workbox/issues/281 for the context\n // behind this behavior.\n if (url.origin !== location.origin && result.index !== 0) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`The regular expression '${regExp.toString()}' only partially matched ` +\n `against the cross-origin URL '${url.toString()}'. RegExpRoute's will only ` +\n `handle cross-origin requests if they match the entire URL.`);\n }\n return;\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 super(match, handler, method);\n }\n}\nexport { RegExpRoute };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst getFriendlyURL = (url) => {\n const urlObj = new URL(String(url), location.href);\n // See https://github.com/GoogleChrome/workbox/issues/2323\n // We want to include everything, except for the origin if it's same-origin.\n return urlObj.href.replace(new RegExp(`^${location.origin}`), '');\n};\nexport { getFriendlyURL };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { defaultMethod } from './utils/constants.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport './_version.js';\n/**\n * The Router can be used to process a `FetchEvent` using one or more\n * {@link workbox-routing.Route}, responding with a `Response` if\n * a matching route exists.\n *\n * If no route matches a given a request, the Router will use a \"default\"\n * handler if one is defined.\n *\n * Should the matching Route throw an error, the Router will use a \"catch\"\n * handler if one is defined to gracefully deal with issues and respond with a\n * Request.\n *\n * If a request matches multiple routes, the **earliest** registered route will\n * be used to respond to the request.\n *\n * @memberof workbox-routing\n */\nclass Router {\n /**\n * Initializes a new Router.\n */\n constructor() {\n this._routes = new Map();\n this._defaultHandlerMap = new Map();\n }\n /**\n * @return {Map>} routes A `Map` of HTTP\n * method name ('GET', etc.) to an array of all the corresponding `Route`\n * instances that are registered.\n */\n get routes() {\n return this._routes;\n }\n /**\n * Adds a fetch event listener to respond to events when a route matches\n * the event's request.\n */\n addFetchListener() {\n // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705\n self.addEventListener('fetch', ((event) => {\n const { request } = event;\n const responsePromise = this.handleRequest({ request, event });\n if (responsePromise) {\n event.respondWith(responsePromise);\n }\n }));\n }\n /**\n * Adds a message event listener for URLs to cache from the window.\n * This is useful to cache resources loaded on the page prior to when the\n * service worker started controlling it.\n *\n * The format of the message data sent from the window should be as follows.\n * Where the `urlsToCache` array may consist of URL strings or an array of\n * URL string + `requestInit` object (the same as you'd pass to `fetch()`).\n *\n * ```\n * {\n * type: 'CACHE_URLS',\n * payload: {\n * urlsToCache: [\n * './script1.js',\n * './script2.js',\n * ['./script3.js', {mode: 'no-cors'}],\n * ],\n * },\n * }\n * ```\n */\n addCacheListener() {\n // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705\n self.addEventListener('message', ((event) => {\n // event.data is type 'any'\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (event.data && event.data.type === 'CACHE_URLS') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const { payload } = event.data;\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Caching URLs from the window`, payload.urlsToCache);\n }\n const requestPromises = Promise.all(payload.urlsToCache.map((entry) => {\n if (typeof entry === 'string') {\n entry = [entry];\n }\n const request = new Request(...entry);\n return this.handleRequest({ request, event });\n // TODO(philipwalton): TypeScript errors without this typecast for\n // some reason (probably a bug). The real type here should work but\n // doesn't: `Array | undefined>`.\n })); // TypeScript\n event.waitUntil(requestPromises);\n // If a MessageChannel was used, reply to the message on success.\n if (event.ports && event.ports[0]) {\n void requestPromises.then(() => event.ports[0].postMessage(true));\n }\n }\n }));\n }\n /**\n * Apply the routing rules to a FetchEvent object to get a Response from an\n * appropriate Route's handler.\n *\n * @param {Object} options\n * @param {Request} options.request The request to handle.\n * @param {ExtendableEvent} options.event The event that triggered the\n * request.\n * @return {Promise|undefined} A promise is returned if a\n * registered route can handle the request. If there is no matching\n * route and there's no `defaultHandler`, `undefined` is returned.\n */\n handleRequest({ request, event, }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'handleRequest',\n paramName: 'options.request',\n });\n }\n const url = new URL(request.url, location.href);\n if (!url.protocol.startsWith('http')) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Workbox Router only supports URLs that start with 'http'.`);\n }\n return;\n }\n const sameOrigin = url.origin === location.origin;\n const { params, route } = this.findMatchingRoute({\n event,\n request,\n sameOrigin,\n url,\n });\n let handler = route && route.handler;\n const debugMessages = [];\n if (process.env.NODE_ENV !== 'production') {\n if (handler) {\n debugMessages.push([`Found a route to handle this request:`, route]);\n if (params) {\n debugMessages.push([\n `Passing the following params to the route's handler:`,\n params,\n ]);\n }\n }\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 const method = request.method;\n if (!handler && this._defaultHandlerMap.has(method)) {\n if (process.env.NODE_ENV !== 'production') {\n debugMessages.push(`Failed to find a matching route. Falling ` +\n `back to the default handler for ${method}.`);\n }\n handler = this._defaultHandlerMap.get(method);\n }\n if (!handler) {\n if (process.env.NODE_ENV !== 'production') {\n // No handler so Workbox will do nothing. If logs is set of debug\n // i.e. verbose, we should print out this information.\n logger.debug(`No route found for: ${getFriendlyURL(url)}`);\n }\n return;\n }\n if (process.env.NODE_ENV !== 'production') {\n // We have a handler, meaning Workbox is going to handle the route.\n // print the routing details to the console.\n logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`);\n debugMessages.forEach((msg) => {\n if (Array.isArray(msg)) {\n logger.log(...msg);\n }\n else {\n logger.log(msg);\n }\n });\n logger.groupEnd();\n }\n // Wrap in try and catch in case the handle method throws a synchronous\n // error. It should still callback to the catch handler.\n let responsePromise;\n try {\n responsePromise = handler.handle({ url, request, event, params });\n }\n catch (err) {\n responsePromise = Promise.reject(err);\n }\n // Get route's catch handler, if it exists\n const catchHandler = route && route.catchHandler;\n if (responsePromise instanceof Promise &&\n (this._catchHandler || catchHandler)) {\n responsePromise = responsePromise.catch(async (err) => {\n // If there's a route catch handler, process that first\n if (catchHandler) {\n if (process.env.NODE_ENV !== 'production') {\n // Still include URL here as it will be async from the console group\n // and may not make sense without the URL\n logger.groupCollapsed(`Error thrown when responding to: ` +\n ` ${getFriendlyURL(url)}. Falling back to route's Catch Handler.`);\n logger.error(`Error thrown by:`, route);\n logger.error(err);\n logger.groupEnd();\n }\n try {\n return await catchHandler.handle({ url, request, event, params });\n }\n catch (catchErr) {\n if (catchErr instanceof Error) {\n err = catchErr;\n }\n }\n }\n if (this._catchHandler) {\n if (process.env.NODE_ENV !== 'production') {\n // Still include URL here as it will be async from the console group\n // and may not make sense without the URL\n logger.groupCollapsed(`Error thrown when responding to: ` +\n ` ${getFriendlyURL(url)}. Falling back to global Catch Handler.`);\n logger.error(`Error thrown by:`, route);\n logger.error(err);\n logger.groupEnd();\n }\n return this._catchHandler.handle({ url, request, event });\n }\n throw err;\n });\n }\n return responsePromise;\n }\n /**\n * Checks a request and URL (and optionally an event) against the list of\n * registered routes, and if there's a match, returns the corresponding\n * route along with any params generated by the match.\n *\n * @param {Object} options\n * @param {URL} options.url\n * @param {boolean} options.sameOrigin The result of comparing `url.origin`\n * against the current origin.\n * @param {Request} options.request The request to match.\n * @param {Event} options.event The corresponding event.\n * @return {Object} An object with `route` and `params` properties.\n * They are populated if a matching route was found or `undefined`\n * otherwise.\n */\n findMatchingRoute({ url, sameOrigin, request, event, }) {\n const routes = this._routes.get(request.method) || [];\n for (const route of routes) {\n let params;\n // route.match returns type any, not possible to change right now.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const matchResult = route.match({ url, sameOrigin, request, event });\n if (matchResult) {\n if (process.env.NODE_ENV !== 'production') {\n // Warn developers that using an async matchCallback is almost always\n // not the right thing to do.\n if (matchResult instanceof Promise) {\n logger.warn(`While routing ${getFriendlyURL(url)}, an async ` +\n `matchCallback function was used. Please convert the ` +\n `following route to use a synchronous matchCallback function:`, route);\n }\n }\n // See https://github.com/GoogleChrome/workbox/issues/2079\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n params = matchResult;\n if (Array.isArray(params) && params.length === 0) {\n // Instead of passing an empty array in as params, use undefined.\n params = undefined;\n }\n else if (matchResult.constructor === Object && // eslint-disable-line\n Object.keys(matchResult).length === 0) {\n // Instead of passing an empty object in as params, use undefined.\n params = undefined;\n }\n else if (typeof matchResult === 'boolean') {\n // For the boolean value true (rather than just something truth-y),\n // don't set params.\n // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353\n params = undefined;\n }\n // Return early if have a match.\n return { route, params };\n }\n }\n // If no match was found above, return and empty object.\n return {};\n }\n /**\n * Define a default `handler` that's called when no routes explicitly\n * match the incoming request.\n *\n * Each HTTP method ('GET', 'POST', etc.) gets its own default handler.\n *\n * Without a default handler, unmatched requests will go against the\n * network as if there were no service worker present.\n *\n * @param {workbox-routing~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n * @param {string} [method='GET'] The HTTP method to associate with this\n * default handler. Each method has its own default.\n */\n setDefaultHandler(handler, method = defaultMethod) {\n this._defaultHandlerMap.set(method, normalizeHandler(handler));\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 * @param {workbox-routing~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n */\n setCatchHandler(handler) {\n this._catchHandler = normalizeHandler(handler);\n }\n /**\n * Registers a route with the router.\n *\n * @param {workbox-routing.Route} route The route to register.\n */\n registerRoute(route) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(route, 'object', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.hasMethod(route, 'match', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.isType(route.handler, 'object', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.hasMethod(route.handler, 'handle', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route.handler',\n });\n assert.isType(route.method, 'string', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route.method',\n });\n }\n if (!this._routes.has(route.method)) {\n this._routes.set(route.method, []);\n }\n // Give precedence to all of the earlier routes by adding this additional\n // route to the end of the array.\n this._routes.get(route.method).push(route);\n }\n /**\n * Unregisters a route with the router.\n *\n * @param {workbox-routing.Route} route The route to unregister.\n */\n unregisterRoute(route) {\n if (!this._routes.has(route.method)) {\n throw new WorkboxError('unregister-route-but-not-found-with-method', {\n method: route.method,\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 }\n else {\n throw new WorkboxError('unregister-route-route-not-registered');\n }\n }\n}\nexport { Router };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { Router } from '../Router.js';\nimport '../_version.js';\nlet defaultRouter;\n/**\n * Creates a new, singleton Router instance if one does not exist. If one\n * does already exist, that instance is returned.\n *\n * @private\n * @return {Router}\n */\nexport const getOrCreateDefaultRouter = () => {\n if (!defaultRouter) {\n defaultRouter = new Router();\n // The helpers that use the default Router assume these listeners exist.\n defaultRouter.addFetchListener();\n defaultRouter.addCacheListener();\n }\n return defaultRouter;\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { Route } from './Route.js';\nimport { RegExpRoute } from './RegExpRoute.js';\nimport { getOrCreateDefaultRouter } from './utils/getOrCreateDefaultRouter.js';\nimport './_version.js';\n/**\n * Easily register a RegExp, string, or function with a caching\n * strategy to a singleton Router instance.\n *\n * This method will generate a Route for you if needed and\n * call {@link workbox-routing.Router#registerRoute}.\n *\n * @param {RegExp|string|workbox-routing.Route~matchCallback|workbox-routing.Route} capture\n * If the capture param is a `Route`, all other arguments will be ignored.\n * @param {workbox-routing~handlerCallback} [handler] A callback\n * function that returns a Promise resulting in a Response. This parameter\n * is required if `capture` is not a `Route` object.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n * @return {workbox-routing.Route} The generated `Route`.\n *\n * @memberof workbox-routing\n */\nfunction registerRoute(capture, handler, method) {\n let route;\n if (typeof capture === 'string') {\n const captureUrl = new URL(capture, location.href);\n if (process.env.NODE_ENV !== 'production') {\n if (!(capture.startsWith('/') || capture.startsWith('http'))) {\n throw new WorkboxError('invalid-string', {\n moduleName: 'workbox-routing',\n funcName: 'registerRoute',\n paramName: 'capture',\n });\n }\n // We want to check if Express-style wildcards are in the pathname only.\n // TODO: Remove this log message in v4.\n const valueToCheck = capture.startsWith('http')\n ? captureUrl.pathname\n : capture;\n // See https://github.com/pillarjs/path-to-regexp#parameters\n const wildcards = '[*:?+]';\n if (new RegExp(`${wildcards}`).exec(valueToCheck)) {\n logger.debug(`The '$capture' parameter contains an Express-style wildcard ` +\n `character (${wildcards}). Strings are now always interpreted as ` +\n `exact matches; use a RegExp for partial or wildcard matches.`);\n }\n }\n const matchCallback = ({ url }) => {\n if (process.env.NODE_ENV !== 'production') {\n if (url.pathname === captureUrl.pathname &&\n url.origin !== captureUrl.origin) {\n logger.debug(`${capture} only partially matches the cross-origin URL ` +\n `${url.toString()}. This route will only handle cross-origin requests ` +\n `if they match the entire URL.`);\n }\n }\n return url.href === captureUrl.href;\n };\n // If `capture` is a string then `handler` and `method` must be present.\n route = new Route(matchCallback, handler, method);\n }\n else if (capture instanceof RegExp) {\n // If `capture` is a `RegExp` then `handler` and `method` must be present.\n route = new RegExpRoute(capture, handler, method);\n }\n else if (typeof capture === 'function') {\n // If `capture` is a function then `handler` and `method` must be present.\n route = new Route(capture, handler, method);\n }\n else if (capture instanceof Route) {\n route = capture;\n }\n else {\n throw new WorkboxError('unsupported-route-type', {\n moduleName: 'workbox-routing',\n funcName: 'registerRoute',\n paramName: 'capture',\n });\n }\n const defaultRouter = getOrCreateDefaultRouter();\n defaultRouter.registerRoute(route);\n return route;\n}\nexport { registerRoute };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst _cacheNameDetails = {\n googleAnalytics: 'googleAnalytics',\n precache: 'precache-v2',\n prefix: 'workbox',\n runtime: 'runtime',\n suffix: typeof registration !== 'undefined' ? registration.scope : '',\n};\nconst _createCacheName = (cacheName) => {\n return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix]\n .filter((value) => value && value.length > 0)\n .join('-');\n};\nconst eachCacheNameDetail = (fn) => {\n for (const key of Object.keys(_cacheNameDetails)) {\n fn(key);\n }\n};\nexport const cacheNames = {\n updateDetails: (details) => {\n eachCacheNameDetail((key) => {\n if (typeof details[key] === 'string') {\n _cacheNameDetails[key] = details[key];\n }\n });\n },\n getGoogleAnalyticsName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);\n },\n getPrecacheName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.precache);\n },\n getPrefix: () => {\n return _cacheNameDetails.prefix;\n },\n getRuntimeName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.runtime);\n },\n getSuffix: () => {\n return _cacheNameDetails.suffix;\n },\n};\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * A helper function that prevents a promise from being flagged as unused.\n *\n * @private\n **/\nexport function dontWaitFor(promise) {\n // Effective no-op.\n void promise.then(() => { });\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n// Callbacks to be executed whenever there's a quota error.\n// Can't change Function type right now.\n// eslint-disable-next-line @typescript-eslint/ban-types\nconst quotaErrorCallbacks = new Set();\nexport { quotaErrorCallbacks };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from './_private/logger.js';\nimport { assert } from './_private/assert.js';\nimport { quotaErrorCallbacks } from './models/quotaErrorCallbacks.js';\nimport './_version.js';\n/**\n * Adds a function to the set of quotaErrorCallbacks that will be executed if\n * there's a quota error.\n *\n * @param {Function} callback\n * @memberof workbox-core\n */\n// Can't change Function type\n// eslint-disable-next-line @typescript-eslint/ban-types\nfunction registerQuotaErrorCallback(callback) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(callback, 'function', {\n moduleName: 'workbox-core',\n funcName: 'register',\n paramName: 'callback',\n });\n }\n quotaErrorCallbacks.add(callback);\n if (process.env.NODE_ENV !== 'production') {\n logger.log('Registered a callback to respond to quota errors.', callback);\n }\n}\nexport { registerQuotaErrorCallback };\n","const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst cursorRequestMap = new WeakMap();\nconst transactionDoneMap = new WeakMap();\nconst transactionStoreNamesMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n promise\n .then((value) => {\n // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval\n // (see wrapFunction).\n if (value instanceof IDBCursor) {\n cursorRequestMap.set(value, request);\n }\n // Catching to avoid \"Uncaught Promise exceptions\"\n })\n .catch(() => { });\n // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Polyfill for objectStoreNames because of Edge.\n if (prop === 'objectStoreNames') {\n return target.objectStoreNames || transactionStoreNamesMap.get(target);\n }\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Edge doesn't support objectStoreNames (booo), so we polyfill it here.\n if (func === IDBDatabase.prototype.transaction &&\n !('objectStoreNames' in IDBTransaction.prototype)) {\n return function (storeNames, ...args) {\n const tx = func.call(unwrap(this), storeNames, ...args);\n transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);\n return wrap(tx);\n };\n }\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(cursorRequestMap.get(this));\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\nexport { reverseTransformCache as a, instanceOfAny as i, replaceTraps as r, unwrap as u, wrap as w };\n","import { w as wrap, r as replaceTraps } from './wrap-idb-value.js';\nexport { u as unwrap, w as wrap } from './wrap-idb-value.js';\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n const request = indexedDB.open(name, version);\n const openPromise = wrap(request);\n if (upgrade) {\n request.addEventListener('upgradeneeded', (event) => {\n upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);\n });\n }\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event.newVersion, event));\n }\n openPromise\n .then((db) => {\n if (terminated)\n db.addEventListener('close', () => terminated());\n if (blocking) {\n db.addEventListener('versionchange', (event) => blocking(event.oldVersion, event.newVersion, event));\n }\n })\n .catch(() => { });\n return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n const request = indexedDB.deleteDatabase(name);\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event));\n }\n return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n if (!(target instanceof IDBDatabase &&\n !(prop in target) &&\n typeof prop === 'string')) {\n return;\n }\n if (cachedMethods.get(prop))\n return cachedMethods.get(prop);\n const targetFuncName = prop.replace(/FromIndex$/, '');\n const useIndex = prop !== targetFuncName;\n const isWrite = writeMethods.includes(targetFuncName);\n if (\n // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n !(isWrite || readMethods.includes(targetFuncName))) {\n return;\n }\n const method = async function (storeName, ...args) {\n // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n let target = tx.store;\n if (useIndex)\n target = target.index(args.shift());\n // Must reject if op rejects.\n // If it's a write operation, must reject if tx.done rejects.\n // Must reject with op rejection first.\n // Must resolve with op value.\n // Must handle both promises (no unhandled rejections)\n return (await Promise.all([\n target[targetFuncName](...args),\n isWrite && tx.done,\n ]))[0];\n };\n cachedMethods.set(prop, method);\n return method;\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nexport { deleteDB, openDB };\n","\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:expiration:7.2.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { openDB, deleteDB } from 'idb';\nimport '../_version.js';\nconst DB_NAME = 'workbox-expiration';\nconst CACHE_OBJECT_STORE = 'cache-entries';\nconst normalizeURL = (unNormalizedUrl) => {\n const url = new URL(unNormalizedUrl, location.href);\n url.hash = '';\n return url.href;\n};\n/**\n * Returns the timestamp model.\n *\n * @private\n */\nclass CacheTimestampsModel {\n /**\n *\n * @param {string} cacheName\n *\n * @private\n */\n constructor(cacheName) {\n this._db = null;\n this._cacheName = cacheName;\n }\n /**\n * Performs an upgrade of indexedDB.\n *\n * @param {IDBPDatabase} db\n *\n * @private\n */\n _upgradeDb(db) {\n // TODO(philipwalton): EdgeHTML doesn't support arrays as a keyPath, so we\n // have to use the `id` keyPath here and create our own values (a\n // concatenation of `url + cacheName`) instead of simply using\n // `keyPath: ['url', 'cacheName']`, which is supported in other browsers.\n const objStore = db.createObjectStore(CACHE_OBJECT_STORE, { keyPath: 'id' });\n // TODO(philipwalton): once we don't have to support EdgeHTML, we can\n // create a single index with the keyPath `['cacheName', 'timestamp']`\n // instead of doing both these indexes.\n objStore.createIndex('cacheName', 'cacheName', { unique: false });\n objStore.createIndex('timestamp', 'timestamp', { unique: false });\n }\n /**\n * Performs an upgrade of indexedDB and deletes deprecated DBs.\n *\n * @param {IDBPDatabase} db\n *\n * @private\n */\n _upgradeDbAndDeleteOldDbs(db) {\n this._upgradeDb(db);\n if (this._cacheName) {\n void deleteDB(this._cacheName);\n }\n }\n /**\n * @param {string} url\n * @param {number} timestamp\n *\n * @private\n */\n async setTimestamp(url, timestamp) {\n url = normalizeURL(url);\n const entry = {\n url,\n timestamp,\n cacheName: this._cacheName,\n // Creating an ID from the URL and cache name won't be necessary once\n // Edge switches to Chromium and all browsers we support work with\n // array keyPaths.\n id: this._getId(url),\n };\n const db = await this.getDb();\n const tx = db.transaction(CACHE_OBJECT_STORE, 'readwrite', {\n durability: 'relaxed',\n });\n await tx.store.put(entry);\n await tx.done;\n }\n /**\n * Returns the timestamp stored for a given URL.\n *\n * @param {string} url\n * @return {number | undefined}\n *\n * @private\n */\n async getTimestamp(url) {\n const db = await this.getDb();\n const entry = await db.get(CACHE_OBJECT_STORE, this._getId(url));\n return entry === null || entry === void 0 ? void 0 : entry.timestamp;\n }\n /**\n * Iterates through all the entries in the object store (from newest to\n * oldest) and removes entries once either `maxCount` is reached or the\n * entry's timestamp is less than `minTimestamp`.\n *\n * @param {number} minTimestamp\n * @param {number} maxCount\n * @return {Array}\n *\n * @private\n */\n async expireEntries(minTimestamp, maxCount) {\n const db = await this.getDb();\n let cursor = await db\n .transaction(CACHE_OBJECT_STORE)\n .store.index('timestamp')\n .openCursor(null, 'prev');\n const entriesToDelete = [];\n let entriesNotDeletedCount = 0;\n while (cursor) {\n const result = cursor.value;\n // TODO(philipwalton): once we can use a multi-key index, we\n // won't have to check `cacheName` here.\n if (result.cacheName === this._cacheName) {\n // Delete an entry if it's older than the max age or\n // if we already have the max number allowed.\n if ((minTimestamp && result.timestamp < minTimestamp) ||\n (maxCount && entriesNotDeletedCount >= maxCount)) {\n // TODO(philipwalton): we should be able to delete the\n // entry right here, but doing so causes an iteration\n // bug in Safari stable (fixed in TP). Instead we can\n // store the keys of the entries to delete, and then\n // delete the separate transactions.\n // https://github.com/GoogleChrome/workbox/issues/1978\n // cursor.delete();\n // We only need to return the URL, not the whole entry.\n entriesToDelete.push(cursor.value);\n }\n else {\n entriesNotDeletedCount++;\n }\n }\n cursor = await cursor.continue();\n }\n // TODO(philipwalton): once the Safari bug in the following issue is fixed,\n // we should be able to remove this loop and do the entry deletion in the\n // cursor loop above:\n // https://github.com/GoogleChrome/workbox/issues/1978\n const urlsDeleted = [];\n for (const entry of entriesToDelete) {\n await db.delete(CACHE_OBJECT_STORE, entry.id);\n urlsDeleted.push(entry.url);\n }\n return urlsDeleted;\n }\n /**\n * Takes a URL and returns an ID that will be unique in the object store.\n *\n * @param {string} url\n * @return {string}\n *\n * @private\n */\n _getId(url) {\n // Creating an ID from the URL and cache name won't be necessary once\n // Edge switches to Chromium and all browsers we support work with\n // array keyPaths.\n return this._cacheName + '|' + normalizeURL(url);\n }\n /**\n * Returns an open connection to the database.\n *\n * @private\n */\n async getDb() {\n if (!this._db) {\n this._db = await openDB(DB_NAME, 1, {\n upgrade: this._upgradeDbAndDeleteOldDbs.bind(this),\n });\n }\n return this._db;\n }\n}\nexport { CacheTimestampsModel };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { dontWaitFor } from 'workbox-core/_private/dontWaitFor.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { CacheTimestampsModel } from './models/CacheTimestampsModel.js';\nimport './_version.js';\n/**\n * The `CacheExpiration` class allows you define an expiration and / or\n * limit on the number of responses stored in a\n * [`Cache`](https://developer.mozilla.org/en-US/docs/Web/API/Cache).\n *\n * @memberof workbox-expiration\n */\nclass CacheExpiration {\n /**\n * To construct a new CacheExpiration instance you must provide at least\n * one of the `config` properties.\n *\n * @param {string} cacheName Name of the cache to apply restrictions to.\n * @param {Object} config\n * @param {number} [config.maxEntries] The maximum number of entries to cache.\n * Entries used the least will be removed as the maximum is reached.\n * @param {number} [config.maxAgeSeconds] The maximum age of an entry before\n * it's treated as stale and removed.\n * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)\n * that will be used when calling `delete()` on the cache.\n */\n constructor(cacheName, config = {}) {\n this._isRunning = false;\n this._rerunRequested = false;\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n paramName: 'cacheName',\n });\n if (!(config.maxEntries || config.maxAgeSeconds)) {\n throw new WorkboxError('max-entries-or-age-required', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n });\n }\n if (config.maxEntries) {\n assert.isType(config.maxEntries, 'number', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n paramName: 'config.maxEntries',\n });\n }\n if (config.maxAgeSeconds) {\n assert.isType(config.maxAgeSeconds, 'number', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n paramName: 'config.maxAgeSeconds',\n });\n }\n }\n this._maxEntries = config.maxEntries;\n this._maxAgeSeconds = config.maxAgeSeconds;\n this._matchOptions = config.matchOptions;\n this._cacheName = cacheName;\n this._timestampModel = new CacheTimestampsModel(cacheName);\n }\n /**\n * Expires entries for the given cache and given criteria.\n */\n async expireEntries() {\n if (this._isRunning) {\n this._rerunRequested = true;\n return;\n }\n this._isRunning = true;\n const minTimestamp = this._maxAgeSeconds\n ? Date.now() - this._maxAgeSeconds * 1000\n : 0;\n const urlsExpired = await this._timestampModel.expireEntries(minTimestamp, this._maxEntries);\n // Delete URLs from the cache\n const cache = await self.caches.open(this._cacheName);\n for (const url of urlsExpired) {\n await cache.delete(url, this._matchOptions);\n }\n if (process.env.NODE_ENV !== 'production') {\n if (urlsExpired.length > 0) {\n logger.groupCollapsed(`Expired ${urlsExpired.length} ` +\n `${urlsExpired.length === 1 ? 'entry' : 'entries'} and removed ` +\n `${urlsExpired.length === 1 ? 'it' : 'them'} from the ` +\n `'${this._cacheName}' cache.`);\n logger.log(`Expired the following ${urlsExpired.length === 1 ? 'URL' : 'URLs'}:`);\n urlsExpired.forEach((url) => logger.log(` ${url}`));\n logger.groupEnd();\n }\n else {\n logger.debug(`Cache expiration ran and found no entries to remove.`);\n }\n }\n this._isRunning = false;\n if (this._rerunRequested) {\n this._rerunRequested = false;\n dontWaitFor(this.expireEntries());\n }\n }\n /**\n * Update the timestamp for the given URL. This ensures the when\n * removing entries based on maximum entries, most recently used\n * is accurate or when expiring, the timestamp is up-to-date.\n *\n * @param {string} url\n */\n async updateTimestamp(url) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(url, 'string', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'updateTimestamp',\n paramName: 'url',\n });\n }\n await this._timestampModel.setTimestamp(url, Date.now());\n }\n /**\n * Can be used to check if a URL has expired or not before it's used.\n *\n * This requires a look up from IndexedDB, so can be slow.\n *\n * Note: This method will not remove the cached entry, call\n * `expireEntries()` to remove indexedDB and Cache entries.\n *\n * @param {string} url\n * @return {boolean}\n */\n async isURLExpired(url) {\n if (!this._maxAgeSeconds) {\n if (process.env.NODE_ENV !== 'production') {\n throw new WorkboxError(`expired-test-without-max-age`, {\n methodName: 'isURLExpired',\n paramName: 'maxAgeSeconds',\n });\n }\n return false;\n }\n else {\n const timestamp = await this._timestampModel.getTimestamp(url);\n const expireOlderThan = Date.now() - this._maxAgeSeconds * 1000;\n return timestamp !== undefined ? timestamp < expireOlderThan : true;\n }\n }\n /**\n * Removes the IndexedDB object store used to keep track of cache expiration\n * metadata.\n */\n async delete() {\n // Make sure we don't attempt another rerun if we're called in the middle of\n // a cache expiration.\n this._rerunRequested = false;\n await this._timestampModel.expireEntries(Infinity); // Expires all.\n }\n}\nexport { CacheExpiration };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { dontWaitFor } from 'workbox-core/_private/dontWaitFor.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { registerQuotaErrorCallback } from 'workbox-core/registerQuotaErrorCallback.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { CacheExpiration } from './CacheExpiration.js';\nimport './_version.js';\n/**\n * This plugin can be used in a `workbox-strategy` to regularly enforce a\n * limit on the age and / or the number of cached requests.\n *\n * It can only be used with `workbox-strategy` instances that have a\n * [custom `cacheName` property set](/web/tools/workbox/guides/configure-workbox#custom_cache_names_in_strategies).\n * In other words, it can't be used to expire entries in strategy that uses the\n * default runtime cache name.\n *\n * Whenever a cached response is used or updated, this plugin will look\n * at the associated cache and remove any old or extra responses.\n *\n * When using `maxAgeSeconds`, responses may be used *once* after expiring\n * because the expiration clean up will not have occurred until *after* the\n * cached response has been used. If the response has a \"Date\" header, then\n * a light weight expiration check is performed and the response will not be\n * used immediately.\n *\n * When using `maxEntries`, the entry least-recently requested will be removed\n * from the cache first.\n *\n * @memberof workbox-expiration\n */\nclass ExpirationPlugin {\n /**\n * @param {ExpirationPluginOptions} config\n * @param {number} [config.maxEntries] The maximum number of entries to cache.\n * Entries used the least will be removed as the maximum is reached.\n * @param {number} [config.maxAgeSeconds] The maximum age of an entry before\n * it's treated as stale and removed.\n * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)\n * that will be used when calling `delete()` on the cache.\n * @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to\n * automatic deletion if the available storage quota has been exceeded.\n */\n constructor(config = {}) {\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-strategies` 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 * @param {Object} options\n * @param {string} options.cacheName Name of the cache the response is in.\n * @param {Response} options.cachedResponse The `Response` object that's been\n * read from a cache and whose freshness should be checked.\n * @return {Response} Either the `cachedResponse`, if it's\n * fresh, or `null` if the `Response` is older than `maxAgeSeconds`.\n *\n * @private\n */\n this.cachedResponseWillBeUsed = async ({ event, request, cacheName, cachedResponse, }) => {\n if (!cachedResponse) {\n return null;\n }\n const isFresh = this._isResponseDateFresh(cachedResponse);\n // Expire entries to ensure that even if the expiration date has\n // expired, it'll only be used once.\n const cacheExpiration = this._getCacheExpiration(cacheName);\n dontWaitFor(cacheExpiration.expireEntries());\n // Update the metadata for the request URL to the current timestamp,\n // but don't `await` it as we don't want to block the response.\n const updateTimestampDone = cacheExpiration.updateTimestamp(request.url);\n if (event) {\n try {\n event.waitUntil(updateTimestampDone);\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n // The event may not be a fetch event; only log the URL if it is.\n if ('request' in event) {\n logger.warn(`Unable to ensure service worker stays alive when ` +\n `updating cache entry for ` +\n `'${getFriendlyURL(event.request.url)}'.`);\n }\n }\n }\n }\n return isFresh ? cachedResponse : null;\n };\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-strategies` handlers when an entry is added to a cache.\n *\n * @param {Object} options\n * @param {string} options.cacheName Name of the cache that was updated.\n * @param {string} options.request The Request for the cached entry.\n *\n * @private\n */\n this.cacheDidUpdate = async ({ cacheName, request, }) => {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'cacheName',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'request',\n });\n }\n const cacheExpiration = this._getCacheExpiration(cacheName);\n await cacheExpiration.updateTimestamp(request.url);\n await cacheExpiration.expireEntries();\n };\n if (process.env.NODE_ENV !== 'production') {\n if (!(config.maxEntries || config.maxAgeSeconds)) {\n throw new WorkboxError('max-entries-or-age-required', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'constructor',\n });\n }\n if (config.maxEntries) {\n assert.isType(config.maxEntries, 'number', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'constructor',\n paramName: 'config.maxEntries',\n });\n }\n if (config.maxAgeSeconds) {\n assert.isType(config.maxAgeSeconds, 'number', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'constructor',\n paramName: 'config.maxAgeSeconds',\n });\n }\n }\n this._config = config;\n this._maxAgeSeconds = config.maxAgeSeconds;\n this._cacheExpirations = new Map();\n if (config.purgeOnQuotaError) {\n registerQuotaErrorCallback(() => this.deleteCacheAndMetadata());\n }\n }\n /**\n * A simple helper method to return a CacheExpiration instance for a given\n * cache name.\n *\n * @param {string} cacheName\n * @return {CacheExpiration}\n *\n * @private\n */\n _getCacheExpiration(cacheName) {\n if (cacheName === cacheNames.getRuntimeName()) {\n throw new WorkboxError('expire-custom-caches-only');\n }\n let cacheExpiration = this._cacheExpirations.get(cacheName);\n if (!cacheExpiration) {\n cacheExpiration = new CacheExpiration(cacheName, this._config);\n this._cacheExpirations.set(cacheName, cacheExpiration);\n }\n return cacheExpiration;\n }\n /**\n * @param {Response} cachedResponse\n * @return {boolean}\n *\n * @private\n */\n _isResponseDateFresh(cachedResponse) {\n if (!this._maxAgeSeconds) {\n // We aren't expiring by age, so return true, it's fresh\n return true;\n }\n // Check if the 'date' header will suffice a quick expiration check.\n // See https://github.com/GoogleChromeLabs/sw-toolbox/issues/164 for\n // discussion.\n const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse);\n if (dateHeaderTimestamp === null) {\n // Unable to parse date, so assume it's fresh.\n return true;\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 const now = Date.now();\n return dateHeaderTimestamp >= now - this._maxAgeSeconds * 1000;\n }\n /**\n * This method will extract the data header and parse it into a useful\n * value.\n *\n * @param {Response} cachedResponse\n * @return {number|null}\n *\n * @private\n */\n _getDateHeaderTimestamp(cachedResponse) {\n if (!cachedResponse.headers.has('date')) {\n return null;\n }\n const dateHeader = cachedResponse.headers.get('date');\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.\n if (isNaN(headerTime)) {\n return null;\n }\n return headerTime;\n }\n /**\n * This is a helper method that performs two operations:\n *\n * - Deletes *all* the underlying Cache instances associated with this plugin\n * instance, by calling caches.delete() on your behalf.\n * - Deletes the metadata from IndexedDB used to keep track of expiration\n * details for each Cache instance.\n *\n * When using cache expiration, calling this method is preferable to calling\n * `caches.delete()` directly, since this will ensure that the IndexedDB\n * metadata is also cleanly removed and open IndexedDB instances are deleted.\n *\n * Note that if you're *not* using cache expiration for a given cache, calling\n * `caches.delete()` and passing in the cache's name should be sufficient.\n * There is no Workbox-specific method needed for cleanup in that case.\n */\n async deleteCacheAndMetadata() {\n // Do this one at a time instead of all at once via `Promise.all()` to\n // reduce the chance of inconsistency if a promise rejects.\n for (const [cacheName, cacheExpiration] of this._cacheExpirations) {\n await self.caches.delete(cacheName);\n await cacheExpiration.delete();\n }\n // Reset this._cacheExpirations to its initial state.\n this._cacheExpirations = new Map();\n }\n}\nexport { ExpirationPlugin };\n","\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:cacheable-response:7.2.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport './_version.js';\n/**\n * This class allows you to set up rules determining what\n * status codes and/or headers need to be present in order for a\n * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * to be considered cacheable.\n *\n * @memberof workbox-cacheable-response\n */\nclass CacheableResponse {\n /**\n * To construct a new CacheableResponse instance you must provide at least\n * one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (!(config.statuses || config.headers)) {\n throw new WorkboxError('statuses-or-headers-required', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n });\n }\n if (config.statuses) {\n assert.isArray(config.statuses, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.statuses',\n });\n }\n if (config.headers) {\n assert.isType(config.headers, 'object', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.headers',\n });\n }\n }\n this._statuses = config.statuses;\n this._headers = config.headers;\n }\n /**\n * Checks a response to see whether it's cacheable or not, based on this\n * object's configuration.\n *\n * @param {Response} response The response whose cacheability is being\n * checked.\n * @return {boolean} `true` if the `Response` is cacheable, and `false`\n * otherwise.\n */\n isResponseCacheable(response) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(response, Response, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'isResponseCacheable',\n paramName: 'response',\n });\n }\n let cacheable = true;\n if (this._statuses) {\n cacheable = this._statuses.includes(response.status);\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 if (process.env.NODE_ENV !== 'production') {\n if (!cacheable) {\n logger.groupCollapsed(`The request for ` +\n `'${getFriendlyURL(response.url)}' returned a response that does ` +\n `not meet the criteria for being cached.`);\n logger.groupCollapsed(`View cacheability criteria here.`);\n logger.log(`Cacheable statuses: ` + JSON.stringify(this._statuses));\n logger.log(`Cacheable headers: ` + JSON.stringify(this._headers, null, 2));\n logger.groupEnd();\n const logFriendlyHeaders = {};\n response.headers.forEach((value, key) => {\n logFriendlyHeaders[key] = value;\n });\n logger.groupCollapsed(`View response status and headers here.`);\n logger.log(`Response status: ${response.status}`);\n logger.log(`Response headers: ` + JSON.stringify(logFriendlyHeaders, null, 2));\n logger.groupEnd();\n logger.groupCollapsed(`View full response details here.`);\n logger.log(response.headers);\n logger.log(response);\n logger.groupEnd();\n logger.groupEnd();\n }\n }\n return cacheable;\n }\n}\nexport { CacheableResponse };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { CacheableResponse, } from './CacheableResponse.js';\nimport './_version.js';\n/**\n * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it\n * easier to add in cacheability checks to requests made via Workbox's built-in\n * strategies.\n *\n * @memberof workbox-cacheable-response\n */\nclass CacheableResponsePlugin {\n /**\n * To construct a new CacheableResponsePlugin instance you must provide at\n * least one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config) {\n /**\n * @param {Object} options\n * @param {Response} options.response\n * @return {Response|null}\n * @private\n */\n this.cacheWillUpdate = async ({ response }) => {\n if (this._cacheableResponse.isResponseCacheable(response)) {\n return response;\n }\n return null;\n };\n this._cacheableResponse = new CacheableResponse(config);\n }\n}\nexport { CacheableResponsePlugin };\n","\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:strategies:7.2.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nexport const cacheOkAndOpaquePlugin = {\n /**\n * Returns a valid response (to allow caching) if the status is 200 (OK) or\n * 0 (opaque).\n *\n * @param {Object} options\n * @param {Response} options.response\n * @return {Response|null}\n *\n * @private\n */\n cacheWillUpdate: async ({ response }) => {\n if (response.status === 200 || response.status === 0) {\n return response;\n }\n return null;\n },\n};\n","/*\n Copyright 2020 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nfunction stripParams(fullURL, ignoreParams) {\n const strippedURL = new URL(fullURL);\n for (const param of ignoreParams) {\n strippedURL.searchParams.delete(param);\n }\n return strippedURL.href;\n}\n/**\n * Matches an item in the cache, ignoring specific URL params. This is similar\n * to the `ignoreSearch` option, but it allows you to ignore just specific\n * params (while continuing to match on the others).\n *\n * @private\n * @param {Cache} cache\n * @param {Request} request\n * @param {Object} matchOptions\n * @param {Array} ignoreParams\n * @return {Promise}\n */\nasync function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) {\n const strippedRequestURL = stripParams(request.url, ignoreParams);\n // If the request doesn't include any ignored params, match as normal.\n if (request.url === strippedRequestURL) {\n return cache.match(request, matchOptions);\n }\n // Otherwise, match by comparing keys\n const keysOptions = Object.assign(Object.assign({}, matchOptions), { ignoreSearch: true });\n const cacheKeys = await cache.keys(request, keysOptions);\n for (const cacheKey of cacheKeys) {\n const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams);\n if (strippedRequestURL === strippedCacheKeyURL) {\n return cache.match(cacheKey, matchOptions);\n }\n }\n return;\n}\nexport { cacheMatchIgnoreParams };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * The Deferred class composes Promises in a way that allows for them to be\n * resolved or rejected from outside the constructor. In most cases promises\n * should be used directly, but Deferreds can be necessary when the logic to\n * resolve a promise must be separate.\n *\n * @private\n */\nclass Deferred {\n /**\n * Creates a promise and exposes its resolve and reject functions as methods.\n */\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n }\n}\nexport { Deferred };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from '../_private/logger.js';\nimport { quotaErrorCallbacks } from '../models/quotaErrorCallbacks.js';\nimport '../_version.js';\n/**\n * Runs all of the callback functions, one at a time sequentially, in the order\n * in which they were registered.\n *\n * @memberof workbox-core\n * @private\n */\nasync function executeQuotaErrorCallbacks() {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`About to run ${quotaErrorCallbacks.size} ` +\n `callbacks to clean up caches.`);\n }\n for (const callback of quotaErrorCallbacks) {\n await callback();\n if (process.env.NODE_ENV !== 'production') {\n logger.log(callback, 'is complete.');\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log('Finished running callbacks.');\n }\n}\nexport { executeQuotaErrorCallbacks };\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * Returns a promise that resolves and the passed number of milliseconds.\n * This utility is an async/await-friendly version of `setTimeout`.\n *\n * @param {number} ms\n * @return {Promise}\n * @private\n */\nexport function timeout(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/*\n Copyright 2020 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheMatchIgnoreParams } from 'workbox-core/_private/cacheMatchIgnoreParams.js';\nimport { Deferred } from 'workbox-core/_private/Deferred.js';\nimport { executeQuotaErrorCallbacks } from 'workbox-core/_private/executeQuotaErrorCallbacks.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { timeout } from 'workbox-core/_private/timeout.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport './_version.js';\nfunction toRequest(input) {\n return typeof input === 'string' ? new Request(input) : input;\n}\n/**\n * A class created every time a Strategy instance instance calls\n * {@link workbox-strategies.Strategy~handle} or\n * {@link workbox-strategies.Strategy~handleAll} that wraps all fetch and\n * cache actions around plugin callbacks and keeps track of when the strategy\n * is \"done\" (i.e. all added `event.waitUntil()` promises have resolved).\n *\n * @memberof workbox-strategies\n */\nclass StrategyHandler {\n /**\n * Creates a new instance associated with the passed strategy and event\n * that's handling the request.\n *\n * The constructor also initializes the state that will be passed to each of\n * the plugins handling this request.\n *\n * @param {workbox-strategies.Strategy} strategy\n * @param {Object} options\n * @param {Request|string} options.request A request to run this strategy for.\n * @param {ExtendableEvent} options.event The event associated with the\n * request.\n * @param {URL} [options.url]\n * @param {*} [options.params] The return value from the\n * {@link workbox-routing~matchCallback} (if applicable).\n */\n constructor(strategy, options) {\n this._cacheKeys = {};\n /**\n * The request the strategy is performing (passed to the strategy's\n * `handle()` or `handleAll()` method).\n * @name request\n * @instance\n * @type {Request}\n * @memberof workbox-strategies.StrategyHandler\n */\n /**\n * The event associated with this request.\n * @name event\n * @instance\n * @type {ExtendableEvent}\n * @memberof workbox-strategies.StrategyHandler\n */\n /**\n * A `URL` instance of `request.url` (if passed to the strategy's\n * `handle()` or `handleAll()` method).\n * Note: the `url` param will be present if the strategy was invoked\n * from a workbox `Route` object.\n * @name url\n * @instance\n * @type {URL|undefined}\n * @memberof workbox-strategies.StrategyHandler\n */\n /**\n * A `param` value (if passed to the strategy's\n * `handle()` or `handleAll()` method).\n * Note: the `param` param will be present if the strategy was invoked\n * from a workbox `Route` object and the\n * {@link workbox-routing~matchCallback} returned\n * a truthy value (it will be that value).\n * @name params\n * @instance\n * @type {*|undefined}\n * @memberof workbox-strategies.StrategyHandler\n */\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(options.event, ExtendableEvent, {\n moduleName: 'workbox-strategies',\n className: 'StrategyHandler',\n funcName: 'constructor',\n paramName: 'options.event',\n });\n }\n Object.assign(this, options);\n this.event = options.event;\n this._strategy = strategy;\n this._handlerDeferred = new Deferred();\n this._extendLifetimePromises = [];\n // Copy the plugins list (since it's mutable on the strategy),\n // so any mutations don't affect this handler instance.\n this._plugins = [...strategy.plugins];\n this._pluginStateMap = new Map();\n for (const plugin of this._plugins) {\n this._pluginStateMap.set(plugin, {});\n }\n this.event.waitUntil(this._handlerDeferred.promise);\n }\n /**\n * Fetches a given request (and invokes any applicable plugin callback\n * methods) using the `fetchOptions` (for non-navigation requests) and\n * `plugins` defined on the `Strategy` object.\n *\n * The following plugin lifecycle methods are invoked when using this method:\n * - `requestWillFetch()`\n * - `fetchDidSucceed()`\n * - `fetchDidFail()`\n *\n * @param {Request|string} input The URL or request to fetch.\n * @return {Promise}\n */\n async fetch(input) {\n const { event } = this;\n let request = toRequest(input);\n if (request.mode === 'navigate' &&\n event instanceof FetchEvent &&\n event.preloadResponse) {\n const possiblePreloadResponse = (await event.preloadResponse);\n if (possiblePreloadResponse) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Using a preloaded navigation response for ` +\n `'${getFriendlyURL(request.url)}'`);\n }\n return possiblePreloadResponse;\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 originalRequest = this.hasCallback('fetchDidFail')\n ? request.clone()\n : null;\n try {\n for (const cb of this.iterateCallbacks('requestWillFetch')) {\n request = await cb({ request: request.clone(), event });\n }\n }\n catch (err) {\n if (err instanceof Error) {\n throw new WorkboxError('plugin-error-request-will-fetch', {\n thrownErrorMessage: err.message,\n });\n }\n }\n // The request can be altered by plugins with `requestWillFetch` making\n // the original request (most likely from a `fetch` event) different\n // from the Request we make. Pass both to `fetchDidFail` to aid debugging.\n const pluginFilteredRequest = request.clone();\n try {\n let fetchResponse;\n // See https://github.com/GoogleChrome/workbox/issues/1796\n fetchResponse = await fetch(request, request.mode === 'navigate' ? undefined : this._strategy.fetchOptions);\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Network request for ` +\n `'${getFriendlyURL(request.url)}' returned a response with ` +\n `status '${fetchResponse.status}'.`);\n }\n for (const callback of this.iterateCallbacks('fetchDidSucceed')) {\n fetchResponse = await callback({\n event,\n request: pluginFilteredRequest,\n response: fetchResponse,\n });\n }\n return fetchResponse;\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Network request for ` +\n `'${getFriendlyURL(request.url)}' threw an error.`, error);\n }\n // `originalRequest` will only exist if a `fetchDidFail` callback\n // is being used (see above).\n if (originalRequest) {\n await this.runCallbacks('fetchDidFail', {\n error: error,\n event,\n originalRequest: originalRequest.clone(),\n request: pluginFilteredRequest.clone(),\n });\n }\n throw error;\n }\n }\n /**\n * Calls `this.fetch()` and (in the background) runs `this.cachePut()` on\n * the response generated by `this.fetch()`.\n *\n * The call to `this.cachePut()` automatically invokes `this.waitUntil()`,\n * so you do not have to manually call `waitUntil()` on the event.\n *\n * @param {Request|string} input The request or URL to fetch and cache.\n * @return {Promise}\n */\n async fetchAndCachePut(input) {\n const response = await this.fetch(input);\n const responseClone = response.clone();\n void this.waitUntil(this.cachePut(input, responseClone));\n return response;\n }\n /**\n * Matches a request from the cache (and invokes any applicable plugin\n * callback methods) using the `cacheName`, `matchOptions`, and `plugins`\n * defined on the strategy object.\n *\n * The following plugin lifecycle methods are invoked when using this method:\n * - cacheKeyWillBeUsed()\n * - cachedResponseWillBeUsed()\n *\n * @param {Request|string} key The Request or URL to use as the cache key.\n * @return {Promise} A matching response, if found.\n */\n async cacheMatch(key) {\n const request = toRequest(key);\n let cachedResponse;\n const { cacheName, matchOptions } = this._strategy;\n const effectiveRequest = await this.getCacheKey(request, 'read');\n const multiMatchOptions = Object.assign(Object.assign({}, matchOptions), { cacheName });\n cachedResponse = await caches.match(effectiveRequest, multiMatchOptions);\n if (process.env.NODE_ENV !== 'production') {\n if (cachedResponse) {\n logger.debug(`Found a cached response in '${cacheName}'.`);\n }\n else {\n logger.debug(`No cached response found in '${cacheName}'.`);\n }\n }\n for (const callback of this.iterateCallbacks('cachedResponseWillBeUsed')) {\n cachedResponse =\n (await callback({\n cacheName,\n matchOptions,\n cachedResponse,\n request: effectiveRequest,\n event: this.event,\n })) || undefined;\n }\n return cachedResponse;\n }\n /**\n * Puts a request/response pair in the cache (and invokes any applicable\n * plugin callback methods) using the `cacheName` and `plugins` defined on\n * the strategy object.\n *\n * The following plugin lifecycle methods are invoked when using this method:\n * - cacheKeyWillBeUsed()\n * - cacheWillUpdate()\n * - cacheDidUpdate()\n *\n * @param {Request|string} key The request or URL to use as the cache key.\n * @param {Response} response The response to cache.\n * @return {Promise} `false` if a cacheWillUpdate caused the response\n * not be cached, and `true` otherwise.\n */\n async cachePut(key, response) {\n const request = toRequest(key);\n // Run in the next task to avoid blocking other cache reads.\n // https://github.com/w3c/ServiceWorker/issues/1397\n await timeout(0);\n const effectiveRequest = await this.getCacheKey(request, 'write');\n if (process.env.NODE_ENV !== 'production') {\n if (effectiveRequest.method && effectiveRequest.method !== 'GET') {\n throw new WorkboxError('attempt-to-cache-non-get-request', {\n url: getFriendlyURL(effectiveRequest.url),\n method: effectiveRequest.method,\n });\n }\n // See https://github.com/GoogleChrome/workbox/issues/2818\n const vary = response.headers.get('Vary');\n if (vary) {\n logger.debug(`The response for ${getFriendlyURL(effectiveRequest.url)} ` +\n `has a 'Vary: ${vary}' header. ` +\n `Consider setting the {ignoreVary: true} option on your strategy ` +\n `to ensure cache matching and deletion works as expected.`);\n }\n }\n if (!response) {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Cannot cache non-existent response for ` +\n `'${getFriendlyURL(effectiveRequest.url)}'.`);\n }\n throw new WorkboxError('cache-put-with-no-response', {\n url: getFriendlyURL(effectiveRequest.url),\n });\n }\n const responseToCache = await this._ensureResponseSafeToCache(response);\n if (!responseToCache) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' ` +\n `will not be cached.`, responseToCache);\n }\n return false;\n }\n const { cacheName, matchOptions } = this._strategy;\n const cache = await self.caches.open(cacheName);\n const hasCacheUpdateCallback = this.hasCallback('cacheDidUpdate');\n const oldResponse = hasCacheUpdateCallback\n ? await cacheMatchIgnoreParams(\n // TODO(philipwalton): the `__WB_REVISION__` param is a precaching\n // feature. Consider into ways to only add this behavior if using\n // precaching.\n cache, effectiveRequest.clone(), ['__WB_REVISION__'], matchOptions)\n : null;\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Updating the '${cacheName}' cache with a new Response ` +\n `for ${getFriendlyURL(effectiveRequest.url)}.`);\n }\n try {\n await cache.put(effectiveRequest, hasCacheUpdateCallback ? responseToCache.clone() : responseToCache);\n }\n catch (error) {\n if (error instanceof Error) {\n // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError\n if (error.name === 'QuotaExceededError') {\n await executeQuotaErrorCallbacks();\n }\n throw error;\n }\n }\n for (const callback of this.iterateCallbacks('cacheDidUpdate')) {\n await callback({\n cacheName,\n oldResponse,\n newResponse: responseToCache.clone(),\n request: effectiveRequest,\n event: this.event,\n });\n }\n return true;\n }\n /**\n * Checks the list of plugins for the `cacheKeyWillBeUsed` callback, and\n * executes any of those callbacks found in sequence. The final `Request`\n * object returned by the last plugin is treated as the cache key for cache\n * reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have\n * been registered, the passed request is returned unmodified\n *\n * @param {Request} request\n * @param {string} mode\n * @return {Promise}\n */\n async getCacheKey(request, mode) {\n const key = `${request.url} | ${mode}`;\n if (!this._cacheKeys[key]) {\n let effectiveRequest = request;\n for (const callback of this.iterateCallbacks('cacheKeyWillBeUsed')) {\n effectiveRequest = toRequest(await callback({\n mode,\n request: effectiveRequest,\n event: this.event,\n // params has a type any can't change right now.\n params: this.params, // eslint-disable-line\n }));\n }\n this._cacheKeys[key] = effectiveRequest;\n }\n return this._cacheKeys[key];\n }\n /**\n * Returns true if the strategy has at least one plugin with the given\n * callback.\n *\n * @param {string} name The name of the callback to check for.\n * @return {boolean}\n */\n hasCallback(name) {\n for (const plugin of this._strategy.plugins) {\n if (name in plugin) {\n return true;\n }\n }\n return false;\n }\n /**\n * Runs all plugin callbacks matching the given name, in order, passing the\n * given param object (merged ith the current plugin state) as the only\n * argument.\n *\n * Note: since this method runs all plugins, it's not suitable for cases\n * where the return value of a callback needs to be applied prior to calling\n * the next callback. See\n * {@link workbox-strategies.StrategyHandler#iterateCallbacks}\n * below for how to handle that case.\n *\n * @param {string} name The name of the callback to run within each plugin.\n * @param {Object} param The object to pass as the first (and only) param\n * when executing each callback. This object will be merged with the\n * current plugin state prior to callback execution.\n */\n async runCallbacks(name, param) {\n for (const callback of this.iterateCallbacks(name)) {\n // TODO(philipwalton): not sure why `any` is needed. It seems like\n // this should work with `as WorkboxPluginCallbackParam[C]`.\n await callback(param);\n }\n }\n /**\n * Accepts a callback and returns an iterable of matching plugin callbacks,\n * where each callback is wrapped with the current handler state (i.e. when\n * you call each callback, whatever object parameter you pass it will\n * be merged with the plugin's current state).\n *\n * @param {string} name The name fo the callback to run\n * @return {Array}\n */\n *iterateCallbacks(name) {\n for (const plugin of this._strategy.plugins) {\n if (typeof plugin[name] === 'function') {\n const state = this._pluginStateMap.get(plugin);\n const statefulCallback = (param) => {\n const statefulParam = Object.assign(Object.assign({}, param), { state });\n // TODO(philipwalton): not sure why `any` is needed. It seems like\n // this should work with `as WorkboxPluginCallbackParam[C]`.\n return plugin[name](statefulParam);\n };\n yield statefulCallback;\n }\n }\n }\n /**\n * Adds a promise to the\n * [extend lifetime promises]{@link https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises}\n * of the event event associated with the request being handled (usually a\n * `FetchEvent`).\n *\n * Note: you can await\n * {@link workbox-strategies.StrategyHandler~doneWaiting}\n * to know when all added promises have settled.\n *\n * @param {Promise} promise A promise to add to the extend lifetime promises\n * of the event that triggered the request.\n */\n waitUntil(promise) {\n this._extendLifetimePromises.push(promise);\n return promise;\n }\n /**\n * Returns a promise that resolves once all promises passed to\n * {@link workbox-strategies.StrategyHandler~waitUntil}\n * have settled.\n *\n * Note: any work done after `doneWaiting()` settles should be manually\n * passed to an event's `waitUntil()` method (not this handler's\n * `waitUntil()` method), otherwise the service worker thread my be killed\n * prior to your work completing.\n */\n async doneWaiting() {\n let promise;\n while ((promise = this._extendLifetimePromises.shift())) {\n await promise;\n }\n }\n /**\n * Stops running the strategy and immediately resolves any pending\n * `waitUntil()` promises.\n */\n destroy() {\n this._handlerDeferred.resolve(null);\n }\n /**\n * This method will call cacheWillUpdate on the available plugins (or use\n * status === 200) to determine if the Response is safe and valid to cache.\n *\n * @param {Request} options.request\n * @param {Response} options.response\n * @return {Promise}\n *\n * @private\n */\n async _ensureResponseSafeToCache(response) {\n let responseToCache = response;\n let pluginsUsed = false;\n for (const callback of this.iterateCallbacks('cacheWillUpdate')) {\n responseToCache =\n (await callback({\n request: this.request,\n response: responseToCache,\n event: this.event,\n })) || undefined;\n pluginsUsed = true;\n if (!responseToCache) {\n break;\n }\n }\n if (!pluginsUsed) {\n if (responseToCache && responseToCache.status !== 200) {\n responseToCache = undefined;\n }\n if (process.env.NODE_ENV !== 'production') {\n if (responseToCache) {\n if (responseToCache.status !== 200) {\n if (responseToCache.status === 0) {\n logger.warn(`The response for '${this.request.url}' ` +\n `is an opaque response. The caching strategy that you're ` +\n `using will not cache opaque responses by default.`);\n }\n else {\n logger.debug(`The response for '${this.request.url}' ` +\n `returned a status code of '${response.status}' and won't ` +\n `be cached as a result.`);\n }\n }\n }\n }\n }\n return responseToCache;\n }\n}\nexport { StrategyHandler };\n","/*\n Copyright 2020 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { StrategyHandler } from './StrategyHandler.js';\nimport './_version.js';\n/**\n * An abstract base class that all other strategy classes must extend from:\n *\n * @memberof workbox-strategies\n */\nclass Strategy {\n /**\n * Creates a new instance of the strategy and sets all documented option\n * properties as public instance properties.\n *\n * Note: if a custom strategy class extends the base Strategy class and does\n * not need more than these properties, it does not need to define its own\n * constructor.\n *\n * @param {Object} [options]\n * @param {string} [options.cacheName] Cache name to store and retrieve\n * requests. Defaults to the cache names provided by\n * {@link workbox-core.cacheNames}.\n * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}\n * to use in conjunction with this caching strategy.\n * @param {Object} [options.fetchOptions] Values passed along to the\n * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)\n * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796)\n * `fetch()` requests made by this strategy.\n * @param {Object} [options.matchOptions] The\n * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions}\n * for any `cache.match()` or `cache.put()` calls made by this strategy.\n */\n constructor(options = {}) {\n /**\n * Cache name to store and retrieve\n * requests. Defaults to the cache names provided by\n * {@link workbox-core.cacheNames}.\n *\n * @type {string}\n */\n this.cacheName = cacheNames.getRuntimeName(options.cacheName);\n /**\n * The list\n * [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}\n * used by this strategy.\n *\n * @type {Array}\n */\n this.plugins = options.plugins || [];\n /**\n * Values passed along to the\n * [`init`]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters}\n * of all fetch() requests made by this strategy.\n *\n * @type {Object}\n */\n this.fetchOptions = options.fetchOptions;\n /**\n * The\n * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions}\n * for any `cache.match()` or `cache.put()` calls made by this strategy.\n *\n * @type {Object}\n */\n this.matchOptions = options.matchOptions;\n }\n /**\n * Perform a request strategy and returns a `Promise` that will resolve with\n * a `Response`, invoking all relevant plugin callbacks.\n *\n * When a strategy instance is registered with a Workbox\n * {@link workbox-routing.Route}, this method is automatically\n * called when the route matches.\n *\n * Alternatively, this method can be used in a standalone `FetchEvent`\n * listener by passing it to `event.respondWith()`.\n *\n * @param {FetchEvent|Object} options A `FetchEvent` or an object with the\n * properties listed below.\n * @param {Request|string} options.request A request to run this strategy for.\n * @param {ExtendableEvent} options.event The event associated with the\n * request.\n * @param {URL} [options.url]\n * @param {*} [options.params]\n */\n handle(options) {\n const [responseDone] = this.handleAll(options);\n return responseDone;\n }\n /**\n * Similar to {@link workbox-strategies.Strategy~handle}, but\n * instead of just returning a `Promise` that resolves to a `Response` it\n * it will return an tuple of `[response, done]` promises, where the former\n * (`response`) is equivalent to what `handle()` returns, and the latter is a\n * Promise that will resolve once any promises that were added to\n * `event.waitUntil()` as part of performing the strategy have completed.\n *\n * You can await the `done` promise to ensure any extra work performed by\n * the strategy (usually caching responses) completes successfully.\n *\n * @param {FetchEvent|Object} options A `FetchEvent` or an object with the\n * properties listed below.\n * @param {Request|string} options.request A request to run this strategy for.\n * @param {ExtendableEvent} options.event The event associated with the\n * request.\n * @param {URL} [options.url]\n * @param {*} [options.params]\n * @return {Array} A tuple of [response, done]\n * promises that can be used to determine when the response resolves as\n * well as when the handler has completed all its work.\n */\n handleAll(options) {\n // Allow for flexible options to be passed.\n if (options instanceof FetchEvent) {\n options = {\n event: options,\n request: options.request,\n };\n }\n const event = options.event;\n const request = typeof options.request === 'string'\n ? new Request(options.request)\n : options.request;\n const params = 'params' in options ? options.params : undefined;\n const handler = new StrategyHandler(this, { event, request, params });\n const responseDone = this._getResponse(handler, request, event);\n const handlerDone = this._awaitComplete(responseDone, handler, request, event);\n // Return an array of promises, suitable for use with Promise.all().\n return [responseDone, handlerDone];\n }\n async _getResponse(handler, request, event) {\n await handler.runCallbacks('handlerWillStart', { event, request });\n let response = undefined;\n try {\n response = await this._handle(request, handler);\n // The \"official\" Strategy subclasses all throw this error automatically,\n // but in case a third-party Strategy doesn't, ensure that we have a\n // consistent failure when there's no response or an error response.\n if (!response || response.type === 'error') {\n throw new WorkboxError('no-response', { url: request.url });\n }\n }\n catch (error) {\n if (error instanceof Error) {\n for (const callback of handler.iterateCallbacks('handlerDidError')) {\n response = await callback({ error, event, request });\n if (response) {\n break;\n }\n }\n }\n if (!response) {\n throw error;\n }\n else if (process.env.NODE_ENV !== 'production') {\n logger.log(`While responding to '${getFriendlyURL(request.url)}', ` +\n `an ${error instanceof Error ? error.toString() : ''} error occurred. Using a fallback response provided by ` +\n `a handlerDidError plugin.`);\n }\n }\n for (const callback of handler.iterateCallbacks('handlerWillRespond')) {\n response = await callback({ event, request, response });\n }\n return response;\n }\n async _awaitComplete(responseDone, handler, request, event) {\n let response;\n let error;\n try {\n response = await responseDone;\n }\n catch (error) {\n // Ignore errors, as response errors should be caught via the `response`\n // promise above. The `done` promise will only throw for errors in\n // promises passed to `handler.waitUntil()`.\n }\n try {\n await handler.runCallbacks('handlerDidRespond', {\n event,\n request,\n response,\n });\n await handler.doneWaiting();\n }\n catch (waitUntilError) {\n if (waitUntilError instanceof Error) {\n error = waitUntilError;\n }\n }\n await handler.runCallbacks('handlerDidComplete', {\n event,\n request,\n response,\n error: error,\n });\n handler.destroy();\n if (error) {\n throw error;\n }\n }\n}\nexport { Strategy };\n/**\n * Classes extending the `Strategy` based class should implement this method,\n * and leverage the {@link workbox-strategies.StrategyHandler}\n * arg to perform all fetching and cache logic, which will ensure all relevant\n * cache, cache options, fetch options and plugins are used (per the current\n * strategy instance).\n *\n * @name _handle\n * @instance\n * @abstract\n * @function\n * @param {Request} request\n * @param {workbox-strategies.StrategyHandler} handler\n * @return {Promise}\n *\n * @memberof workbox-strategies.Strategy\n */\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport '../_version.js';\nexport const messages = {\n strategyStart: (strategyName, request) => `Using ${strategyName} to respond to '${getFriendlyURL(request.url)}'`,\n printFinalResponse: (response) => {\n if (response) {\n logger.groupCollapsed(`View the final response here.`);\n logger.log(response || '[No response returned]');\n logger.groupEnd();\n }\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { cacheOkAndOpaquePlugin } from './plugins/cacheOkAndOpaquePlugin.js';\nimport { Strategy } from './Strategy.js';\nimport { messages } from './utils/messages.js';\nimport './_version.js';\n/**\n * An implementation of a\n * [network first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-first-falling-back-to-cache)\n * request strategy.\n *\n * By default, this strategy will cache responses with a 200 status code as\n * well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).\n * Opaque responses are are cross-origin requests where the response doesn't\n * support [CORS](https://enable-cors.org/).\n *\n * If the network request fails, and there is no cache match, this will throw\n * a `WorkboxError` exception.\n *\n * @extends workbox-strategies.Strategy\n * @memberof workbox-strategies\n */\nclass NetworkFirst extends Strategy {\n /**\n * @param {Object} [options]\n * @param {string} [options.cacheName] Cache name to store and retrieve\n * requests. Defaults to cache names provided by\n * {@link workbox-core.cacheNames}.\n * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}\n * to use in conjunction with this caching strategy.\n * @param {Object} [options.fetchOptions] Values passed along to the\n * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)\n * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796)\n * `fetch()` requests made by this strategy.\n * @param {Object} [options.matchOptions] [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)\n * @param {number} [options.networkTimeoutSeconds] If set, any network requests\n * that fail to respond within the timeout will fallback to the cache.\n *\n * This option can be used to combat\n * \"[lie-fi]{@link https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi}\"\n * scenarios.\n */\n constructor(options = {}) {\n super(options);\n // If this instance contains no plugins with a 'cacheWillUpdate' callback,\n // prepend the `cacheOkAndOpaquePlugin` plugin to the plugins list.\n if (!this.plugins.some((p) => 'cacheWillUpdate' in p)) {\n this.plugins.unshift(cacheOkAndOpaquePlugin);\n }\n this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0;\n if (process.env.NODE_ENV !== 'production') {\n if (this._networkTimeoutSeconds) {\n assert.isType(this._networkTimeoutSeconds, 'number', {\n moduleName: 'workbox-strategies',\n className: this.constructor.name,\n funcName: 'constructor',\n paramName: 'networkTimeoutSeconds',\n });\n }\n }\n }\n /**\n * @private\n * @param {Request|string} request A request to run this strategy for.\n * @param {workbox-strategies.StrategyHandler} handler The event that\n * triggered the request.\n * @return {Promise}\n */\n async _handle(request, handler) {\n const logs = [];\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-strategies',\n className: this.constructor.name,\n funcName: 'handle',\n paramName: 'makeRequest',\n });\n }\n const promises = [];\n let timeoutId;\n if (this._networkTimeoutSeconds) {\n const { id, promise } = this._getTimeoutPromise({ request, logs, handler });\n timeoutId = id;\n promises.push(promise);\n }\n const networkPromise = this._getNetworkPromise({\n timeoutId,\n request,\n logs,\n handler,\n });\n promises.push(networkPromise);\n const response = await handler.waitUntil((async () => {\n // Promise.race() will resolve as soon as the first promise resolves.\n return ((await handler.waitUntil(Promise.race(promises))) ||\n // If Promise.race() resolved with null, it might be due to a network\n // timeout + a cache miss. If that were to happen, we'd rather wait until\n // the networkPromise resolves instead of returning null.\n // Note that it's fine to await an already-resolved promise, so we don't\n // have to check to see if it's still \"in flight\".\n (await networkPromise));\n })());\n if (process.env.NODE_ENV !== 'production') {\n logger.groupCollapsed(messages.strategyStart(this.constructor.name, request));\n for (const log of logs) {\n logger.log(log);\n }\n messages.printFinalResponse(response);\n logger.groupEnd();\n }\n if (!response) {\n throw new WorkboxError('no-response', { url: request.url });\n }\n return response;\n }\n /**\n * @param {Object} options\n * @param {Request} options.request\n * @param {Array} options.logs A reference to the logs array\n * @param {Event} options.event\n * @return {Promise}\n *\n * @private\n */\n _getTimeoutPromise({ request, logs, handler, }) {\n let timeoutId;\n const timeoutPromise = new Promise((resolve) => {\n const onNetworkTimeout = async () => {\n if (process.env.NODE_ENV !== 'production') {\n logs.push(`Timing out the network response at ` +\n `${this._networkTimeoutSeconds} seconds.`);\n }\n resolve(await handler.cacheMatch(request));\n };\n timeoutId = setTimeout(onNetworkTimeout, this._networkTimeoutSeconds * 1000);\n });\n return {\n promise: timeoutPromise,\n id: timeoutId,\n };\n }\n /**\n * @param {Object} options\n * @param {number|undefined} options.timeoutId\n * @param {Request} options.request\n * @param {Array} options.logs A reference to the logs Array.\n * @param {Event} options.event\n * @return {Promise}\n *\n * @private\n */\n async _getNetworkPromise({ timeoutId, request, logs, handler, }) {\n let error;\n let response;\n try {\n response = await handler.fetchAndCachePut(request);\n }\n catch (fetchError) {\n if (fetchError instanceof Error) {\n error = fetchError;\n }\n }\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n if (process.env.NODE_ENV !== 'production') {\n if (response) {\n logs.push(`Got response from network.`);\n }\n else {\n logs.push(`Unable to get a response from the network. Will respond ` +\n `with a cached response.`);\n }\n }\n if (error || !response) {\n response = await handler.cacheMatch(request);\n if (process.env.NODE_ENV !== 'production') {\n if (response) {\n logs.push(`Found a cached response in the '${this.cacheName}'` + ` cache.`);\n }\n else {\n logs.push(`No response found in the '${this.cacheName}' cache.`);\n }\n }\n }\n return response;\n }\n}\nexport { NetworkFirst };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * Claim any currently available clients once the service worker\n * becomes active. This is normally used in conjunction with `skipWaiting()`.\n *\n * @memberof workbox-core\n */\nfunction clientsClaim() {\n self.addEventListener('activate', () => self.clients.claim());\n}\nexport { clientsClaim };\n","/*\n Copyright 2020 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * A utility method that makes it easier to use `event.waitUntil` with\n * async functions and return the result.\n *\n * @param {ExtendableEvent} event\n * @param {Function} asyncFn\n * @return {Function}\n * @private\n */\nfunction waitUntil(event, asyncFn) {\n const returnPromise = asyncFn();\n event.waitUntil(returnPromise);\n return returnPromise;\n}\nexport { waitUntil };\n","\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:precaching:7.2.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport '../_version.js';\n// Name of the search parameter used to store revision info.\nconst REVISION_SEARCH_PARAM = '__WB_REVISION__';\n/**\n * Converts a manifest entry into a versioned URL suitable for precaching.\n *\n * @param {Object|string} entry\n * @return {string} A URL with versioning info.\n *\n * @private\n * @memberof workbox-precaching\n */\nexport function createCacheKey(entry) {\n if (!entry) {\n throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });\n }\n // If a precache manifest entry is a string, it's assumed to be a versioned\n // URL, like '/app.abcd1234.js'. Return as-is.\n if (typeof entry === 'string') {\n const urlObject = new URL(entry, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href,\n };\n }\n const { revision, url } = entry;\n if (!url) {\n throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });\n }\n // If there's just a URL and no revision, then it's also assumed to be a\n // versioned URL.\n if (!revision) {\n const urlObject = new URL(url, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href,\n };\n }\n // Otherwise, construct a properly versioned URL using the custom Workbox\n // search parameter along with the revision info.\n const cacheKeyURL = new URL(url, location.href);\n const originalURL = new URL(url, location.href);\n cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);\n return {\n cacheKey: cacheKeyURL.href,\n url: originalURL.href,\n };\n}\n","/*\n Copyright 2020 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * A plugin, designed to be used with PrecacheController, to determine the\n * of assets that were updated (or not updated) during the install event.\n *\n * @private\n */\nclass PrecacheInstallReportPlugin {\n constructor() {\n this.updatedURLs = [];\n this.notUpdatedURLs = [];\n this.handlerWillStart = async ({ request, state, }) => {\n // TODO: `state` should never be undefined...\n if (state) {\n state.originalRequest = request;\n }\n };\n this.cachedResponseWillBeUsed = async ({ event, state, cachedResponse, }) => {\n if (event.type === 'install') {\n if (state &&\n state.originalRequest &&\n state.originalRequest instanceof Request) {\n // TODO: `state` should never be undefined...\n const url = state.originalRequest.url;\n if (cachedResponse) {\n this.notUpdatedURLs.push(url);\n }\n else {\n this.updatedURLs.push(url);\n }\n }\n }\n return cachedResponse;\n };\n }\n}\nexport { PrecacheInstallReportPlugin };\n","/*\n Copyright 2020 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * A plugin, designed to be used with PrecacheController, to translate URLs into\n * the corresponding cache key, based on the current revision info.\n *\n * @private\n */\nclass PrecacheCacheKeyPlugin {\n constructor({ precacheController }) {\n this.cacheKeyWillBeUsed = async ({ request, params, }) => {\n // Params is type any, can't change right now.\n /* eslint-disable */\n const cacheKey = (params === null || params === void 0 ? void 0 : params.cacheKey) ||\n this._precacheController.getCacheKeyForURL(request.url);\n /* eslint-enable */\n return cacheKey\n ? new Request(cacheKey, { headers: request.headers })\n : request;\n };\n this._precacheController = precacheController;\n }\n}\nexport { PrecacheCacheKeyPlugin };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport '../_version.js';\n/**\n * @param {string} groupTitle\n * @param {Array} deletedURLs\n *\n * @private\n */\nconst logGroup = (groupTitle, deletedURLs) => {\n logger.groupCollapsed(groupTitle);\n for (const url of deletedURLs) {\n logger.log(url);\n }\n logger.groupEnd();\n};\n/**\n * @param {Array} deletedURLs\n *\n * @private\n * @memberof workbox-precaching\n */\nexport function printCleanupDetails(deletedURLs) {\n const deletionCount = deletedURLs.length;\n if (deletionCount > 0) {\n logger.groupCollapsed(`During precaching cleanup, ` +\n `${deletionCount} cached ` +\n `request${deletionCount === 1 ? ' was' : 's were'} deleted.`);\n logGroup('Deleted Cache Requests', deletedURLs);\n logger.groupEnd();\n }\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport '../_version.js';\n/**\n * @param {string} groupTitle\n * @param {Array} urls\n *\n * @private\n */\nfunction _nestedGroup(groupTitle, urls) {\n if (urls.length === 0) {\n return;\n }\n logger.groupCollapsed(groupTitle);\n for (const url of urls) {\n logger.log(url);\n }\n logger.groupEnd();\n}\n/**\n * @param {Array} urlsToPrecache\n * @param {Array} urlsAlreadyPrecached\n *\n * @private\n * @memberof workbox-precaching\n */\nexport function printInstallDetails(urlsToPrecache, urlsAlreadyPrecached) {\n const precachedCount = urlsToPrecache.length;\n const alreadyPrecachedCount = urlsAlreadyPrecached.length;\n if (precachedCount || alreadyPrecachedCount) {\n let message = `Precaching ${precachedCount} file${precachedCount === 1 ? '' : 's'}.`;\n if (alreadyPrecachedCount > 0) {\n message +=\n ` ${alreadyPrecachedCount} ` +\n `file${alreadyPrecachedCount === 1 ? ' is' : 's are'} already cached.`;\n }\n logger.groupCollapsed(message);\n _nestedGroup(`View newly precached URLs.`, urlsToPrecache);\n _nestedGroup(`View previously precached URLs.`, urlsAlreadyPrecached);\n logger.groupEnd();\n }\n}\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nlet supportStatus;\n/**\n * A utility function that determines whether the current browser supports\n * constructing a new `Response` from a `response.body` stream.\n *\n * @return {boolean} `true`, if the current browser can successfully\n * construct a `Response` from a `response.body` stream, `false` otherwise.\n *\n * @private\n */\nfunction canConstructResponseFromBodyStream() {\n if (supportStatus === undefined) {\n const testResponse = new Response('');\n if ('body' in testResponse) {\n try {\n new Response(testResponse.body);\n supportStatus = true;\n }\n catch (error) {\n supportStatus = false;\n }\n }\n supportStatus = false;\n }\n return supportStatus;\n}\nexport { canConstructResponseFromBodyStream };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { canConstructResponseFromBodyStream } from './_private/canConstructResponseFromBodyStream.js';\nimport { WorkboxError } from './_private/WorkboxError.js';\nimport './_version.js';\n/**\n * Allows developers to copy a response and modify its `headers`, `status`,\n * or `statusText` values (the values settable via a\n * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax}\n * object in the constructor).\n * To modify these values, pass a function as the second argument. That\n * function will be invoked with a single object with the response properties\n * `{headers, status, statusText}`. The return value of this function will\n * be used as the `ResponseInit` for the new `Response`. To change the values\n * either modify the passed parameter(s) and return it, or return a totally\n * new object.\n *\n * This method is intentionally limited to same-origin responses, regardless of\n * whether CORS was used or not.\n *\n * @param {Response} response\n * @param {Function} modifier\n * @memberof workbox-core\n */\nasync function copyResponse(response, modifier) {\n let origin = null;\n // If response.url isn't set, assume it's cross-origin and keep origin null.\n if (response.url) {\n const responseURL = new URL(response.url);\n origin = responseURL.origin;\n }\n if (origin !== self.location.origin) {\n throw new WorkboxError('cross-origin-copy-response', { origin });\n }\n const clonedResponse = response.clone();\n // Create a fresh `ResponseInit` object by cloning the headers.\n const responseInit = {\n headers: new Headers(clonedResponse.headers),\n status: clonedResponse.status,\n statusText: clonedResponse.statusText,\n };\n // Apply any user modifications.\n const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit;\n // Create the new response from the body stream and `ResponseInit`\n // modifications. Note: not all browsers support the Response.body stream,\n // so fall back to reading the entire body into memory as a blob.\n const body = canConstructResponseFromBodyStream()\n ? clonedResponse.body\n : await clonedResponse.blob();\n return new Response(body, modifiedResponseInit);\n}\nexport { copyResponse };\n","/*\n Copyright 2020 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { copyResponse } from 'workbox-core/copyResponse.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { Strategy } from 'workbox-strategies/Strategy.js';\nimport './_version.js';\n/**\n * A {@link workbox-strategies.Strategy} implementation\n * specifically designed to work with\n * {@link workbox-precaching.PrecacheController}\n * to both cache and fetch precached assets.\n *\n * Note: an instance of this class is created automatically when creating a\n * `PrecacheController`; it's generally not necessary to create this yourself.\n *\n * @extends workbox-strategies.Strategy\n * @memberof workbox-precaching\n */\nclass PrecacheStrategy extends Strategy {\n /**\n *\n * @param {Object} [options]\n * @param {string} [options.cacheName] Cache name to store and retrieve\n * requests. Defaults to the cache names provided by\n * {@link workbox-core.cacheNames}.\n * @param {Array} [options.plugins] {@link https://developers.google.com/web/tools/workbox/guides/using-plugins|Plugins}\n * to use in conjunction with this caching strategy.\n * @param {Object} [options.fetchOptions] Values passed along to the\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init}\n * of all fetch() requests made by this strategy.\n * @param {Object} [options.matchOptions] The\n * {@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions|CacheQueryOptions}\n * for any `cache.match()` or `cache.put()` calls made by this strategy.\n * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to\n * get the response from the network if there's a precache miss.\n */\n constructor(options = {}) {\n options.cacheName = cacheNames.getPrecacheName(options.cacheName);\n super(options);\n this._fallbackToNetwork =\n options.fallbackToNetwork === false ? false : true;\n // Redirected responses cannot be used to satisfy a navigation request, so\n // any redirected response must be \"copied\" rather than cloned, so the new\n // response doesn't contain the `redirected` flag. See:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1\n this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin);\n }\n /**\n * @private\n * @param {Request|string} request A request to run this strategy for.\n * @param {workbox-strategies.StrategyHandler} handler The event that\n * triggered the request.\n * @return {Promise}\n */\n async _handle(request, handler) {\n const response = await handler.cacheMatch(request);\n if (response) {\n return response;\n }\n // If this is an `install` event for an entry that isn't already cached,\n // then populate the cache.\n if (handler.event && handler.event.type === 'install') {\n return await this._handleInstall(request, handler);\n }\n // Getting here means something went wrong. An entry that should have been\n // precached wasn't found in the cache.\n return await this._handleFetch(request, handler);\n }\n async _handleFetch(request, handler) {\n let response;\n const params = (handler.params || {});\n // Fall back to the network if we're configured to do so.\n if (this._fallbackToNetwork) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`The precached response for ` +\n `${getFriendlyURL(request.url)} in ${this.cacheName} was not ` +\n `found. Falling back to the network.`);\n }\n const integrityInManifest = params.integrity;\n const integrityInRequest = request.integrity;\n const noIntegrityConflict = !integrityInRequest || integrityInRequest === integrityInManifest;\n // Do not add integrity if the original request is no-cors\n // See https://github.com/GoogleChrome/workbox/issues/3096\n response = await handler.fetch(new Request(request, {\n integrity: request.mode !== 'no-cors'\n ? integrityInRequest || integrityInManifest\n : undefined,\n }));\n // It's only \"safe\" to repair the cache if we're using SRI to guarantee\n // that the response matches the precache manifest's expectations,\n // and there's either a) no integrity property in the incoming request\n // or b) there is an integrity, and it matches the precache manifest.\n // See https://github.com/GoogleChrome/workbox/issues/2858\n // Also if the original request users no-cors we don't use integrity.\n // See https://github.com/GoogleChrome/workbox/issues/3096\n if (integrityInManifest &&\n noIntegrityConflict &&\n request.mode !== 'no-cors') {\n this._useDefaultCacheabilityPluginIfNeeded();\n const wasCached = await handler.cachePut(request, response.clone());\n if (process.env.NODE_ENV !== 'production') {\n if (wasCached) {\n logger.log(`A response for ${getFriendlyURL(request.url)} ` +\n `was used to \"repair\" the precache.`);\n }\n }\n }\n }\n else {\n // This shouldn't normally happen, but there are edge cases:\n // https://github.com/GoogleChrome/workbox/issues/1441\n throw new WorkboxError('missing-precache-entry', {\n cacheName: this.cacheName,\n url: request.url,\n });\n }\n if (process.env.NODE_ENV !== 'production') {\n const cacheKey = params.cacheKey || (await handler.getCacheKey(request, 'read'));\n // Workbox is going to handle the route.\n // print the routing details to the console.\n logger.groupCollapsed(`Precaching is responding to: ` + getFriendlyURL(request.url));\n logger.log(`Serving the precached url: ${getFriendlyURL(cacheKey instanceof Request ? cacheKey.url : cacheKey)}`);\n logger.groupCollapsed(`View request details here.`);\n logger.log(request);\n logger.groupEnd();\n logger.groupCollapsed(`View response details here.`);\n logger.log(response);\n logger.groupEnd();\n logger.groupEnd();\n }\n return response;\n }\n async _handleInstall(request, handler) {\n this._useDefaultCacheabilityPluginIfNeeded();\n const response = await handler.fetch(request);\n // Make sure we defer cachePut() until after we know the response\n // should be cached; see https://github.com/GoogleChrome/workbox/issues/2737\n const wasCached = await handler.cachePut(request, response.clone());\n if (!wasCached) {\n // Throwing here will lead to the `install` handler failing, which\n // we want to do if *any* of the responses aren't safe to cache.\n throw new WorkboxError('bad-precaching-response', {\n url: request.url,\n status: response.status,\n });\n }\n return response;\n }\n /**\n * This method is complex, as there a number of things to account for:\n *\n * The `plugins` array can be set at construction, and/or it might be added to\n * to at any time before the strategy is used.\n *\n * At the time the strategy is used (i.e. during an `install` event), there\n * needs to be at least one plugin that implements `cacheWillUpdate` in the\n * array, other than `copyRedirectedCacheableResponsesPlugin`.\n *\n * - If this method is called and there are no suitable `cacheWillUpdate`\n * plugins, we need to add `defaultPrecacheCacheabilityPlugin`.\n *\n * - If this method is called and there is exactly one `cacheWillUpdate`, then\n * we don't have to do anything (this might be a previously added\n * `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin).\n *\n * - If this method is called and there is more than one `cacheWillUpdate`,\n * then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so,\n * we need to remove it. (This situation is unlikely, but it could happen if\n * the strategy is used multiple times, the first without a `cacheWillUpdate`,\n * and then later on after manually adding a custom `cacheWillUpdate`.)\n *\n * See https://github.com/GoogleChrome/workbox/issues/2737 for more context.\n *\n * @private\n */\n _useDefaultCacheabilityPluginIfNeeded() {\n let defaultPluginIndex = null;\n let cacheWillUpdatePluginCount = 0;\n for (const [index, plugin] of this.plugins.entries()) {\n // Ignore the copy redirected plugin when determining what to do.\n if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) {\n continue;\n }\n // Save the default plugin's index, in case it needs to be removed.\n if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) {\n defaultPluginIndex = index;\n }\n if (plugin.cacheWillUpdate) {\n cacheWillUpdatePluginCount++;\n }\n }\n if (cacheWillUpdatePluginCount === 0) {\n this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin);\n }\n else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) {\n // Only remove the default plugin; multiple custom plugins are allowed.\n this.plugins.splice(defaultPluginIndex, 1);\n }\n // Nothing needs to be done if cacheWillUpdatePluginCount is 1\n }\n}\nPrecacheStrategy.defaultPrecacheCacheabilityPlugin = {\n async cacheWillUpdate({ response }) {\n if (!response || response.status >= 400) {\n return null;\n }\n return response;\n },\n};\nPrecacheStrategy.copyRedirectedCacheableResponsesPlugin = {\n async cacheWillUpdate({ response }) {\n return response.redirected ? await copyResponse(response) : response;\n },\n};\nexport { PrecacheStrategy };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { waitUntil } from 'workbox-core/_private/waitUntil.js';\nimport { createCacheKey } from './utils/createCacheKey.js';\nimport { PrecacheInstallReportPlugin } from './utils/PrecacheInstallReportPlugin.js';\nimport { PrecacheCacheKeyPlugin } from './utils/PrecacheCacheKeyPlugin.js';\nimport { printCleanupDetails } from './utils/printCleanupDetails.js';\nimport { printInstallDetails } from './utils/printInstallDetails.js';\nimport { PrecacheStrategy } from './PrecacheStrategy.js';\nimport './_version.js';\n/**\n * Performs efficient precaching of assets.\n *\n * @memberof workbox-precaching\n */\nclass PrecacheController {\n /**\n * Create a new PrecacheController.\n *\n * @param {Object} [options]\n * @param {string} [options.cacheName] The cache to use for precaching.\n * @param {string} [options.plugins] Plugins to use when precaching as well\n * as responding to fetch events for precached assets.\n * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to\n * get the response from the network if there's a precache miss.\n */\n constructor({ cacheName, plugins = [], fallbackToNetwork = true, } = {}) {\n this._urlsToCacheKeys = new Map();\n this._urlsToCacheModes = new Map();\n this._cacheKeysToIntegrities = new Map();\n this._strategy = new PrecacheStrategy({\n cacheName: cacheNames.getPrecacheName(cacheName),\n plugins: [\n ...plugins,\n new PrecacheCacheKeyPlugin({ precacheController: this }),\n ],\n fallbackToNetwork,\n });\n // Bind the install and activate methods to the instance.\n this.install = this.install.bind(this);\n this.activate = this.activate.bind(this);\n }\n /**\n * @type {workbox-precaching.PrecacheStrategy} The strategy created by this controller and\n * used to cache assets and respond to fetch events.\n */\n get strategy() {\n return this._strategy;\n }\n /**\n * Adds items to the precache list, removing any duplicates and\n * stores the files in the\n * {@link workbox-core.cacheNames|\"precache cache\"} when the service\n * worker installs.\n *\n * This method can be called multiple times.\n *\n * @param {Array} [entries=[]] Array of entries to precache.\n */\n precache(entries) {\n this.addToCacheList(entries);\n if (!this._installAndActiveListenersAdded) {\n self.addEventListener('install', this.install);\n self.addEventListener('activate', this.activate);\n this._installAndActiveListenersAdded = true;\n }\n }\n /**\n * This method will add items to the precache list, removing duplicates\n * and ensuring the information is valid.\n *\n * @param {Array} entries\n * Array of entries to precache.\n */\n addToCacheList(entries) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isArray(entries, {\n moduleName: 'workbox-precaching',\n className: 'PrecacheController',\n funcName: 'addToCacheList',\n paramName: 'entries',\n });\n }\n const urlsToWarnAbout = [];\n for (const entry of entries) {\n // See https://github.com/GoogleChrome/workbox/issues/2259\n if (typeof entry === 'string') {\n urlsToWarnAbout.push(entry);\n }\n else if (entry && entry.revision === undefined) {\n urlsToWarnAbout.push(entry.url);\n }\n const { cacheKey, url } = createCacheKey(entry);\n const cacheMode = typeof entry !== 'string' && entry.revision ? 'reload' : 'default';\n if (this._urlsToCacheKeys.has(url) &&\n this._urlsToCacheKeys.get(url) !== cacheKey) {\n throw new WorkboxError('add-to-cache-list-conflicting-entries', {\n firstEntry: this._urlsToCacheKeys.get(url),\n secondEntry: cacheKey,\n });\n }\n if (typeof entry !== 'string' && entry.integrity) {\n if (this._cacheKeysToIntegrities.has(cacheKey) &&\n this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) {\n throw new WorkboxError('add-to-cache-list-conflicting-integrities', {\n url,\n });\n }\n this._cacheKeysToIntegrities.set(cacheKey, entry.integrity);\n }\n this._urlsToCacheKeys.set(url, cacheKey);\n this._urlsToCacheModes.set(url, cacheMode);\n if (urlsToWarnAbout.length > 0) {\n const warningMessage = `Workbox is precaching URLs without revision ` +\n `info: ${urlsToWarnAbout.join(', ')}\\nThis is generally NOT safe. ` +\n `Learn more at https://bit.ly/wb-precache`;\n if (process.env.NODE_ENV === 'production') {\n // Use console directly to display this warning without bloating\n // bundle sizes by pulling in all of the logger codebase in prod.\n console.warn(warningMessage);\n }\n else {\n logger.warn(warningMessage);\n }\n }\n }\n }\n /**\n * Precaches new and updated assets. Call this method from the service worker\n * install event.\n *\n * Note: this method calls `event.waitUntil()` for you, so you do not need\n * to call it yourself in your event handlers.\n *\n * @param {ExtendableEvent} event\n * @return {Promise}\n */\n install(event) {\n // waitUntil returns Promise\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return waitUntil(event, async () => {\n const installReportPlugin = new PrecacheInstallReportPlugin();\n this.strategy.plugins.push(installReportPlugin);\n // Cache entries one at a time.\n // See https://github.com/GoogleChrome/workbox/issues/2528\n for (const [url, cacheKey] of this._urlsToCacheKeys) {\n const integrity = this._cacheKeysToIntegrities.get(cacheKey);\n const cacheMode = this._urlsToCacheModes.get(url);\n const request = new Request(url, {\n integrity,\n cache: cacheMode,\n credentials: 'same-origin',\n });\n await Promise.all(this.strategy.handleAll({\n params: { cacheKey },\n request,\n event,\n }));\n }\n const { updatedURLs, notUpdatedURLs } = installReportPlugin;\n if (process.env.NODE_ENV !== 'production') {\n printInstallDetails(updatedURLs, notUpdatedURLs);\n }\n return { updatedURLs, notUpdatedURLs };\n });\n }\n /**\n * Deletes assets that are no longer present in the current precache manifest.\n * Call this method from the service worker activate event.\n *\n * Note: this method calls `event.waitUntil()` for you, so you do not need\n * to call it yourself in your event handlers.\n *\n * @param {ExtendableEvent} event\n * @return {Promise}\n */\n activate(event) {\n // waitUntil returns Promise\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return waitUntil(event, async () => {\n const cache = await self.caches.open(this.strategy.cacheName);\n const currentlyCachedRequests = await cache.keys();\n const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());\n const deletedURLs = [];\n for (const request of currentlyCachedRequests) {\n if (!expectedCacheKeys.has(request.url)) {\n await cache.delete(request);\n deletedURLs.push(request.url);\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n printCleanupDetails(deletedURLs);\n }\n return { deletedURLs };\n });\n }\n /**\n * Returns a mapping of a precached URL to the corresponding cache key, taking\n * into account the revision information for the URL.\n *\n * @return {Map} A URL to cache key mapping.\n */\n getURLsToCacheKeys() {\n return this._urlsToCacheKeys;\n }\n /**\n * Returns a list of all the URLs that have been precached by the current\n * service worker.\n *\n * @return {Array} The precached URLs.\n */\n getCachedURLs() {\n return [...this._urlsToCacheKeys.keys()];\n }\n /**\n * Returns the cache key used for storing a given URL. If that URL is\n * unversioned, like `/index.html', then the cache key will be the original\n * URL with a search parameter appended to it.\n *\n * @param {string} url A URL whose cache key you want to look up.\n * @return {string} The versioned URL that corresponds to a cache key\n * for the original URL, or undefined if that URL isn't precached.\n */\n getCacheKeyForURL(url) {\n const urlObject = new URL(url, location.href);\n return this._urlsToCacheKeys.get(urlObject.href);\n }\n /**\n * @param {string} url A cache key whose SRI you want to look up.\n * @return {string} The subresource integrity associated with the cache key,\n * or undefined if it's not set.\n */\n getIntegrityForCacheKey(cacheKey) {\n return this._cacheKeysToIntegrities.get(cacheKey);\n }\n /**\n * This acts as a drop-in replacement for\n * [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match)\n * with the following differences:\n *\n * - It knows what the name of the precache is, and only checks in that cache.\n * - It allows you to pass in an \"original\" URL without versioning parameters,\n * and it will automatically look up the correct cache key for the currently\n * active revision of that URL.\n *\n * E.g., `matchPrecache('index.html')` will find the correct precached\n * response for the currently active service worker, even if the actual cache\n * key is `'/index.html?__WB_REVISION__=1234abcd'`.\n *\n * @param {string|Request} request The key (without revisioning parameters)\n * to look up in the precache.\n * @return {Promise}\n */\n async matchPrecache(request) {\n const url = request instanceof Request ? request.url : request;\n const cacheKey = this.getCacheKeyForURL(url);\n if (cacheKey) {\n const cache = await self.caches.open(this.strategy.cacheName);\n return cache.match(cacheKey);\n }\n return undefined;\n }\n /**\n * Returns a function that looks up `url` in the precache (taking into\n * account revision information), and returns the corresponding `Response`.\n *\n * @param {string} url The precached URL which will be used to lookup the\n * `Response`.\n * @return {workbox-routing~handlerCallback}\n */\n createHandlerBoundToURL(url) {\n const cacheKey = this.getCacheKeyForURL(url);\n if (!cacheKey) {\n throw new WorkboxError('non-precached-url', { url });\n }\n return (options) => {\n options.request = new Request(url);\n options.params = Object.assign({ cacheKey }, options.params);\n return this.strategy.handle(options);\n };\n }\n}\nexport { PrecacheController };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { PrecacheController } from '../PrecacheController.js';\nimport '../_version.js';\nlet precacheController;\n/**\n * @return {PrecacheController}\n * @private\n */\nexport const getOrCreatePrecacheController = () => {\n if (!precacheController) {\n precacheController = new PrecacheController();\n }\n return precacheController;\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * Removes any URL search parameters that should be ignored.\n *\n * @param {URL} urlObject The original URL.\n * @param {Array} ignoreURLParametersMatching RegExps to test against\n * each search parameter name. Matches mean that the search parameter should be\n * ignored.\n * @return {URL} The URL with any ignored search parameters removed.\n *\n * @private\n * @memberof workbox-precaching\n */\nexport function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) {\n // Convert the iterable into an array at the start of the loop to make sure\n // deletion doesn't mess up iteration.\n for (const paramName of [...urlObject.searchParams.keys()]) {\n if (ignoreURLParametersMatching.some((regExp) => regExp.test(paramName))) {\n urlObject.searchParams.delete(paramName);\n }\n }\n return urlObject;\n}\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { removeIgnoredSearchParams } from './removeIgnoredSearchParams.js';\nimport '../_version.js';\n/**\n * Generator function that yields possible variations on the original URL to\n * check, one at a time.\n *\n * @param {string} url\n * @param {Object} options\n *\n * @private\n * @memberof workbox-precaching\n */\nexport function* generateURLVariations(url, { ignoreURLParametersMatching = [/^utm_/, /^fbclid$/], directoryIndex = 'index.html', cleanURLs = true, urlManipulation, } = {}) {\n const urlObject = new URL(url, location.href);\n urlObject.hash = '';\n yield urlObject.href;\n const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching);\n yield urlWithoutIgnoredParams.href;\n if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) {\n const directoryURL = new URL(urlWithoutIgnoredParams.href);\n directoryURL.pathname += directoryIndex;\n yield directoryURL.href;\n }\n if (cleanURLs) {\n const cleanURL = new URL(urlWithoutIgnoredParams.href);\n cleanURL.pathname += '.html';\n yield cleanURL.href;\n }\n if (urlManipulation) {\n const additionalURLs = urlManipulation({ url: urlObject });\n for (const urlToAttempt of additionalURLs) {\n yield urlToAttempt.href;\n }\n }\n}\n","/*\n Copyright 2020 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { Route } from 'workbox-routing/Route.js';\nimport { generateURLVariations } from './utils/generateURLVariations.js';\nimport './_version.js';\n/**\n * A subclass of {@link workbox-routing.Route} that takes a\n * {@link workbox-precaching.PrecacheController}\n * instance and uses it to match incoming requests and handle fetching\n * responses from the precache.\n *\n * @memberof workbox-precaching\n * @extends workbox-routing.Route\n */\nclass PrecacheRoute extends Route {\n /**\n * @param {PrecacheController} precacheController A `PrecacheController`\n * instance used to both match requests and respond to fetch events.\n * @param {Object} [options] Options to control how requests are matched\n * against the list of precached URLs.\n * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will\n * check cache entries for a URLs ending with '/' to see if there is a hit when\n * appending the `directoryIndex` value.\n * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An\n * array of regex's to remove search params when looking for a cache match.\n * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will\n * check the cache for the URL with a `.html` added to the end of the end.\n * @param {workbox-precaching~urlManipulation} [options.urlManipulation]\n * This is a function that should take a URL and return an array of\n * alternative URLs that should be checked for precache matches.\n */\n constructor(precacheController, options) {\n const match = ({ request, }) => {\n const urlsToCacheKeys = precacheController.getURLsToCacheKeys();\n for (const possibleURL of generateURLVariations(request.url, options)) {\n const cacheKey = urlsToCacheKeys.get(possibleURL);\n if (cacheKey) {\n const integrity = precacheController.getIntegrityForCacheKey(cacheKey);\n return { cacheKey, integrity };\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Precaching did not find a match for ` + getFriendlyURL(request.url));\n }\n return;\n };\n super(match, precacheController.strategy);\n }\n}\nexport { PrecacheRoute };\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { registerRoute } from 'workbox-routing/registerRoute.js';\nimport { getOrCreatePrecacheController } from './utils/getOrCreatePrecacheController.js';\nimport { PrecacheRoute } from './PrecacheRoute.js';\nimport './_version.js';\n/**\n * Add a `fetch` listener to the service worker that will\n * respond to\n * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}\n * with precached assets.\n *\n * Requests for assets that aren't precached, the `FetchEvent` will not be\n * responded to, allowing the event to fall through to other `fetch` event\n * listeners.\n *\n * @param {Object} [options] See the {@link workbox-precaching.PrecacheRoute}\n * options.\n *\n * @memberof workbox-precaching\n */\nfunction addRoute(options) {\n const precacheController = getOrCreatePrecacheController();\n const precacheRoute = new PrecacheRoute(precacheController, options);\n registerRoute(precacheRoute);\n}\nexport { addRoute };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { getOrCreatePrecacheController } from './utils/getOrCreatePrecacheController.js';\nimport './_version.js';\n/**\n * Adds items to the precache list, removing any duplicates and\n * stores the files in the\n * {@link workbox-core.cacheNames|\"precache cache\"} when the service\n * worker installs.\n *\n * This method can be called multiple times.\n *\n * Please note: This method **will not** serve any of the cached files for you.\n * It only precaches files. To respond to a network request you call\n * {@link workbox-precaching.addRoute}.\n *\n * If you have a single array of files to precache, you can just call\n * {@link workbox-precaching.precacheAndRoute}.\n *\n * @param {Array} [entries=[]] Array of entries to precache.\n *\n * @memberof workbox-precaching\n */\nfunction precache(entries) {\n const precacheController = getOrCreatePrecacheController();\n precacheController.precache(entries);\n}\nexport { precache };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { addRoute } from './addRoute.js';\nimport { precache } from './precache.js';\nimport './_version.js';\n/**\n * This method will add entries to the precache list and add a route to\n * respond to fetch events.\n *\n * This is a convenience method that will call\n * {@link workbox-precaching.precache} and\n * {@link workbox-precaching.addRoute} in a single call.\n *\n * @param {Array} entries Array of entries to precache.\n * @param {Object} [options] See the\n * {@link workbox-precaching.PrecacheRoute} options.\n *\n * @memberof workbox-precaching\n */\nfunction precacheAndRoute(entries, options) {\n precache(entries);\n addRoute(options);\n}\nexport { precacheAndRoute };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst SUBSTRING_TO_FIND = '-precache-';\n/**\n * Cleans up incompatible precaches that were created by older versions of\n * Workbox, by a service worker registered under the current scope.\n *\n * This is meant to be called as part of the `activate` event.\n *\n * This should be safe to use as long as you don't include `substringToFind`\n * (defaulting to `-precache-`) in your non-precache cache names.\n *\n * @param {string} currentPrecacheName The cache name currently in use for\n * precaching. This cache won't be deleted.\n * @param {string} [substringToFind='-precache-'] Cache names which include this\n * substring will be deleted (excluding `currentPrecacheName`).\n * @return {Array} A list of all the cache names that were deleted.\n *\n * @private\n * @memberof workbox-precaching\n */\nconst deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBSTRING_TO_FIND) => {\n const cacheNames = await self.caches.keys();\n const cacheNamesToDelete = cacheNames.filter((cacheName) => {\n return (cacheName.includes(substringToFind) &&\n cacheName.includes(self.registration.scope) &&\n cacheName !== currentPrecacheName);\n });\n await Promise.all(cacheNamesToDelete.map((cacheName) => self.caches.delete(cacheName)));\n return cacheNamesToDelete;\n};\nexport { deleteOutdatedCaches };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { deleteOutdatedCaches } from './utils/deleteOutdatedCaches.js';\nimport './_version.js';\n/**\n * Adds an `activate` event listener which will clean up incompatible\n * precaches that were created by older versions of Workbox.\n *\n * @memberof workbox-precaching\n */\nfunction cleanupOutdatedCaches() {\n // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705\n self.addEventListener('activate', ((event) => {\n const cacheName = cacheNames.getPrecacheName();\n event.waitUntil(deleteOutdatedCaches(cacheName).then((cachesDeleted) => {\n if (process.env.NODE_ENV !== 'production') {\n if (cachesDeleted.length > 0) {\n logger.log(`The following out-of-date precaches were cleaned up ` +\n `automatically:`, cachesDeleted);\n }\n }\n }));\n }));\n}\nexport { cleanupOutdatedCaches };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { Route } from './Route.js';\nimport './_version.js';\n/**\n * NavigationRoute makes it easy to create a\n * {@link workbox-routing.Route} that matches for browser\n * [navigation requests]{@link https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests}.\n *\n * It will only match incoming Requests whose\n * {@link https://fetch.spec.whatwg.org/#concept-request-mode|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 `denylist` and `allowlist` parameters.\n *\n * @memberof workbox-routing\n * @extends workbox-routing.Route\n */\nclass NavigationRoute extends Route {\n /**\n * If both `denylist` and `allowlist` are provided, the `denylist` will\n * take precedence and the request will not match this route.\n *\n * The regular expressions in `allowlist` and `denylist`\n * are matched against the concatenated\n * [`pathname`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname}\n * and [`search`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search}\n * portions of the requested URL.\n *\n * *Note*: These RegExps may be evaluated against every destination URL during\n * a navigation. Avoid using\n * [complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077),\n * or else your users may see delays when navigating your site.\n *\n * @param {workbox-routing~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n * @param {Object} options\n * @param {Array} [options.denylist] If any of these patterns match,\n * the route will not handle the request (even if a allowlist RegExp matches).\n * @param {Array} [options.allowlist=[/./]] If any of these patterns\n * match the URL's pathname and search parameter, the route will handle the\n * request (assuming the denylist doesn't match).\n */\n constructor(handler, { allowlist = [/./], denylist = [] } = {}) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isArrayOfClass(allowlist, RegExp, {\n moduleName: 'workbox-routing',\n className: 'NavigationRoute',\n funcName: 'constructor',\n paramName: 'options.allowlist',\n });\n assert.isArrayOfClass(denylist, RegExp, {\n moduleName: 'workbox-routing',\n className: 'NavigationRoute',\n funcName: 'constructor',\n paramName: 'options.denylist',\n });\n }\n super((options) => this._match(options), handler);\n this._allowlist = allowlist;\n this._denylist = denylist;\n }\n /**\n * Routes match handler.\n *\n * @param {Object} options\n * @param {URL} options.url\n * @param {Request} options.request\n * @return {boolean}\n *\n * @private\n */\n _match({ url, request }) {\n if (request && request.mode !== 'navigate') {\n return false;\n }\n const pathnameAndSearch = url.pathname + url.search;\n for (const regExp of this._denylist) {\n if (regExp.test(pathnameAndSearch)) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`The navigation route ${pathnameAndSearch} is not ` +\n `being used, since the URL matches this denylist pattern: ` +\n `${regExp.toString()}`);\n }\n return false;\n }\n }\n if (this._allowlist.some((regExp) => regExp.test(pathnameAndSearch))) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`The navigation route ${pathnameAndSearch} ` + `is being used.`);\n }\n return true;\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`The navigation route ${pathnameAndSearch} is not ` +\n `being used, since the URL being navigated to doesn't ` +\n `match the allowlist.`);\n }\n return false;\n }\n}\nexport { NavigationRoute };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { getOrCreatePrecacheController } from './utils/getOrCreatePrecacheController.js';\nimport './_version.js';\n/**\n * Helper function that calls\n * {@link PrecacheController#createHandlerBoundToURL} on the default\n * {@link PrecacheController} instance.\n *\n * If you are creating your own {@link PrecacheController}, then call the\n * {@link PrecacheController#createHandlerBoundToURL} on that instance,\n * instead of using this function.\n *\n * @param {string} url The precached URL which will be used to lookup the\n * `Response`.\n * @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the\n * response from the network if there's a precache miss.\n * @return {workbox-routing~handlerCallback}\n *\n * @memberof workbox-precaching\n */\nfunction createHandlerBoundToURL(url) {\n const precacheController = getOrCreatePrecacheController();\n return precacheController.createHandlerBoundToURL(url);\n}\nexport { createHandlerBoundToURL };\n"],"names":["self","_","e","logger","globalThis","__WB_DISABLE_DEV_LOGS","inGroup","methodToColorMap","debug","log","warn","error","groupCollapsed","groupEnd","print","method","args","test","navigator","userAgent","console","styles","logPrefix","join","api","loggerMethods","Object","keys","key","messages","invalid-value","paramName","validValueDescription","value","Error","JSON","stringify","not-an-array","moduleName","className","funcName","incorrect-type","expectedType","classNameStr","incorrect-class","expectedClassName","isReturnValueProblem","missing-a-method","expectedMethod","add-to-cache-list-unexpected-type","entry","add-to-cache-list-conflicting-entries","firstEntry","secondEntry","plugin-error-request-will-fetch","thrownErrorMessage","invalid-cache-name","cacheNameId","unregister-route-but-not-found-with-method","unregister-route-route-not-registered","queue-replay-failed","name","duplicate-queue-name","expired-test-without-max-age","methodName","unsupported-route-type","not-array-of-class","expectedClass","max-entries-or-age-required","statuses-or-headers-required","invalid-string","channel-name-required","invalid-responses-are-same-args","expire-custom-caches-only","unit-must-be-bytes","normalizedRangeHeader","single-range-only","invalid-range-values","no-range-header","range-not-satisfiable","size","start","end","attempt-to-cache-non-get-request","url","cache-put-with-no-response","no-response","message","bad-precaching-response","status","non-precached-url","add-to-cache-list-conflicting-integrities","missing-precache-entry","cacheName","cross-origin-copy-response","origin","opaque-streams-source","type","generatorFunction","code","details","messageGenerator","WorkboxError","constructor","errorCode","isArray","Array","hasMethod","object","isType","isInstance","isOneOf","validValues","includes","isArrayOfClass","item","finalAssertExports","defaultMethod","validMethods","normalizeHandler","handler","assert","handle","Route","match","setCatchHandler","catchHandler","RegExpRoute","regExp","RegExp","result","exec","href","location","index","toString","slice","getFriendlyURL","urlObj","URL","String","replace","Router","_routes","Map","_defaultHandlerMap","routes","addFetchListener","addEventListener","event","request","responsePromise","handleRequest","respondWith","addCacheListener","data","payload","urlsToCache","requestPromises","Promise","all","map","Request","waitUntil","ports","then","postMessage","protocol","startsWith","sameOrigin","params","route","findMatchingRoute","debugMessages","push","has","get","forEach","msg","err","reject","_catchHandler","catch","catchErr","matchResult","length","undefined","setDefaultHandler","set","registerRoute","unregisterRoute","routeIndex","indexOf","splice","defaultRouter","getOrCreateDefaultRouter","capture","captureUrl","valueToCheck","pathname","wildcards","matchCallback","_cacheNameDetails","googleAnalytics","precache","prefix","runtime","suffix","registration","scope","_createCacheName","filter","eachCacheNameDetail","fn","cacheNames","updateDetails","getGoogleAnalyticsName","userCacheName","getPrecacheName","getPrefix","getRuntimeName","getSuffix","dontWaitFor","promise","quotaErrorCallbacks","Set","registerQuotaErrorCallback","callback","add","instanceOfAny","constructors","some","c","idbProxyableTypes","cursorAdvanceMethods","getIdbProxyableTypes","IDBDatabase","IDBObjectStore","IDBIndex","IDBCursor","IDBTransaction","getCursorAdvanceMethods","prototype","advance","continue","continuePrimaryKey","cursorRequestMap","WeakMap","transactionDoneMap","transactionStoreNamesMap","transformCache","reverseTransformCache","promisifyRequest","resolve","unlisten","removeEventListener","success","wrap","cacheDonePromiseForTransaction","tx","done","complete","DOMException","idbProxyTraps","target","prop","receiver","objectStoreNames","objectStore","replaceTraps","wrapFunction","func","transaction","storeNames","call","unwrap","sort","apply","transformCachableValue","Proxy","IDBRequest","newValue","openDB","version","blocked","upgrade","blocking","terminated","indexedDB","open","openPromise","oldVersion","newVersion","db","deleteDB","deleteDatabase","readMethods","writeMethods","cachedMethods","getMethod","targetFuncName","useIndex","isWrite","storeName","store","shift","oldTraps","_extends","DB_NAME","CACHE_OBJECT_STORE","normalizeURL","unNormalizedUrl","hash","CacheTimestampsModel","_db","_cacheName","_upgradeDb","objStore","createObjectStore","keyPath","createIndex","unique","_upgradeDbAndDeleteOldDbs","setTimestamp","timestamp","id","_getId","getDb","durability","put","getTimestamp","expireEntries","minTimestamp","maxCount","cursor","openCursor","entriesToDelete","entriesNotDeletedCount","urlsDeleted","delete","bind","CacheExpiration","config","_isRunning","_rerunRequested","maxEntries","maxAgeSeconds","_maxEntries","_maxAgeSeconds","_matchOptions","matchOptions","_timestampModel","Date","now","urlsExpired","cache","caches","updateTimestamp","isURLExpired","expireOlderThan","Infinity","ExpirationPlugin","cachedResponseWillBeUsed","cachedResponse","isFresh","_isResponseDateFresh","cacheExpiration","_getCacheExpiration","updateTimestampDone","cacheDidUpdate","_config","_cacheExpirations","purgeOnQuotaError","deleteCacheAndMetadata","dateHeaderTimestamp","_getDateHeaderTimestamp","headers","dateHeader","parsedDate","headerTime","getTime","isNaN","CacheableResponse","statuses","_statuses","_headers","isResponseCacheable","response","Response","cacheable","headerName","logFriendlyHeaders","CacheableResponsePlugin","cacheWillUpdate","_cacheableResponse","cacheOkAndOpaquePlugin","stripParams","fullURL","ignoreParams","strippedURL","param","searchParams","cacheMatchIgnoreParams","strippedRequestURL","keysOptions","assign","ignoreSearch","cacheKeys","cacheKey","strippedCacheKeyURL","Deferred","executeQuotaErrorCallbacks","timeout","ms","setTimeout","toRequest","input","StrategyHandler","strategy","options","_cacheKeys","ExtendableEvent","_strategy","_handlerDeferred","_extendLifetimePromises","_plugins","plugins","_pluginStateMap","plugin","fetch","mode","FetchEvent","preloadResponse","possiblePreloadResponse","originalRequest","hasCallback","clone","cb","iterateCallbacks","pluginFilteredRequest","fetchResponse","fetchOptions","runCallbacks","fetchAndCachePut","responseClone","cachePut","cacheMatch","effectiveRequest","getCacheKey","multiMatchOptions","vary","responseToCache","_ensureResponseSafeToCache","hasCacheUpdateCallback","oldResponse","newResponse","state","statefulCallback","statefulParam","doneWaiting","destroy","pluginsUsed","Strategy","responseDone","handleAll","_getResponse","handlerDone","_awaitComplete","_handle","waitUntilError","strategyStart","strategyName","printFinalResponse","NetworkFirst","p","unshift","_networkTimeoutSeconds","networkTimeoutSeconds","logs","promises","timeoutId","_getTimeoutPromise","networkPromise","_getNetworkPromise","race","timeoutPromise","onNetworkTimeout","fetchError","clearTimeout","clientsClaim","clients","claim","asyncFn","returnPromise","REVISION_SEARCH_PARAM","createCacheKey","urlObject","revision","cacheKeyURL","originalURL","PrecacheInstallReportPlugin","updatedURLs","notUpdatedURLs","handlerWillStart","PrecacheCacheKeyPlugin","precacheController","cacheKeyWillBeUsed","_precacheController","getCacheKeyForURL","logGroup","groupTitle","deletedURLs","printCleanupDetails","deletionCount","_nestedGroup","urls","printInstallDetails","urlsToPrecache","urlsAlreadyPrecached","precachedCount","alreadyPrecachedCount","supportStatus","canConstructResponseFromBodyStream","testResponse","body","copyResponse","modifier","responseURL","clonedResponse","responseInit","Headers","statusText","modifiedResponseInit","blob","PrecacheStrategy","_fallbackToNetwork","fallbackToNetwork","copyRedirectedCacheableResponsesPlugin","_handleInstall","_handleFetch","integrityInManifest","integrity","integrityInRequest","noIntegrityConflict","_useDefaultCacheabilityPluginIfNeeded","wasCached","defaultPluginIndex","cacheWillUpdatePluginCount","entries","defaultPrecacheCacheabilityPlugin","redirected","PrecacheController","_urlsToCacheKeys","_urlsToCacheModes","_cacheKeysToIntegrities","install","activate","addToCacheList","_installAndActiveListenersAdded","urlsToWarnAbout","cacheMode","warningMessage","installReportPlugin","credentials","currentlyCachedRequests","expectedCacheKeys","values","getURLsToCacheKeys","getCachedURLs","getIntegrityForCacheKey","matchPrecache","createHandlerBoundToURL","getOrCreatePrecacheController","removeIgnoredSearchParams","ignoreURLParametersMatching","generateURLVariations","directoryIndex","cleanURLs","urlManipulation","urlWithoutIgnoredParams","endsWith","directoryURL","cleanURL","additionalURLs","urlToAttempt","PrecacheRoute","urlsToCacheKeys","possibleURL","addRoute","precacheRoute","precacheAndRoute","SUBSTRING_TO_FIND","deleteOutdatedCaches","currentPrecacheName","substringToFind","cacheNamesToDelete","cleanupOutdatedCaches","cachesDeleted","NavigationRoute","allowlist","denylist","_match","_allowlist","_denylist","pathnameAndSearch","search"],"mappings":"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ACJ,SAAA;IACJ,OAAA;IACJ,KAAA;IACA,IAAA,OAAO0W,eAAe,CAAA;IAC1B,GAAA;IACJ;;ICngBA;IACA;AACA;IACA;IACA;IACA;IACA;IAOA;IACA;IACA;IACA;IACA;IACA,MAAMW,QAAQ,CAAC;IACX;IACJ;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACIvW,EAAAA,WAAWA,CAAC4T,OAAO,GAAG,EAAE,EAAE;IACtB;IACR;IACA;IACA;IACA;IACA;IACA;QACQ,IAAI,CAACtU,SAAS,GAAGyH,UAAU,CAACM,cAAc,CAACuM,OAAO,CAACtU,SAAS,CAAC,CAAA;IAC7D;IACR;IACA;IACA;IACA;IACA;IACA;IACQ,IAAA,IAAI,CAAC6U,OAAO,GAAGP,OAAO,CAACO,OAAO,IAAI,EAAE,CAAA;IACpC;IACR;IACA;IACA;IACA;IACA;IACA;IACQ,IAAA,IAAI,CAACe,YAAY,GAAGtB,OAAO,CAACsB,YAAY,CAAA;IACxC;IACR;IACA;IACA;IACA;IACA;IACA;IACQ,IAAA,IAAI,CAAC3F,YAAY,GAAGqE,OAAO,CAACrE,YAAY,CAAA;IAC5C,GAAA;IACA;IACJ;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;MACIpO,MAAMA,CAACyS,OAAO,EAAE;QACZ,MAAM,CAAC4C,YAAY,CAAC,GAAG,IAAI,CAACC,SAAS,CAAC7C,OAAO,CAAC,CAAA;IAC9C,IAAA,OAAO4C,YAAY,CAAA;IACvB,GAAA;IACA;IACJ;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;MACIC,SAASA,CAAC7C,OAAO,EAAE;IACf;QACA,IAAIA,OAAO,YAAYY,UAAU,EAAE;IAC/BZ,MAAAA,OAAO,GAAG;IACN9Q,QAAAA,KAAK,EAAE8Q,OAAO;YACd7Q,OAAO,EAAE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"} \ No newline at end of file diff --git a/index.html b/index.html index 83906c5..cd6e80f 100644 --- a/index.html +++ b/index.html @@ -1,23 +1,36 @@ - - - - - Copy Trading - - - -
- - + + + + + Copy Trading + + + + + + + + + + + + + + + +
+ + + diff --git a/package-lock.json b/package-lock.json index d5f31ff..5d37f76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,8 @@ "globals": "^15.12.0", "postcss": "^8.4.49", "tailwindcss": "^3.4.16", - "vite": "^6.0.1" + "vite": "^6.0.1", + "vite-plugin-pwa": "^0.21.1" } }, "node_modules/@alloc/quick-lru": { @@ -131,47 +132,1099 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-compilation-targets": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-module-imports": { + "node_modules/@babel/plugin-transform-react-jsx-source": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-module-transforms": { + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -180,82 +1233,119 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", - "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-string-parser": { + "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-validator-identifier": { + "node_modules/@babel/plugin-transform-spread": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-validator-option": { + "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helpers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/parser": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", - "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.26.3" + "@babel/helper-plugin-utils": "^7.25.9" }, - "bin": { - "parser": "bin/babel-parser.js" + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-react-jsx-self": { + "node_modules/@babel/plugin-transform-unicode-property-regex": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", - "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "dev": true, - "license": "MIT", "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { @@ -265,22 +1355,135 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-react-jsx-source": { + "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", - "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "dev": true, - "license": "MIT", "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/@babel/runtime": { "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", @@ -1092,6 +2295,16 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -1347,6 +2560,106 @@ "node": ">=12" } }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", + "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve/node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", @@ -1914,6 +3227,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dev": true, + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, "node_modules/@tanstack/react-virtual": { "version": "3.11.1", "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.11.1.tgz", @@ -2046,12 +3371,24 @@ "@types/react": "^18.0.0" } }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "license": "MIT" }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true + }, "node_modules/@vitejs/plugin-react": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", @@ -2369,6 +3706,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/autoprefixer": { "version": "10.4.20", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", @@ -2423,6 +3775,45 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2511,6 +3902,12 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -2998,6 +4395,15 @@ "node": ">= 6" } }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -3121,6 +4527,19 @@ "node": ">=18" } }, + "node_modules/core-js-compat": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", + "dev": true, + "dependencies": { + "browserslist": "^4.24.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -3326,6 +4745,15 @@ "dev": true, "license": "MIT" }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -3455,6 +4883,21 @@ "dev": true, "license": "MIT" }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.71", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.71.tgz", @@ -4051,6 +5494,12 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4152,6 +5601,22 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz", + "integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -4189,6 +5654,36 @@ "node": ">=16.0.0" } }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -4333,6 +5828,12 @@ "node": ">=14.14" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -4443,6 +5944,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, "node_modules/get-stream": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", @@ -4852,6 +6359,12 @@ "node": ">=18.18.0" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "dev": true + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -4931,6 +6444,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -5074,11 +6598,10 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, - "license": "MIT", "dependencies": { "hasown": "^2.0.2" }, @@ -5196,6 +6719,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", @@ -5275,6 +6804,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-set": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", @@ -5484,6 +7022,24 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/java-properties": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", @@ -5556,6 +7112,12 @@ "license": "MIT", "peer": true }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -5595,6 +7157,15 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -5621,6 +7192,15 @@ "json-buffer": "3.0.1" } }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5759,6 +7339,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true + }, "node_modules/lodash.uniqby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", @@ -5787,6 +7373,15 @@ "yallist": "^3.0.2" } }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, "node_modules/map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -8794,6 +10389,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, "node_modules/onetime": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", @@ -9036,6 +10640,15 @@ "node": ">=8" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -9388,6 +11001,18 @@ "node": ">= 0.8.0" } }, + "node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "dev": true, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pretty-ms": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", @@ -9456,6 +11081,15 @@ ], "license": "MIT" }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -9744,12 +11378,39 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "license": "MIT" }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", @@ -9769,6 +11430,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/registry-auth-token": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.3.tgz", @@ -9781,6 +11459,24 @@ "node": ">=14" } }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, "node_modules/remove": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/remove/-/remove-0.1.5.tgz", @@ -9800,6 +11496,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -10216,6 +11921,15 @@ "node": "*" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", @@ -10439,6 +12153,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "dev": true + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -10458,6 +12178,23 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true + }, "node_modules/spawn-error-forwarder": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", @@ -10681,6 +12418,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stringify-object/node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", @@ -10731,6 +12491,15 @@ "node": ">=4" } }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/strip-final-newline": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", @@ -10945,6 +12714,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/terser": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -10993,6 +12786,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/tinyglobby": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", + "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "dev": true, + "dependencies": { + "fdir": "^6.4.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", + "dev": true, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -11005,6 +12837,15 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/traverse": { "version": "0.6.8", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", @@ -11162,6 +13003,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/unicode-emoji-modifier-base": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", @@ -11172,6 +13022,37 @@ "node": ">=4" } }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/unicorn-magic": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", @@ -11214,6 +13095,16 @@ "node": ">= 10.0.0" } }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", @@ -11380,6 +13271,36 @@ } } }, + "node_modules/vite-plugin-pwa": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.21.1.tgz", + "integrity": "sha512-rkTbKFbd232WdiRJ9R3u+hZmf5SfQljX1b45NF6oLA6DSktEKpYllgTo1l2lkiZWMWV78pABJtFjNXfBef3/3Q==", + "dev": true, + "dependencies": { + "debug": "^4.3.6", + "pretty-bytes": "^6.1.1", + "tinyglobby": "^0.2.10", + "workbox-build": "^7.3.0", + "workbox-window": "^7.3.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vite-pwa/assets-generator": "^0.2.6", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", + "workbox-build": "^7.3.0", + "workbox-window": "^7.3.0" + }, + "peerDependenciesMeta": { + "@vite-pwa/assets-generator": { + "optional": true + } + } + }, "node_modules/warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", @@ -11389,6 +13310,23 @@ "loose-envify": "^1.0.0" } }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -11507,6 +13445,448 @@ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "license": "MIT" }, + "node_modules/workbox-background-sync": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz", + "integrity": "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg==", + "dev": true, + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.3.0.tgz", + "integrity": "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA==", + "dev": true, + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-build": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.3.0.tgz", + "integrity": "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ==", + "dev": true, + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.24.4", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^2.4.1", + "@rollup/plugin-terser": "^0.4.3", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "7.3.0", + "workbox-broadcast-update": "7.3.0", + "workbox-cacheable-response": "7.3.0", + "workbox-core": "7.3.0", + "workbox-expiration": "7.3.0", + "workbox-google-analytics": "7.3.0", + "workbox-navigation-preload": "7.3.0", + "workbox-precaching": "7.3.0", + "workbox-range-requests": "7.3.0", + "workbox-recipes": "7.3.0", + "workbox-routing": "7.3.0", + "workbox-strategies": "7.3.0", + "workbox-streams": "7.3.0", + "workbox-sw": "7.3.0", + "workbox-window": "7.3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dev": true, + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/workbox-build/node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/workbox-build/node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/workbox-build/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/workbox-build/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/workbox-build/node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/workbox-build/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "node_modules/workbox-build/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/workbox-build/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/workbox-build/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/workbox-build/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/workbox-build/node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dev": true, + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workbox-build/node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/workbox-build/node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/workbox-build/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/workbox-build/node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.3.0.tgz", + "integrity": "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA==", + "dev": true, + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-core": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.3.0.tgz", + "integrity": "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==", + "dev": true + }, + "node_modules/workbox-expiration": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.3.0.tgz", + "integrity": "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ==", + "dev": true, + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-google-analytics": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.3.0.tgz", + "integrity": "sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg==", + "dev": true, + "dependencies": { + "workbox-background-sync": "7.3.0", + "workbox-core": "7.3.0", + "workbox-routing": "7.3.0", + "workbox-strategies": "7.3.0" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.3.0.tgz", + "integrity": "sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg==", + "dev": true, + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-precaching": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.3.0.tgz", + "integrity": "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==", + "dev": true, + "dependencies": { + "workbox-core": "7.3.0", + "workbox-routing": "7.3.0", + "workbox-strategies": "7.3.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.3.0.tgz", + "integrity": "sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ==", + "dev": true, + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-recipes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.3.0.tgz", + "integrity": "sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg==", + "dev": true, + "dependencies": { + "workbox-cacheable-response": "7.3.0", + "workbox-core": "7.3.0", + "workbox-expiration": "7.3.0", + "workbox-precaching": "7.3.0", + "workbox-routing": "7.3.0", + "workbox-strategies": "7.3.0" + } + }, + "node_modules/workbox-routing": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.3.0.tgz", + "integrity": "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==", + "dev": true, + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-strategies": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.3.0.tgz", + "integrity": "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==", + "dev": true, + "dependencies": { + "workbox-core": "7.3.0" + } + }, + "node_modules/workbox-streams": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.3.0.tgz", + "integrity": "sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw==", + "dev": true, + "dependencies": { + "workbox-core": "7.3.0", + "workbox-routing": "7.3.0" + } + }, + "node_modules/workbox-sw": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.3.0.tgz", + "integrity": "sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA==", + "dev": true + }, + "node_modules/workbox-window": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.3.0.tgz", + "integrity": "sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA==", + "dev": true, + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "7.3.0" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -11602,6 +13982,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index ab92382..01304fc 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "globals": "^15.12.0", "postcss": "^8.4.49", "tailwindcss": "^3.4.16", - "vite": "^6.0.1" + "vite": "^6.0.1", + "vite-plugin-pwa": "^0.21.1" } } diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6b77a1f1331bafca3db7e21262d3ac7beab5fc5a GIT binary patch literal 919 zcmV;I18Dq-P)Px#4^T{0MgRZ*|IpL_qNo3Jd;dgF)fO_H0009vNkl($<1R1gkGLj?6r?ST&lHu0|&u)WMo-i885k?~!$`0O=B@}7G zn5py5MWf%~*bLBs%%J6DbtBNAWz~^ruaoG3K!c0-$f2#OhSoH?Bxn^VwC2$zK{piI zPeJ&s1lR=41&AV#nI z`;fGPvq!rITnWVJ&D0w>w-e~`6f`!~5@-+}D8}DL+lT?`9H2pXQF2N2a5{R57@*Dp z8iyA>!k`xp4KG7@3&Hos7>!oD9KC&35e>SB1bP641khuqJ=K9a2ThA1gKkB|7z{** zeYcbVopes`{jS4kEkQSXA;IRru|{;8KAK>3o6mInn*ZvfG1`I413p}L2)zmJV5vgD zk1fKv4A7~A3p*Chq5)`l-RK198+Se5bm)HROZ;#kFVK-e)QMOGjx?y1iv!W(po2Mh zceUc61Nc4)dzALT7W_>-kg*;&&tzgq3WU9?Qxth~j)n=-QaXxCGZ>TrV*KkR!6}AEBh6%b>*oGK3CYA@c zwso~h=82f>CUVGGqKPSb!VZf4R>##6MxV)cT5)VX=8b)@DnF_~BauO*Cj|S1%{1Ki tiqZX*@O*yvidWM|QkO1Wx^!tre*oLtlYtCyFarPp002ovPDHLkV1iuMu$=$^ literal 0 HcmV?d00001 diff --git a/public/desktop-screenshot.png b/public/desktop-screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..0c4b46c72e8b9f2020af3144c039570ca7618996 GIT binary patch literal 95071 zcmeFZXIoQS7cMNIAc`V3M4Eztbm_e)3R_x~-jR-oAWb>}3!(_9^o|8kLXl1=i3$jz zBnZUNBPE1h5<&@4cF^}`jJlYY4zaR+*CbChz_p3%oNnwsCg%MIkNy3NqUZof zcPOh(O!W6pPBJkiJ^lTU$GmNHb%!?gg+=_j$j{YcW54qKz39KIOPwpa9kx$X>p#x~ zKGxNBJNnPJ{{H3c>0<+mn)?b0{=3Cv=gt+$vHiQ{|NHeLhYxz671##?{r8Qg2AEHX zS@p|;jdvNgZF;m_OX+e(-hna6qU-~#mrwk6nNPfCMMu4+-ZPmbX&>IN#GIotC#n0E z{qGI^@5{OmnR)u$-@gQ#W*ys{8{z`#@Ndp+Bm~T!^|cW!h*)@$;6l7ARdqAhg`M2Q z!>{g5gSg03f^tz;Ew2;xn~$75Be&klb*Dn08hx6Jx03rC9E^U*D*wcjB?o!Wb7Cjq z+gqWppsfAhsu4H7a0r}~3toUcX=eJUGUza5^$;Jz@ zZl#>Lbj$4H&B3I_?KFk?I8oe@6QcUh1)V*P^-7(po@Eo7+H6Rmvy{p7&Go&8#+C?- zcojkn-w1?D&18ECe@%{7y3$Nq=awToa3xCdRS&=7l9a*7?bPmmLS-$^-Tbd0J{g~Q zUp3wJ{OQiO1D3i(LNC`tR!i!D@$ynu_V+k}f{VoXK7RSc?!M`u7JXlsExNEd$5XUE zV4h7e|Ka`RyIj@`wHfC|>*>Dt->Rga8ouwl6__-V7o;y$9oFH=tM9v+kwBTxO&egp z?b#8PJtAjC6BT(f8GTn@v$5;Kua*#J`&SW6yLA`D)m7+p;4BLpY%@cNbT!9PSJ=Ry zye_IE^JtPy;AVD#O5a|rDCQlmla8fxZMGAI)?lS$(`u<7_Nt~1G)vmi9j2z33S8mZkOn?)!(mJ<~^v_@1B&PrlzO_V37aBi zPquaA%5#1VW!58SPqxP&k<^xj?YL^vwuY)dF(2-j2tsM~6JbO)OPn#cKIfHR%rcHg z_{C*o)>H5ni5ZBPe&6>e_e86zi12K#nJtS2x%#sdRjAHdRJ)L=PNf||@o~9}PvM(J zDylWMA1EiiE7yxPIVcFmWDl(?01-BM9Ow&;UKIu*&c z*C}yhQ5sh^)G!gdaG1@&x8Y`o8|dmv(7ld@YD--I#x$4zu;lAERmbts;a1;&Q`w){{ z$pi|GMo{O7crpRiwml~42dr%42gMoMq@GgZ8Gh&79F5n&KJ7ehU;gMCMZuA3Wq+Sc zY6gvB_;T@u;F!Q$+v-k+F=_vC`z58ij+b6MKHjn}xH%xqrN>Hk;4y!q&_4e(3k+ML zL$mLJB(0XJ$aQZ@h*U>~M|;%XS)tQ*=Vl!JQ<^B>6UNueo@p%giF@09j1=lC+B&fvTg#g z#Om$}HMQ{C-rlRSFQs(o?wQr8u?e+{A=KKx=9=D4y<;+Qyd2bVlMCD`BlPeEvff)M zrjp#l5R`v!H2d~Bvpa6GMpk7lJ5uwoV}`ot=G#@V25L|$4C*{({rn-PwyGZ>FSE8DUd|DTBTbtOYfP>cbh*2HL(rqxq98t&NgXSueUw$cbTd-x5Hp-7oTqwtmUmPmM0_H zAJv%Q`TY}{aL!zzjMClgJxck+huSBaN)bO|#W~IS2g+MKI~Kb_?GMW1*s>cU`&vaz zLzWs)=eZa=UY3->r*>6$?0udloXUWh`WP-eKK*=WB8wgFCFTrS%sWuUse;K$usL^D00(phJ-zBnh-#W{`p3n%Vt%?jZZ4DarVsv)DrF>OiE;rYg0Mnl5S9J8Te@+=Y%TM0 zZxxufT;pZTDjQx{9){QuDU>}z$T%7fcc7<#zTTijrF7}gtEFmtqWzX)=K&R$W-^M` zE2K`~pLPD++hDSy9iSUV3+Ztt@w)!e%l2;LcN?WsvQa^}bnDZlD`2`7mHLT=v%~IA z#i{jhRAdjhcF?nbXuF1B{%ckcmU=LlRk3g)x`$dl%+xQVVX)F*)X{Z6F>GtonmH$e zeYmw3}_y75etK@GllJporUH>1yQ-hE}((P6XfSfUji@)18td%UE(kz9;O=v-=Zb zJ*yrH`9W9HV@raLjGp%Y@E`-1S#kfdX{~0PxXKCS+#N={#DH=8adnm)d|?%HPNV;n zn{LqFW>*(3)7eR8FKBU~1xs5)xcp_+?S8;8{xm7(BJ||aD7 z4!!#+$YLyY9S&x9l;1-Pl@TS zlXRvShF7+--=4bQKi_=$-&E=oul+4MmK+AnyTgmF;)-{4X7?^joRqjQN;-j#(*bGP zQlx5bbU6DZsFDr1X2tZQcHOwvM>J=qyUOm+_Mkv*(X^4tg{9uMYXDulc6W+ew`w!_1Bl-U`y*OW_cPxg19F7TrgJh+aXX!$^&F2j*wx_YwFW z5e*>Pda;|!ry+du9CCsOuZyJ@8`wq@6P@?oSd_Y38d|LdPohfv+^mRmQ?fh*?z&qq zQ=;Damgk;Q3<C_k^~r)My~k_ZM=aPBp&$_dz+B+FDCAa;#5;}$HO!)rM|46a{A6Mj zlH;ECMjU6FL{a%R;@JFv9;bAib-W(Wmb+@m+)IND5&QhhXkKc*@$#>w%myoWRsoaA zY415@k#I9226i%_zn+WR*~t+L4r@v1SAiT-AgF=VMQ6rUkZc!=`z23!z z-@D{m36&U$YPGa}w)0(_t2B=XC@h3!v~*kx!i7xLg=cigSIgn19WjN8s%vQpiB(}9 z<7sR0CH1EiN&0Xoyl>OsT6xozj=P~(_vXHom5Zl-WFbGZ2_h{mLp6PF84M~t2GVZL zqnaC^{*U++p&X@0b(Rd%_abH55k1))HwhV^ugIVfpUy!X0*9tt+T%OPKwLha5jAt7 z@FH3W>bvy*ZL)+8c*sO0ojPA23+)isds2&3mqh9?_7IyW9Le&!h#NjY)J_6Wlg5=^b2ddDLo}0#wiW+?`^9ur_G=Rva5Io^ zJ<}VD-kTMaHL9$M5Y_uIQ7Y<2>Z4sX-^uOW7x>!-Nl1;Z;C zP)A|yYV!^+a$*w==|k!pgBaw6n{_247Dl8E&j^&++TUUa;!qcVFXOL9A> zPOC+*d+aN;EU#aa3p;SISD_dqtGDjDuX=N9>_iz1h%?Q{w+12V0X1Re4j;P_uW7sa z5-lo79qH!K6HeQfWV&gEai_v|I%PA? zmA2e?Q^jP$D#&xsy?8)*+}Hd|!HT_~T^_Z2&hslz(=hKrFAtM=@etiqqxwMSY)fm$ z`u$RiX{dZA6M@=ED4Pk0$wbDvX8@lUgcN@bDxe1sTxLt(Cz)x!THPfOfVQ;mM2HnS zz%tNRc@BE;24$OT8$@_D4LRD7=EFmWPW&gajoa_!uR8=R%BqOc5)2q&;#!XcbtE(F zXy}{I-nZKPn>(p!EO(adjF--P=A2r%b3R9YV|fuGR+N*wCw88y zlhm~IDnVmCS#?DcE&4f|-`%qRF}Fe9ZpD(92B-8AU-Es60po-PGK0+xi!zu9HmYYc z5rS{Hc06fJ8DRvWv7zH)Gs!KG{KBAc^R=A3NTmCfjACP4*xFL};)A`JM6`e+6l}uD zWMUQJ5H|f-q^SFn5cwuT_kvzlIUi!f^WhQYi$-xZgCctIdrnrJb1@3xy(0QhtP$YL zXbwm~x9$DgLev7)1$8nnM2f1MLiS`jtff&0+(%xzm|6|E=Mqp6;lQC`qOEt& z4!9poqaj{ggm}yU=>8=7FxSB|E$+Gure~>eWf`cH&C0B61fhIoN4*Ih#Sx?C+M&^X z+r#@6p)U900h7h+80ng?x7AYDS~5LcpeSQ{wo$YEnO=!P4xhk>vlH*2l|nUa{k#iD z?9G31bYa9p#&>khmD%ao1Wxc$x_KVKqJ-P|CnmwgAR~O#hLRZFNw; zucH%?*uqT05c2duTChYa;Cd>`TzcZQX=Q|xe4UfkC@;w^<95QCwO0Q%qgvt??;^3*1>Uw|dYAtp6lg2%!AvA&E+kB2f(-ki88kKJ5>lx^Ir z^b5ADuNo(YRUkSwyBEl}5oIr~aXZ#ojLu=?7ZB$zNP+^h&8*OK?D{-r?jAq2n`TSM zuvF36o8~mSn3{Wt0e}e?drOykaw~gt30}K3Y$h@RJ?8-L)BHdbybb8RWbgYxy(tpL z8D1w#&PC`fpU5;-oqkjkC7x;GftCM+*meg8KAh$-Cj<=o7)B1f3jidIB?ibBAz)s* zsZ^r7ZYq;?jE-uVh{;#=&@vT5zqD_ZPi#2Am zZPF>EZ(B^*R8@Lr6koQy3pnJz+_th3s=&~)K&|1MTaEGDfRX#$o#DE%s$OV9W zoA_mjm;K#h0JSV*&I)Rl3h2@DMyiX^xEK2VZ@@D&y57k;7sA zQ(}}etkcEkQ26Tu2K@iS zEM;~rJ3y!kWj3UFuDn-wtY{+$;rh}cTfwXAySSr4g;c;rBA3tWaf3wS-Zb z*kx8FwFRi(>Hw{*s}ka)zH1gLOID{KKrzQdr^3D1B?uYV-b2ZnGineI<*Be)0?FZY z@KiWHy-4KY0}gxn0h>D&^@h4H;|yYC89L+|#8OHt&PjqtbuK!nFn6L|1mZ!+IDbPX zsD}!eiBXiP4s8ojszS25Oauyz$`udu!kIKNy^w;LwDe0M2Y%Wn14W(p?BX%RNmH}$ zB90_g!RfnU8=u*Xlt62GsYV6zpL#w@fMxt4NgB*DPu@IiwZV_H7z_oAoA=?ggK>lAj`VgQG_KKYo7ByIr(nX*dr zxVwLPWpEpld&p~J3$Md~YJ%3LUr`r^smpWopD1k;oMQgax{E3@$kY<~i+1-uALx}Y z=Xe4nN$`T###V#wHtCj%JX3Q8@`8Im*m`L)0OVA|6-cY)8FRNZWmSWA+@Y>E%IXxJ z(ga+^t3hRm8{tv8AY-Si*ie+EEEpN%bt&yNC|=FBGtJV-G?0MW|LaYVCsW+6o%X{_ z|2)2cQU9{C3=aK>W?VFp%2PC~gsxf$y_kAVm|kc|Hx3dt={dyIg#jST2fK_d*-S zOY_XTe|(WHK~b4vOUl(D~TOS6#Zy1DGjvUThbS)KZV z)?e6LR7{U3cn9Pt8{*?x&ZsIJfUMaJim;@quOP~bT8po@shHC0Ib4>g=#)${q6$Ad zAEZN`2*QmJG$$oMHFnV?bT4X7TJnxe^THd#2vm-kVecmn-1$vCQHuK&SiV-|G#|9; zECdVdlf*1&Ne7ixp<2c(MIjzb9_AF<#B9kjDJow4PSwo=7kCEeq^-Zq#VD#^)jtT8 z_KvuR4N*oYtH|w;7SwPk(F-p*A6x zVY#Z8dftftlkwU;xWxJ1Ld4}<)!T2UA9FtsTW=9=7%v%9Y)ZM+Rx!UMQ?!U^)2GZ^kf;`Jq&aXw~afk=1nOh~#3CQq-x!b%tbqT0hgKZC4C`BL2l`^qQMh`_V$Am=Z zRnjURX6>SoUAcpXjYyH}^+x{A5U0bbPTpLb04|ay;%wViHx;qmIg=>sRGRAZw=4n{Kblv4QC{ph^=GPXTO z;@Rd%#I&l{rMrvEcg<@eJR3n)2hNYKbKLbDy!*c^w@54t8ey!$s8t`=#N?zit$nIY ztp|dIGN?ZO?og7D^5`YkZ3iKx4>ctzw`e73a@lhb-_>nrg&qK9fNeT?e~|FP;H z%;xzjty5nWPYhT*)kAMT zq6rZ%)xoeSZqZDZ$r$RYPgWYx7w~_20g9O~klj9za~IEs0r9yHLGxeo&<|I)nA$yy zG)8T!Y}(Y@#>+#2Fn@cg*bG>jcR&8?CnM>43wE!G|6Fq4I(_0j`4ysQJ~Q*$-p+%v zHy(rc&uA4aZACPH3qNxM)8^}hn!P{IPT?CZ?Gv(cka4Y=6#DKIRAP-vdw#1Ve`c89 ziGMInBAbq8y*ydz(%W`hUVJ$)7cp&&DMdZYR`*_%_C>_L3F0xce~?}2RIe9mR2?yP zF+8GmUX%4#uXoUxEp9hLOVUJ!akrxwo*cIGt?ZLf)o7%uW4O8|F*qjSx}|EkNukjP zLeU$vRr1KO>^C!!5<2b;In`a9>$tIqi(PqAM(1IKxiUm4Xwpvd5+OC-5Hh z^eM9iS`sYTZnXSITCw}$toJutAvgp9yRAiE2SI(ktzfuUCE@dx$=@o;1Bh+qGsv`3 z|6tA>+wf0yN&nr+u?5GXJ2w;{vi@a}LrTwYtLAYHguVW~?W4-MhZLE??YY+!$@(9g0PY!d{h2dVvju-en19|r#Kj-juXuzrwp8rbi}9b*KIq-| zAEE!e4ApICX3mLc`!w{cO#bI^_AAc+_6Fy4i(HtPOxjs~EdEkU{+}BU=CeWnaZ^8c zHSjSuwq%-VW9#=V0{ts$zi$rcUn#;i1HaO8VCrhS1fkz_gCu&7RnK1k^VoD`}gs7 zGC)rdW&c3*@2?gPEJSoGI`HpT|F<{YUO>~N3->kunic=tgrY34Pz*=i?;7C^14lSlcN5eWic`TsT2NjoPUb7e~QbvKgHTV zj`L5&{BQRC2e$YJ9{B@X{F{CMfi3{njD1YW;ZIf0m+=`(V!SJ~a?v)qzx zT%U@#&L$~8OH!UvWj%W4*a=aZu@S-!yIN`VBZB$nUG(k;=KmWdvRIjz`W1^PTtJH1 z%Cn!~8mY^O3BUmz`k)xXY}nqWnCsroW-9qLB5{R@g|*|$VOc&wN_X<6j=le+2h(uw z<;#L4`sW}OyYlSv-9f^CdzmbCVBO(xs0tJF(B+~k_~XJsbBZ)A?NJ0hCi${e$3!Hy zEnxVjK_@WSa8fUxBf9^1Nh>x>&dv4p6d5jvkHY6=d5vhw z`AszWfi)rCPEpg3cSgE&1R_^p2G4mkzITQ?tC%1kq_Uekn+%p>{z6ioZsw#mmMF6A z5=JNyJwjQ#AsIxEfugv8%})3;VDND5jJ*3_Dkyu}jrdT((SR-+_m_{|CYm<4rE>;j z>-MOm$S`Cs%*q=lDS>zA=iBx$ZOntBC)e+6cnQ=;F6#tg2KeXTcM0pJLEU|{~n z4QM1>34qN();dy6la;KTrS(&|=1JlA?Cy6VO1q9M=!mZ@bHCM3dd}?>c0L}yW%fLp zf;*$(>HC~lr?Rg-4^P2P1oiU=^(%n-lb@QuEwNfj-&o0v>{R&ex@pj|@P znjT;dx4DiD7$@cwp4Yuqc3=q`JYSgU922fdnoGs$k%w0-Ulvv`-4X@gUlCT^Wo(x+RmzsX-22Y?_hY*0in1hRXp9}#Mr~5>KB3WDx{NM zT!D8@;M>YK2u^#T`_8&g4ewC>JisOYm~M1@Ybe^_g$V> z6e^CQ8bM)=lS5tx>#Q_g!|xO@E@#+%tp_}{c{d`Yav#!$Zk z?|f56poOZdb4!;Iw%M8K+Opb^Lff8H0S8kwAj zyvGP@m)xk?L2|P33b$HU8^E0=j2(lC5RBs{F!Yyh*fv2dYdk!cSE%>osB~$cbZuWv z^%CHmc9$yzA?3|Jx5Kn!#wGVWR}R9e1+?&AfZ3*#p%VcHDTQi=*A|N|2kcB6bi4tk z_hnOfy^gk3$J^dvZ~d@;zoLKH^e_)|ZKbZ4ZtZ#uwKG3-LfeGNWU?LECb!guq7+6TZJD&l;5kj2F<-t-q?kHj`=`q-3L-oz7Tx-2+|ZHh;nw z=-rB+Tz@9#HqJZn&h>*nh0!Yy+rtUZrhr>Zq{xdh6B0)4fc1r7Y*kEE>5r^W&ybFt z{_Yk?K$Lb|(}7={&xx!oyHc8KpKR11Tu2^qOG!MUY@_pat0wRLQLs$g3PE*y#6K-@ zJVNajz8#a28`t+#tiY!1R$wbpv?x0S>x{i94Vi*aJAt9y6Bvge6I+>3292C)m>tzN zJROOIuO%Ob;JuKO5%hT~-B7afq(8VzW9DwIzf+sQV@3Zoak=*KY~m6y5uE^xPy5SJ zS0-g~6%WX90AmF<8JFQ$(u!xNcVwtRJt)La#W-9$+k7*`>dSnj#0q(M%XE9=jaf2mnB;C(m5fm z+6VKi{@}@%WJIt=EY^cEcr>saN}&U;BX%;e*#t(^+* zHiw1p_WshnB&Si#4|J&#`m;;J?9MDGp&sJ|>5|Bd>YH$z{mjPTrLNS5J{Qm`^WCRe z94ngAhTK@`mIbRhtxb2lTaw$o#)#p15`} zea~Y{Y9rB4wlDJ5&X<65{hF_@)Xkb!PXzXYFfU4oU)~TI8nTBxA0K{HFlO~c(e~-f z*Q0uzIu0?A{KnP<=fI~TZuMxZBq(51&CUJYA8g1Wu@fyMItC_VG_I_p)<>R2oV z2NBF5mBb3zu^1qzxuUdmtgkec+byiUQ596sD}2bQuG%oUO-miu&|=9ckooHMb$Kp{ z9+97e=`SC~$g{C=BpjA)z6c9KHogVJ={TifN1SbFT%^~?XzFF;WciI=GL=Ri*J&8@ zf$%hB{^cJxxSZWp`{mACzxMKNe;d&36uKM&kM;DKQkuvF(&5WMjw1Q|f$}l$xKDNa z6-oa3sio?M)bzLV%bXtOyZv`!RC^O+H)p##zw-JY2VA;6JHHc1#DvC+jX*tWwjBM6 z;N~9v9s_mpAdOG&Rn_V!xOHpjc;jK5#o?)A!<0Qzr+I@;X6>AOZYxf%H{A7Rb4qSq zu&-wwm85CFuj*l42&O~B0IHB#T(z6qkD|-Cx~lSnJ)03)v(EFg?+zp1!XttmLeQ34 zYm2YAUx!C@8)y?=Ugtd!3SJ53kIlQkyBP5K0C!r$cHQkD`~hFBDpSqHcQ(;zv{1^& z_2#%B$IT$>YG?-&+X`0LzYTlC$}~TaAYMK5OwxGDe}TlRm>*Q#dekYsq{OQpy8JvW zKNv>uxpRLo2tH5B;q5bxs6Zy%H@@u@3ai@Mj#ym{@a!a)?A8;yg;UbX%DV)?t&c8h zJyr-glj>rGmv%OqTunuX7pm7e1Ux=vG@ypvBc_wyEiZFr~iKvLGv|ZOaS@^fUVht$Y1@cO_mQTsHP+LrL zdEa~Oj%~?P9JUQQo?BUA;S;^7G81fHi#|W>xkd$un4DsQ^2k-PS89jhQG=`P74!}5 z;ue@hUruncx8vnk(>?ER3iq;$2ldH$^~o9drP&KgDd_r^~|nt$mn{`f5HtQEvuGIkxoAuUR{7v3SM||-BJq;6RIM=`-rH*FyOC)NDNw!XPvMC zM+!hQlUW>fLe%tPI^RRqqt8b1Sz4Zj(aC2N-&e|%jmg!2_HmxSi|LXI3N_Op)@K_{ z=qI1yddSB46pGKL)*G;dhJOwwPXR6BNqlrOz=M`Ns^k%vi~I(heQ9r`xwG>SX-|W( zcX;Nx0%{?^d^M_7{X!oD+oUYZ1>lDQBM&JyC)-Yehu`0n zix}=co`4VH6i~d#dIX92Iv~OKG-e3r{$;H|LlRHG)~tZS+c^2v7vZD5i-93Kauixw ziqTL+BtK|Xb(rB4l62qd+Eic7y^Z#laIP32`RTzLJU`>K z&5fYWA8=B;=`+%bQ)x<+ZLk4IiH=tJO)NwEB=8(#P0Czq@w0`=^$4#I&;P33+L>IB zvCdGk{1(tSPVD(s^Y&KA)Qv zP@Cr(>&=q%%@lB2V!_&%MqlfYn;Pe)XlvxO!^pkJ77vyX>nd-vdw;iyu18R303tba+!@@2n;0aA@IXRVKd3OD^QCFHchs2=9mBIF{IBEZNJl2fj1X zMn;pd+?+aF_cS->PI&muPk}~}qn^Dl+#75F3Iexp*G?ykWH`v5w)1{1U$uP9%jfG` zdSh|rgQr*-PXWM9+_&QHrqmpx#3s26B~JDStrZd6Zd*rJwY03mG=SW5T_jhqqunC+b8G~%BG{Xjg}R>y!&94^L|e`JX2lj94g z9hJjI*@mQ}?J4Wd$cJ(`3Q$dVA{a2!3MdtT(*6^-be&mpc2(Z<+>4q{bbbz<&#K+a z&;SQzfs^?a8upZTDBMm`+~>ouE<1)!S~4f>>5flc3!Gfo+h>(urT`dsr)=k0NY%~l zi&=yIJ4@K_xGDa|$ryVe$E(=<#6mWRKN&8Ue_q#VKL)ObqT-*7>mkWXo0t>h_6I=x``mB5WYT5Gz?s%o%p1;wAnG$4?LAMn_eQ}J!R8L+ zO!(E9eaK_t{qidS8kFzKplv6;1VRI6Rrt$R@>FCxESNl9zZHg_hOttAyOj6J=9UWT2u*1hlyvBV0}t3j0u;A;G&b ze_PKsX*1E8E(CxwdGewm-WUpB$gNr;QZNY=Gm|Q^mz!~{=;#yq5kq)h;-vI=mZo6P z+aD)PpVxnPASxXV*$E(_F&!_R)oM^^h0(RfVO1>oU2OYKc}g=N-tqcO~R1xfZ46Yzjg!ezG!}9k|JehaD|5eB2LEGnUwSTi`_FE8g z4&w)>H8gFHE%y|TB3nV)`USe7gzI7Y0>?O-#Oegu(^TYcRo)I;m14X z37zL3K1tiB_OM#%yG?DYPQ}MBY1rJ7dBHeeH+A=88>6V0l2$fS1LG#E!<|Z~CtuXS zWf8?Pt7ldQJzn=-#C?JSmOa%K8Bv9*!cX)BNR^iMt6=BayqC!6LdP(dDC)RZ=1^b6 zm=qQ8*ivF;ZT`9BujT*;EtooPvPp(xZN5C`cxrgy`yC~fFW$Kdu1$|SW^op&`VbG6B1Rj zTQiFNqmzM%)kO=K-el0X?8cU8y=5r|qG62E3$+AmMe4DJ@Y*Cgb+}D)??w{!9 z#PIB^fbA{?%sdq{J#;BTmV!FxveV7w0ngyT#v9vt4v{`DZ{YO=ckit*o{ofiWQJSfj6&ix&($!yq-fn=-(-fu-seX* zjLr-L;6-t!lMjL2l;QxGy1P9q=h-uvPWNpAJo$*orS7h*R)6!+j+W+)%7^cE>t7LX zr>9##1)w;YpX?6WPrOrE0APOx8;W&wVgpmD*xBl?vK#OBR{)%~@9=9;{TL%@faGS% z{Y*AD#`bA7#a=~r`X=bS2|(A?=?W`|I3%+iE81QfrG;BL})vo`BET!?q$GgJ!aeH zsd=MtAr&AQlsa|lZI?x)0-CrZrlTbbqx26&Mpby&2XeqS9?JsIUHMIA6{LBr{6R?j zXaqf2B?Z_)82~J+SNAKgCy~C}g9(HRj=$uidfmPPNes4wg;U#xIkkN61NKR?wx^b? z!ah6i&yQUn9#KiSi)GLO2+3o&)uMJ+rOBCHkwBBc_W_`TMF#J@>^^m8UecW!p!9R` ziN68>7PrIidZLYzZ^Igzd54g(^Y2nkV*qpMEeU+O0AQ6C{fz?jBM8jrg2=T~f|KE; zW^v?kEM2)0w#zA^*lSh*a6CK5zgxU%!0*VMT+bUT%Nn|^DK4VcawNCH^H>wrLAa?toLV4Qv^b$~4|uZ4d1wwK;=Vnt2#Mn?j5 ztxZLyZELWJPzI!c)ODG6A7s6W!}(Rwt9Pom?e1KwbXnhJs)UX7V(Yvv1tF?ro<^>> zG)5(qXHtTlR)U|5kXWJ|JyNGXod!%Y`C)(b>E@ONi0lPF_$>0c?v~Z%RKZ(VDB8+{ z@#-gm!zMrm0*iXT;_DSN(1*QrpL<~L$qIn|%=wQJ-)P9r5rpK8)`{UTI?1gku(E); zde>D{Qi5>hL(r(Pb?t8BxXNTy5Z^XMuk=ig@gBoS8E}0VR~qTNEYp+@gHolsP{dN& zr1`#59f57|qknHSCO%nC46_pUFI*TsQ!BP=S4)?p~U99=D;+1 z+`uQmH_~RSz-_Sor6f$Vw!fB_`omZ17kiFfYJUleCYV=K#+79)4~2|J9%5eVqKsqx zo;&Z&a0dVk7nzA&l~tJCncC&qt>NT6BG1X_4Hm(Rr$i^)oHST+%1BR#+0HG#Gx9)e{Q>$RP3LY~@ z1>@nfq)0qUruCw!79diVoJ^+(xos>XcEo+wWM;)5tU(|-!YhqJEG>*26>dOSa%Pit zv}K@kuK=SNS}tlN$L;~VaeTo8=d0TrA>ft2djYm5*Ef}vs@TXPz*My}fXhVR3>0ME z@6`Acm+>m3tpX%gyFw6{4MIc@is}r7liSQ#vEz0`LhjgfyW11~`w74u$+{9#zog*2 z=+~;MoshgxdU!E&5&hg`rrBZvbMD@YTtN%s!3pN45#(L*tNnj=`yx&=+!A} z6L-#-fxQ_(g87v*W`icclG1$0r8wOx`Gl$FYbo^4+aHI>N#~ga;iH8!$6s4#5cmY_ z;drefK0t#9i@Jwi9@Sji5#F9Y2|=`jgeOda_}>6N=Spba>}gY=ie-uPvOk90-P~I0jHo z1<()RL1c1CaIaww06ADlHT}3^-nz5CD)=N~YJ#@T=ztXu-ralGQ;1osvVfavZ@uR1 zEGQhWRgd<+QXlocfEr#np||kziC}i!@VnCJoIq3!d-WVZaIP6HH1@6w$RQ%^?abLI zhowI1vNsSz($+o9HByE|Symn7LpMG@0XV!WZ%F9Lw(Qj)K6_xwlEi6l_D|G!%;t`l zwUMX(Kla}GDX!?*7Y$+X05d>BaCZm+1`qB8*8~mj?(RW?TX1&^?iwTz0vX(cyTf2Z z2zT>6_nf+~ZoPlt)%%eu*u$*7R(F4-dv$2cz_nI1cc$L6Kkc6twIH=r0qiRA`R>nz zZV_7AQ&ml~I>iSphNWEqBQEL!6d+fxVOh>UN4ij9Ff)L$j;%+dR-Rp6b4X)AfykVfJ~;pfy1+{^0|U+5RlO+znFc=%f~2^6so5iR zV#xFS9bi@XnS(FH7FRBjxJ-JPtghrYgLW%$J7PxFCb?17FwRV<(nW@qDWYyDIW4k! zXQBPIeOkEkIY2zvZ9KZKaDRT0UA+_)R+YEUmREkCNchZ)DqT#?!!8>b==h*Jy?ZmJj8muew3Gi0Lb@7Y^WQO%}dE0%T&ldsboGh1f$qYxTbnv<}*-)yjC}q8q((iCDp8sHCVQ?f} zyFb~6#ce$uUr8;uO3X16#a$hueKaS@HH>+3cXd-|yHOmmnKVV_R z?w;L6x<$^mM}+R;iUiz1x7642e1i@?!az|P3BB@d1`C?+TZ``m>dE1X(b&)y?2l(f zu33jlPY6Wi)isD;b%~2o#b<+6K#K0fY%^M6qCC=+4H(40Js-HJlQ$xNdlA%XeSO1J z$&SYu`1EQaf~T%nEl~{~M|-NXA0QULZE4sTItp^BNPIdJg?O4b2HX#4V^GjH^_2uq z)}g`D3gQUMW}|V-U}+meFg{kHbe9#e7!4B(>}5K)4UaZ&5Ufzx)ewPI9p!g_qn<15 z*XkUuYG~SzGoh80s8y{K)})qq2==;SF2y)rz&}w6I8z{uhto%3ZEEluS~6m>_%#36 z*FeT8;{&Ok%^3!8(^d>f!%|!RWQ-^gGowdhi+(}MzyI=zt)74lW&hc__V4BcjvQVG z^3pN6#hfCZ7q9u^D~n$jE03IBZjDP&I!C?i`sdTvX9bGUW4BB8I`vXxH?fhL9To!D zak~zyc&`QBs}~PPUPi)EB^jzcG%+|Q8{*rTY{D!;(96IJtSMa~~ERLS~4$=Pp;O1q!IP)jb^ z>64X?DGq#bc?Vuft55y1c9rTKI4R#$a%fngSx}@;R5nM81q>VTLuR$CDr(Eu4XGeZM3RPL_i@oV>$Hz!@PjW;9?Vk$LsYEyZC7 zqbCbN!%CiiES-VE*@*WM$?xm==8*b?vDAtc=^s2OBBm>0-xMkqVj((xA-`o-b5whtWn@5h?mOwEF11putBCgNsh%hvwxM7AQvs z`F-jHx1Al>e48wcdnb-jgUM=@ZJ#I(?{Vlcse8}%lg6zH9El)$=ZP+K;mFd`Wwj|C z8t{19gI$hJz(=PiRcR_WTmPZWxj26(PO>+egg5rYzF_}gEuHfu0uc`tQnpCsi0PKT zI-D()OJb>O`Zg~CHL#d4AKqcAIz~g>ZoDM;ti>;J1 zXWff3`vT6X3toWnYrHJ$12a;Hssh2958GRD;WBJW!f!3#f zFj|*`DP+7$mkPez8QUBhh>Y3>}yKG;tKclkS z9!Ff28yCxy#vq~5GanFtUH{W)#dYZTsnB{SdW62&H7wxm}ypeDKA^ZaW`1_z~cjkJF8&RFJDtx-RtFnQ*~p;_DVgvevS z?*xZ#IT(b)g;r7oJ%gw0fJ%pHgLQClu%3_BHA1E4^#oyoPf*fkZSC7vhrSo(rF_pB ztIJ7(zkxv={WmJB-F^z(%+PSb#2l{@w$iE~QKZkcEnE;t7LSR>os9ntKrJ|P=X010 zy-pPEMG=5z3%C`GXA88Q#`7KS6#3KP%q9jl zAP5c!JWs^ZTopYrs#49zG3(D?r6cB6qW*4L{XO@V458KPX!J9Mi%?wzMjjQx*MHOe zWgxjZ|NCpndfu^M^He;Q1S^Z>{v2x6>D|TlZZ|cVIt^0|EPbln< zxSLWkxugV8%&y+KZ|(s`2HHtaTsHzi5_2}55Hjb9{@KKjTRv`biBwiwXrzX$Rj-gC z*EeJJQW^!Na{;Z~2H3+$VS)G{0skAl35x{K-R(BU>CC#jUA#bp3Ykk|Cj~drkr^I2yzE=uM6X+R?*043D3~rZ_ zFL@Y6ZI?TfiFAvLrnB17bfnifWVJjqigi5sCK0LM7vaY(s}qQ;9UJ_`XL{f^P7}n7 zo5ii;ET^Q>Iu5AIEb9<2BV!szGYu5v(1+F<0u#-oB-O7IM`1S1e;&4jy?swbt)%?V zdoi&E6jODz{WHZxx8_6L^X)MbdH;X@dO3)rg@#76LoEbw<3T!Q6ZJE=WZ?s{GBPJK1Zz~A$B zMm?_3tb8SQQ?8IcnarzfFm!3HL69xrl{ouw&;D?KD$oLMo4GYZ6)S8(>mtJx3rRKu zLrax%^KDeMS2hq+rOKtiie}b8h!+lJ3T5K*sl)VxM{5SDnD`?xU%halAojF*-2d~g zoP-esq<*sJQF(30pY_~6P&vAQTU9|Zw!M!_t&ym>X~5lDYF}QB@na&*6^G{~aG=B@ zqrywi&Q=IWvliu2vDqRRZ39o+c25Xs1LLiG{#^?yX1xt^4t*`SSic@Vzmqmm_z`(P z0ypV=JA#fnDl&#H*;2~-^S4}f;AJgklT&4&5^<35iBnPr{Gu*75!Lbt-o!N@oWTtJ?^O-lQPy0AH5^;uaWM3Hw53Fg>h>>-=mk z&&%R>w%G=Xw@}XO_Z_tDC`@#Axqhi+8;xM7IO)2wq&pHrbS97CLmDZQZZm6>!(8ln zJ28<|*L|l^Mmv)!uK)c{mT&DqsP7uGnd(FSkV&6j!f-IsQD^c)eRC-0#fTt-O9a^` zL&MlVVwluFM|{-H-Y-(Ca^DIT9D%o0i{&*d^egFS%04EI;Oo(VWWCXeKYryvE&GFF zOek5uyL(amzR~v%69I2fW~0f3gRs$GN?tVC-Ls~=(ceKVJL)HACI2Fp`0~|P4ltg6 zwbK-@a#`uPDY`yhY~Kxk^#D=yL%_{1CRkUrcgSarG+s&a-(9?9ZjXG!WELZ$oGl>N z^A|zFrjM|TlI5Wx83xeC5HjQqB_)T&Sx@o1hbEf|I3QQ6rZ9WF6{}|BUu@^Hgi$Wm zQn_K4HXNi7(Bx|I4^Xn5l^WxNL{+7F9?o&9f5wWs!#$rMHyD3U6o8aRLbY&Ku0682Lya z5LczMaYFJF9I|n8)sa-RX<+UX#n#HMjd(szJv2g$KKRPysTHEJJekGAUfmA7jFZy8 zCK(tJ(s~}BFJZaT?p9vVwY(+Q{TJ$UZOg3Fh_0CNF6>I?-RO@fWEO_~E5}4~WNccI z78m29IGO|@00Wzo(YBau^!f6~=`5Iv$lt#E$>f8?>ie*h zx$}K4_+x|l7`o;+O3s)#UI`+ne0RX!OwlJpc8m;VDGaW^)!mi7TaR6 z5Y&tk^pQnZkE9N(Jy^bi>teNHZooN87vKgiVG3(ysFi{$&CMAox(sry(J)!9cX&*F z#}z3$Uh+^;Q!CJJr$_9eOoRsEXs&+`Yt;b{6tqEN77La0)q5v{Mos;TH4*FPc}@WnxA!z7vq1q!W{OA(Yoi-nDYLjclEk1WM?4{C zwbbkv1s}=l6^*3^iP3~ME+8Qdi=uP(Ox$BL8&tI(!o&m}!K`Pc-{Np(ZUZ%>uY|c) zIQDJ4EBQu9x9<|;MS(J}5V-UuoTd~!6MPq9Nzcz0R70?npHtND!B=&6Dq@o0TK5tR zrTjgb{AN(qN#Xac-W>7dQclQRaJwY1iB-^xh>)aUMMMHu5@CVjy(CZNOvo-})qQWD zMAadcH&c#X%2X@0RMg~hn+w0$GbPyE>fg9Q10k|ccU@p?K2^U~O_s4c*X&6zVTtc0 zH=(CS3>rMKIdl6o67w_E;re-U>MZ5?^$^w#^zJ4D$s#&J@{I}ZHd;8A!w+5NUP*9rd&B;nDBF=(1OK-K-h=y3ipESu& ztK3H%ezo@}WU1GC2BmJ`uTN=C1)R-}9_gI9riiP~+P;cSv=4D(QJDIJeidc%32r zw&M#S`?(N=$lPpHwjt;QZCJk%7;c`#th51N|8u<9TnNa85rs&ictm5`=n$Go%ywc% z8hg!2@^LPClNQ?13xWIv$O^pAH&W3IUwoh}}XcSB*8L}y0Fa5x#+Z-J^ z;<7vL)R-UP{l&%3BOun>n5~L-h~iLsFzV(02t&>mrpkxicS{G!c?syFKT}wy;8s&i zU~f%1*<5)=^eUpq3fYoZyC*B$Ud!raV~L+i_b zoI;2_6R7Fgr*4KE?99948?#RLG%N3Y41h|LR@>|#ZX0o-5f_ip1WSjY;u=4Yb=>H9 z|Fp$Q_54Oz{PJ`qqsf{pA;Y?+bt^MwR-d$;kIHiAcR=RPRHm`ljN(J~s1>JA=r&RcZBC9dU@z88_|%D{eUeZ~IKRvw04r{3Xi z7po$tpa7F(eIYE%CK@WUl_I-%wu-9$#j&N>l}LDO=(8@*gA&w|Hu>S4C(eaQx2Bzn zYB7gjv>ksUn$mJBnV4^F+8;=5CB<20ta&La9a?N}>|+0Z$y=k;>2N2DdCjq`Q7JPJ zl*#KLCK3L^$eE$iHt(w3pv$MnC@na&kMQ|6U`{Bs|K?#5PHJ=mJ_}6>iTh))?afC= z`3Em4(F%Zrp%$;RBi@_-K)w+XrIC(aBS4u~UKRHHrI4H(>7$qdO$WP~6p7HxQ5K9U z(S9I>0kp8nXt+)qp0KlWd^z}obnY)w-MUj^ZfnPM=TEe%?^pd>l1r3x&GSbJq+paO zknIe7J#P;4BnX6;@f>G`QBvSF5FR6p$2@`S4%=AyZ5NotXdaN(LAv9R#3>#&wDD_Q zE{jQkC9`YeK_aw_2s}%G;*K^kaVC;!H@KFCA+^6AMZgop1ny7%f!}UZVCKGC&IK*{;>TauTuDe4{{m;8+ zVpNUtiu=oK3tA58I@C!# zvp65)m6@Oj_-Ev;!z8f=Pu4yaO%n{$Ndfa|4hP9VasT0z{)){@z&C9SI7lwnsP^V| zuOCw~yE^`j9xQ#@$!<^|T9{BJuh<_crkSQhX6T*^|8A7Q`)G%_7-eVWy{`i>gY7)} z6JN+i!(~4Ng_N3IB$tyS9B4N%J0a_V5ov(QLPa!?!td`0gC6-Jqw)J;QOP&G>2Y7) z=e4%JKA5Q_JXH6zmX}Rd8%Zqwpv@G}t%5i&&28#b=^*g{d|*+N7IWzaKlU$N%liu{GC7|N{vi_ZFn zxF65u&8@_w%6_5xN{Pm@_WA`8XEM3I`%_D zbbJbZ@O1~yrEVNO-u!B@#? zN`16~!-xB;LIAPUJJvSN0qknT`1R35(qfa1ja-psGJZntH{2je(e|7L-~LN6XDYKg z-#h2j4B<&F$sM=D>vkqDHdRMhTo9}UU?+I|Q2j2)<_L(1t<&6@9(=DCniVATb<$Qk zBo>=|2PvT5aK_Oq;Vvd6XHV4r{Dvp1gI%^Ua5a2 zkQ4c&*8o;)qcw;%uvwvIxs8!Y760#404;SPVEu$z;Z4%xeM}}q&_}p)U}4M&zKIn) z&C|iif}l514-f}z(9Sc76=oBEU0eOhRGE#OqROOnlts(X;EyXCBJ6jcrnL=`Az}Ed zPOt2wJuez60qkBNM09;F9q^_`La^m%=5-Q<|7zFDN~Q1zQE@K7tRN2<5xl>1MRG58 zMkFM{v5RLawKETY?+y5@dx~ire;>er19EB!bx=(y%k3l(=gYjWtO3BmiU96q#GW#y z-Pq~AKPlvuiQP)Fa&i`Oa+Ze;pOz?QDskIrw9r|C`9lc^CCMp+zccE8kID-Y^1Zs! zPA!ts*{Q-0MxOhX!JS#5)h1C{zZIAV5q~+s1M6S}c;tNgScW!G7a3T>R2CAJk^CvzsQ|S4@9cIuH=qce?G9>?ln*aKsQ)k>}CHdL*Z=N>n zo1x(w!I&ssA)hNwA*31H6keS86|j$hm|D;e3^5v`Ew_W|^#d-Y?9ymj%g`dRg1NGZ z!u{L;tu|!=A&x21bV?;nu}EV+b3u=j0-*mkJvGTJ{Lq@9$$siH;`-R6QphCS!`zo0 z0=>UJ-Boujgr^;XqHtws^6=!ozR6C{J9Bj&7?E7Ck%aAyI!iEE?fhzaVYf8*JFZ4r zy53}=MA7D8s^y#2VmhC@TFmePd|5Zx9PyaDJXdBg1`%`l_t%TwlA4;jlispKDO-Bg z|E3zackz|;P`RHaXpFVOIotz;J&daH(FbV8Nc&Kq+3-&L;Q`$gS)Mdgs?1E<@X7`s zoi4u6{n#xkSC7H;^`uynEJFdySN5sMB!<0#Nc_ftRsYype&C>Cy+XT1J8L&e>1N)- zrEasHty-t=>x|4p6611Qqx9Z5=ZQrproX+v*@g2Jq6<)2=JlWiH+x2Iq=K*!fo0?U zGO?UuCQ`CgoD+<}z`g4jdLPH5^Afn9f$r3CA{ZORa;2lA!p%>=N6R`T-ZVyN2u7Zr z56D5Ff5v6qp5!aX28ar1Y>XV~idh&}>A$@IzG1y~!B2Ga*$a)&{O*5WU!AVzqI`%^ zqkqPfLSYDE%P}J4sb7K_#ELSSmU;4EBKDJyv#72eL=hu9lt9IdM zD*>sovO3O=xOv`!Aj;T|fJc7`GE6vy($4KU{)c|_ax6WwQB5|<6Ly_9i8!b~Kyz!! z{=2c+(=CRE-P4yIl$O-r^zwn;)I@{R#T0{+Th5?o=d^+F9^`bjE*$4mAky3enxKZ&!!gG)b#Rh^dOB$?3Vv52u(2 z4#Q%V4E9S?VKnT1_mW9(zIMx_0%g>`o0Bd6*XBfn1v|3}rAYo{qIxhYG1E(CjWsyq z-ytPe?b;uUaDXdZDsh>q`Z%ReHzrE+&J0-YgTj3is>Q=5Z9|&mhi02^6Ig-jyQJMD zNqkY#_qaVt!^Fw;f0}#h5EWHiCzD4s(#{K8jYWKBH^8gAd-Jh= zfM;+YXw@tPTHHS-Hgfth#*mW|NIvl?ifM0!)wwN0^Y$kS0WNAu3j)R2jc-=~Fy!zb zbjDzMpSWD>E^*2w%J_6pjIgAC|K~@`A^5)Qy758%;PY2Jeq{=305_Du<3@~visHQZ zLM@6?>mDH1K5EH}MLY%~A(uNBM`fH9WD}Ymf*^DZbPWw!jUPDd&E07%Vdjv31Leo3 zJ&)!U{m=eV>R^bOYJm4=t4X9}3{5WjE{pVe_MSQ^-Hs6%#bqVCrZ7RTjUzKt>x|t? z+NizK+<<%lbrT)D#>htv#w;fu#hyHaThRdksxTM@t97b9{(#{1+K&lI+4a$ME^SO_ z8Gqf{Ph#!g7W}Gy8xu&;Ljc3>@+mbHkdjJ|Tp$n3iXm*hA z6@W-K4gcfA6`hA96%wU97)59iWEhP_jd3Iy%pnYjo5tEMJLAQ`h4YimQTXV;>&<>z zx*Pq7;?v8FPyNs;3;D)UsvpPtrLe(*=4e%WL=vU{`|^Z^cuB_yF~GMek#M=c$QF*l z`&}lG+>T$MtMScVD1+0j!Y6jw9sz~ zwnE$^za@}i5KkE0U4HAaJese2hbq3jch62cn9QWkba0^Q?J}MDS<@4q!Iq?Zi6;dYlh>VQ9x7HT|2f7>64q(0Hd0e1G5P~ZQ6r~$ba;^{cKk^jM zEbcNUG<;+5>t#c9^nxgUqm*8lYHm zZdP+OWMA_L9|#IPaSRIo`toPT&f$wyQe{V6n<$tr z0}X9IXlp-8u~1op6`>{w-5S^O!-1A0&ZU-M)UlsEk0k*8l_8yE%o;j|@TkQ;u>9e&i;{$ed)nvq!?%=+(3{2Fb+%|oZfG~HBn`nQmQ)TW6;b0=M0BTg> zkpyrKTdB}Z0WFF|9#maRqa^HlJ}I?WZ-(V}v*JNOPHx|BL{JK%x<|nzSd$m0d!M?c z?zW5-94*Tv?loIvS`DpKl|(BLUK5Qb=g#2mmS*B*)jB#=UiZ0%T^}#$;S}*td*Vov zL+%3cUH+04BrVVl%4KO-%ILNGM!J1a%6TUi6eLzY=^+`uU0#~ABU_T|j~I#1gD_Nj zUmd*DLV7bf7NwWKNZy*aJ1z~A(g=+F!T{hooJ(9RmVs?QE*eF7+jqjkvG+Y5-<&j= zJ1`iO)lweN%?y9-9{p!O=J54P2)9i`Lw_`H5%o{&0q2$ z9A}ri?6tkMkO?{)lpVpJlF9(C#w2_*Fd>^WfFfJ_OhiP$>w>mgza`bzZ*0`SX5YeT zI!{a@R-+FQq-+krW#5yg8s;4!ZQ}u|rzx#m00W zyNl1u1mb3g&Bs;R##g!@3Bhc0g+9CQ6vFZj@B=xHIu6@Q>BG<>b?PY8L#?KYnY8bh)0~q#3Y@>2fW#E1RikHB)@LlrxS0}xTnK@QZdj{jISpo();oj>=Qzd1CmMT|u0|c?oCMwng!HF8`Lj1e`Yb>=rx2cc*4eblFirTrWMU*65YfBsAhLd17L*{37vR zGj+vekwgg z?PiCs05*Wsqbe>x-^+?~wnUt`Z9Arr8S*5sZD>eWbxD^;bK+!BI>{098-r5bsAot8 z7u)?^-ZIUZ>X&)3tHA*Ic%3D~Df4zG1WkWVt4$xBxQ~m2DhL&ac=(i(l-|=?AH$wg z#(Jhg>bLOa3(ao^A;B)7(m-wwjz}D`ccLQy;9P9F*FI5gCXKOXFN0AbdJeI~Qh}ZBJkRj}aX)di_PgAm!!Pk_6cUJZ^@lp@nAgI=$}?991V?&k zD3id2YYJHU-wVxga`(!5F}^d|O%x0+$8vs$<5CDH^sws=k$h~>U~x)Ku)bIe8MB&) zA48 zd$=|Fn_uTRryo<^kM&!5XHr`%v@Gr`z3ZlA89xY`Wc9!1K&MCdi>rzGBmXsZ;?sdrgx7HbcI}>7D?Q z#Wt5xrgG|{=d)TG#UX`y-QrRn6|_V91LvFYrPH3NIFWy!h=k~g-^(s}U8k2ibTBI! zUwVf7)>}fl9{=4pABKYa!KMz=wGhp!4?#4#P{D|TO@Mac;~FNfLNkZ(BW{kzl$;XX zummL2mdu%)fH(~ig2N>AjBt5q2VP2cdG*9wDw_J-cdN_+83o8I{av4I^*ReeQ|z9U zuk_eJfD~T^FOdGErwA}ks(Hkn3rXYn@(Skgs_y)E0!=6aexf**!M**?ML7mJd0*K3 z=ruMm6sDguzc-!0>l%rn$A+Rx^pZJw7ajW@vK67vb?8)%kdG&gjk|G`hrdj$Z&C)- z>PU%uB$gPuK{`6Zq;y}r-1t(?%+%L84iI}`z-3f?+XGRsgygS-UkIndDg5{7kKn2( zw?d>+dcX{f-*}-WQyZ>2im&8k_yKm{O59pZA^Q0C@RR|;1yJevfX__Lc+%~Gs7*}C{ko(I7+DiSqwJJ0sY4}Ceg7d=v z$a&t916u+O|4J)?k9dJx642)vz!%iPejSo9^jJ#gI8tHp2Q>I@nPA8HEAi(OJQ19~ zGI??DoVQymT~Ge<(|2WeI&kECqzaavm59#c4aMZDBmfQa#wzid`+*GK=}#*taUsE zssC5ef`2WE;`Npj)QGLkI7UXkdHsu-OQQPxO~nAm+9m$bq;M6#j+iRTs%4K=zbvhn zq*?un;-=cc(pg@6MV&YQd_bfzp|-~_nH{ zUQR$A#n1bEUxu$TGe28hU#ys^n2a!@Df{$6EH(#X!N-L`Ok~Knoa=jm5p)z7^M27n z`kP`RrZ+Go=gF+9_j~f_$5LGU`*2)}l0FGkmtvMrW-0bGn;^kKzV)_Vax2CSzRZMf zy(r-WW+BhV5UA%FPrZqQxO~w!NV6x`lY3v|STyFe}=+23YOhUG7@`+!|?gnxbD? z_FJfp>PM1M>Jj64{$a8j%p+txfG)f}6RvFG5sa#Ic}*s03F{3iDJU`j%#dkXL?brP zY&wFMN*nd5$?Ni!Fq3=Y0jh<=uQU$VQ=uEaD9Us5MA?kFUmv;lfw4H}QF)0f_ZV*; z(&y(}HMSCp`1D&H6WTpahY}3j{Zg;7m_AhNa4V4|;kya`5M(Lg+b0`roqwGnWbsD( zx{l_}q<~>vtf;B$T5r&Fk<%st#50{tjK=Qs4h}U@9!7)Ns5vGkW;3lo^nFESS4MR{ zq6tIi?Mr4YD1p|sxss)15WC;?-7ft62gO3-9O6oSR`YKrxLnIFyj!zI&&zUa7y?p! zDTL%BC;fnPC!i;z&EDD4|JZWj3%2F7{pQ^GJpMCI6VF- zCvp|a1GN=!KibpDR4JDKqN8vqGyC|SkbM&1Og>B#QB*a!kJtZ8*V-J}Oimky*s^z? zJzr|Iz}!5RhDD6!L9Z{iSuFo_wt>dDD$(gXI8xC`B1m?- z;J<(Ws_$2tS_Dh;48mCN;0?d|ZdR+l$0m%)CZow0Hrp;F8XH5qFdE`4^^TUCzNlxN z)d{Q*K8VFDW(&j|%v2|>mljy!Qb)v+@{2oko_{vmCicq>O|zbC#n7g&$15Vhv+Vnh zyWfvXSbtlmD*rVBdr0yJY?xPO^5JG>m(QD#1s^INPdSDyz)9f;huE#Or`U;7f60B03OG-A+dmAb8k$@tY%X=K9h2S67=vLsLxK8z0_i+ zj%8t%p>0|`z;^E`p)>T8Qq}&}&XVF~!k$QtnMJ~5D@nrp&!W8>s9vQDp4e*3#YQW@ z_C|lwQN*QlW%$JKO8 z%(F7Y7Wf4*6EQwM1@$(icy+8kz$g000d8zO9Q~^|k`cX(qfn;p{l7)*h-Rx9`B;E} zBhKb`8G0*1VK*ngn)+!B4~(=IPBt<~D<%5uSfn-=k*}s=TV*$c>(mUs3T2jVFdr|d z6*p=w_8V+gp(iTBVIGuC$t2j^kWc7+oyu;QQ=*VApYL^fQQn~+aC9~uzz&fFTOY6X zh_w8W10@&)4AoS%0+tRikY-NGSR0FCgFdBkS@67M(TU#J*d*IOjS#}2;0S&Kk(tfh zc8jhRsz4xg2P<796rhNi@u^7D^@r6~sug1b_1cmv;{YUt?*_=vGQe9{gM+Bp8|BK! zJ}Q?gi2SQB=^a0}P4=_@^H=N@1~$fs)$5>A21^5q z=IALX78~~wi=k~V>OIgUtcOqNJd%K#22GujrFz&@5T9+yYR9aDV_L9>+}& z0H@{xT^ldiRkN;gs}Rx5X5n$9bo0pzXgmPfpb21frWi88*|VH_X=%d_>GuJ*IsS-q z8G}nB_MGp1<{t{#b`U0 ze|eG=8>#acEP?+=s>7Y%MJFbwbQS&Q5IKW4`Y5|v5xVx9a)WAt71eDVZSP38sOXsz zoYnP4;&M>szkivt4)eX#jgFtsAYDX$f7&JI_a5Q6=y}v(m{Zx<#EwlR02Fk|2#tvL zZWiPDE9ibwkR#NtiwB+W{S)wrtarsQYutY-M~yBvRs7yU1~k^`b*XRm`xt}RE;=4H zQ5IHr3o!Z~mTf86kqtq3eK5osD~H{+ZVY(x`|WOzkcdpR!K0ShKx>}dF-SfP_EE(dD zM!Kdj^DTfuF`bi0j^(rXg7oVzLO4VM$uty42;}3u4DJd+YRmC#!5=yT?jY=)tL3)K zUl_zOUPhd+#&-eD8?YF2yKbEsMRgLFO9kH|;=jd}K#G->FR~iaNKh_zO9k8xCs!0t zN*3L$)m1*lTX`1&CnNK1ZqZ`QOTboH6qW}G#&E^o!TP3HsWtKWk*9X(^PEjmk4O>; zfKE*9vaM&T=Smv8k+(d=C-u6W)0^!V#AOwi>r4doBRj>N>YPs8G;MjLitrj;5}^;I zAMYh3E+NAmz$~J0l`CwJY=KN@lK&se1ixG^IV>O-4(FlI z&54;a+A`fvSgC);T2=AvoqC9kkzt8mUubVeNnPrMkhK7f`thU%Lh+F*5F*~=q3IDBClUuVV6)f0! z=KEPjx5VR3`RWtwYoUKK_HzHwyppGi-v$Gr6+AdNq=J8`aM51PXBKXPtcDs(?P^BZ ztlRF&#H`iGn8K==QMvp{f)%Hmmti_b67?SrCkjd1*-8gSITZLBg-Hy`j{9m^5t~pP z5(W3^zsSQPqJrs?-9Gu^Vd$z{P1dtTfIrA7v(HerC@ftfdTL6@=Vs!}NJ0^Vn1aF% zf4OL61!}qW?A05$No^w^-5a?Tbxue|m_o}Me`vB|dt{qV?Pd3$}{GJ9Y5AexPWN^beN6h#=WMYUFHBZWH`TZ>g zvxND+!*HIfn%IWuTouWuFxO)*`VBw^vn2WV^#wiDZ*x`@sy05ReRF(e)?I+@`KA^f z2Xp5@0pJ}5oH}uR%Cio5RBKD>D_E#ffz9FWL{%{mo5(JOZYC zomOypP}_@0^?0lgOZh-ERb}c?+EVF9R2ZOxTLHeR&zBPD8KiyuAGX?LC#YFJ*_x?S zX2+3<^w~5npq)PZbqK60EKe-N_LNC{^#10!I3|;aiyze(H;qOI&l77s!Yk;p_8-kb zt-(sWMyb8fPol(-SW+SB{&3vQRlwzBsjcvfyW(TRDx z=UwAOdKnzRushyci!_~^DA?XIC^ZkaA%UC5+Vc4!2(sTf1&?R<^qQGCVPgEi3dPTw z)8lthi;V~W%w?x|$)uJR^_5Y~>vC(GK~_HIB?o1xUzu>-zg4##+UH3s7z!#gHTp|V zk`Z9@TQ*5^vFWoR^{>QzF<0kQ5ogq9Wn%r(_D*sPMW5kFu{QwURl2_G^+=FLQy@X3 zkmnH3fa|KMX6^SOrm$OC(Bmi%IB05;14P36Ve~IZ1vEy1C8S3|Mg1t?yx&B)e}8vL zxYvVys9v01)ZPMLl)rFeEtT}083z2K~ zx-=K?J0PH<{$$)!IIP- zNau3h*uoI-xhDNRH$2Q@ODMbWOf{&CS<+w&8@u>>7?x9%Y0z_&J65uZ*NYl&2}e@8 zdp}CKiu>x3-lhFwh~}DQldOs`IW!eccUyM1i;6bouxx}Jswu%|x_Dl$YcSU2iTt-0 zfW%>zUIuw>jk-=#^4)sKcXF-fl=UTIUdV>{8{!5N!rSE#mWw@J1j3B>4~h_5dn0*(524DpH-6~Bb- zF4`jC!6B&DZ&)N%o$Ex6R2%IR6cynW1(S*RN5_&0$(R0?JX`MVcn0E9qvBw{*cp>3 zexI^~4DPhhmkTC%=@zqFEhsg;wt~dQ7mZtR4IfBfbGto*#FlXDcj)*=+eoJWnvRoj9(QQWRZ|%w zIiZN52HqqW|M|@S|6lt5#44>dOHlIjFR14F`TCOTm%dT^zxP!= zDv*{(h&S_e{>#l^3wgG`k?bz#EW0%?tfBv3d$CjW8ErjvMAtI~{fhtDoKKx=syl%2 zH3)VjHcB8`(aOB|C7Ob6a&UO~zOJs$^%h2TaehU`iC!cIQ!qBB-Ubp-fz%gOHMK2jn$g^xOXZ$d!yeYL=8^dwbi_#a7mY$)e*4Gj3#)7#TfDXSwQPq!%A1Z* zal*ZmfxYi2@#IUx4$~DO~mYNj(MU+r1l0r6Y$>vjim`^ z|3&_b?R0&0Uc8rP`IMI3PL{*)@bG}c#D&U=pUb4gk%ccJVwmGP@}@a zCFuX4zSefADOFz)vK!=;RcepS&Bf_Al3evAegBTB`sq_%)bj8r*!naGko$7F?)Or( z+f_tG13APt4}l_B)fMm>Ol^&*GYShE094w$SG4$42%{Bzl>fvUV)0U_$p?K6#V=3f1x!u+deC! zKn_bK9)&LD!fBB5|w=?dw z?*dCst?h~~Xp`ukgPkdf|GPr)`xGi^RNd}*d#2doXQ0yJX8%LG1oJzsUKFBmXt83H zOZ_Kb8QXk(W?v)SIty%3(Y0*qOTO1vueJVWaKB&juvKmo+xuvIcUp|_Qdc?9UmlD= z)l?o>`GtOi{xj^2%mYG>P|%(HMO}!z(f{-I{d;j1)8SmMI!i?vt8@}GW^^}R!HK#9 z%X$n}U}VSvWDpuZ3YgwilSL`H*tKt6-QDBMydLHYSJt(Ty>j3e4iz8PU*4O@9F-ds zKl+s#1>+svmxj;jprEe)LG_1v=nvIOIdCt`2CgF-@mmvQ8}_e-+c%iRUcmf`RqJx3 zIp1K8MZoEhfLck&h8U7y=DT9TA73_E=QrJ^S*+eK6-pWSbjeR zd~E2D5$5Pfbe;eL+DDNhxeR8{nSSp)yS2`XX)PAjNgIl&(5AYVH`NggafXIEba+*X zW7Z%cSp43durJ)(@m~n_4=;uj`CE2piVfVh z?M^qR22pCi5ipQ4*Gp%VVZbe+M;wAbi}B=-6;KRshRtRL=7N7MdoMC_QPpYTCgfXRWW0X7&Vr;*lcrP9Rm zVgcXRVfl@U{;7dkq_9Ik6<*?TZPRj0EIZ7yBq={ir+q_=2yVIwwI9WXwFr1^qs`UYHk`}R2ZiAIG>SNQiW5j3mLN4F~KI|7btHDG8(D9Yak0^~4r8UF))>dAAua|DxZr`68y* z(NB#@eaOg{>F4KPa_c`-;&p$e0_1g~<50M>cdc^rqZj*A6BvT$Ac2L-Z~I*x!W4br z@1uxs;GNwW`|Qp)_2)nAhleuubfD^6KAYt$hN3Ceg1+qN9@-r$ni}7flKn~1Gioi~#`jnAR z?aCBeHcuRxj3_>!t?gnqFIovmk2EGV%|jRGU5ux=!4LeWDH<50ArR7mPjY0*{9^~n zSL@x&+fpN3%H`5bOeFUZ5Q^0g%nVrKBcXW|#J!o+a&pIv8%7uSk0+OkaB{uV=ht^D zUkihF+of%rGipcZUJFJ0Kb+vnj;gN(wMk;XKk{ilGfQ`x-@q+`rtu0#=cEsFTL``o%u~c6MeDVb#q)9t|7NBfQ*DiO z(Y0NT$p$B8IZ&}w!HFQ5h``EfP9K%kn{alFEx2YW<0;Qjztk4Am#4*ZI2Dim8Yk?f zw)8|9$Le#V;I>TG#kFn|YLhno=Q1N$=5%$)Spp=o1kh7D(;u|bWNB)Hr+RDe|>5+Jjb-BB}Jv*6W?+fl7KPGLj!-aA6>FcG> z{>$s4|JP;Y*Ij1m%FX=*7#xl+ayssH^<&}Jee?O1=A*Wowp zec!RbcaTNC@u%L_Ogxobk}c~(KYiL6eq@ryDCO5!+7)M=xpyX-`IwaXCtS)$Y^$T5 zmGghv7@t0Ud%CkEk0j)en%KWM`26GYcW-d$yOQOA9bzsqAbXWaot;(xp;E#u`+;8< z>lX()ic47Olg_#~+RbfTnVCEHWIN2of!~sLXI((F-u4=rI z>*_Xox!#Wc)bhCm7uUrkd(c=|j*XQGI)bgGGzu=zoWRTK3%nvHr~Jn)z$dp1=TN@P zceLV#^V5VA2cdQZF-mU5%Us=LQXVwhzG(q3FDB;cel?PBgxIUJjqKmA+^<`&_dqGh z)^2oAR*DnEE;1q^)FTWFkIW1CiBUL&?g0N?FB|RE&d^}|?>dR^Aj6AFwJ{Hzk>EnoI#*V{OSgrG7S>8~Q`#?qgG!=ReV80;Fc>D3}Sk%BZVu=}=gj^BCv+>Vo1 zuse`5$K6NpZ4RWwPjCr**aaMnnOh&hX29UL_@p$%rj+S;!JHz5OnQnkW4 zs!!s{BbS!ozsI2z7Rs%m_@oT#*sHd$T)=YuPb%S)ty6d`vUU*y2 z_lOGZwoXHJpyN?~e9KX?;m~8RWq46wD;2a zbYc3%=N@h{vLbG_{u26JUUiS22pnOcFr(bi7sKqd(f3e)L-V;}P_=Wk&CzsZ{0RnO zcf3Ga=5#iem5GUo6-Wr0p4;xJgLZOU+=ymH#P#x$cRyHa$A>!X^#5rW^?1yg66t?S zm?eV3@wZcIpkMbs*O z*-iqBsYFmYo*&F|IMF48UXRBSiB6+K;0%44JTa%vNwjuji9m-RPte^pu2i-muWM;A z-iLq;9o_J-+}Q^81Ga_UVEgY>G>@qS1XxEl96iNCfnoT>Aznf}S18_XZwUy5L8xAR z*?PbuycJ55D^cBCTSXR)0&s>cb>(jHY|g;7saExxbM zTxNUoh)wY6&sEM{W)|bxQt(xQo6jwJ`>#*Gs-k~$H(E8GrFef^b$V3zUysnpHLv|L#( zkT%#~{uk8X9*LU(c4JZ!68Ya=`Ea?NqJtAMK;AHteV31~EgHy3ydBD3ew)Q93jT93DL$F-ymjRP9@wbceFdgTG7f`RW4Ikj)?gjlRV zL%}Be*GhWf+twaS(cY@BztiTfBA5LGROibV8OK+(L-~yH?;9Pq)@3cmNJLAVQpQyZ zWpIE?>@By532NDndPnHp-9aS|0+g-9eww|Y;ke+vUjD=Fx#M@@RfrY@ZABKCu8Jm# ztMw@GRN)61+|2 zn2af&$Q6Gu-x=1q_=C2Bm-(Pa$gSt%K$}o0AkTl9VCWHNYPH-FNPB5e7CBAXf$|7i zL;I$UsDTy=?$Dr4_16<`-ZLmfXY!_)F_EeVr2iK>RbkByoSqaf;G0m%P??AmAaMX@ zL~btM>sUBRQgiwjZyvF5(5Z*OwDKOyT{GBn{Z*kwKeJw_-$GIhDgHelcHNgF96a|f zCA-ljGQ$R)Rbs*KQIHDH5nqw#rkPTb3WJf$Ck)J{ zR(e@dY4};=KHuKoa(~=Ouq2;QX*ph-8_k>l_56we+K@Gz#eG6@V|b$)4FeM+1a&J` zug3h&_&JJ3?MIi$+ht1xG=fdG87sP4S8rCfhI2WK<=n4f*QvAJznSo*`SUoUqgo2vg56!O>idqn=o6M(ciBA?~;gafWF0oJ%1{$b9) zRT)Dn^zH?a*6p$-<0+^sFw#8tONvUg8*2((Dpwd+b&EeZ@17Fdzzlf!tF*aedjzSw zZgEG@L*hpjtcUzEz=bjM)AVXk%U4D^&Ds#TEWRU6N~L3_d^B|*u9i_>A&2eB+;C5? z56!%59%d(PUQSn5up`Q4_mB5ztM=c`R_Us#RU=;}cjGVJ_Be9JU5*fuC5irfKRP`6 zmQ|0-ePgK>{h#nVb-)k7>b(dR$Mc-)lWLl3@|jV7etL8xH5M7|V*wc(h`7*fe%o!k zxX0cspK%}+;_Sjf#bT$M4QT;PKzFc+4vT8^?i^V7%n5gXnFDi=Hkw*zX|~ZL>$Kiw zf9#+Bnaam))$-i(WAo`gnFw$!gFEMMCU1c5|RRI-ae@YQ2+6QaO?o z75h|T7c^a=BmP|RoCL>VFBBZP=B)iKlU4$cGN#c{84x>4T#mRVYxi1JwxYP*3^Rcf z7xx|H>vh2kIpI4IRN(&lBoExl6)x&5J?{=F(6o)RpkHrTpj63cLEFZDg}}qC^2@%9f6hg zherYMtVp-`;~|qpn*wx7C$K;R7G|^KXzUacJU6R8!B5lWTG0au45Gjt)S%4{e}xN4 z1v?YVgy`QpuwnO%*gD2D zpi}qPe~kl#BAoTt;68tzUK?Kc&m^ORYa9rdaarw%zz%!>byd&jvHwQj+IOf=+_u?_ zbh=U~5J@=_m#tWGqq*3mToWHI-!;fcryHCs2fdrg*wz1;;=%5erTi=w=y;8PWGbF5 zfwVYjKCyd$l9W1(cOjgs3CIP4#sdlU%jAG#TVbL8$c-Ri z$$-~B`WM<*jqzWz+Py`@QME!i2O7eD%Pyq_bjic=(wDo&S5E%A6xNx zmc@Izj|SOP11E_ImN(8q7zgmvY-Pch`%`&hD0oT$p{fmA|Bl$=dMq9y9!*fd2EIU_ zk0aB^#3dQ?vSVs3{9*6t2S(aJf73u^vncDedH9vx*m~N$4h_eO{WpcLeIB{H@sd!mLi`Y#c7{z{DFe>kL5cF zLH*EbFF=d9)hQT=To|GOJ5VBz7hn7#liZK*NdNUhK3IRd*p%+~l2G_)c@?+4%MO1+UTASaHeLB1Kvc&sgJ-e)T`y6$dQF+UAJro#(>GNu(YLS6_ zc&t_lo&9IESj3<{mgzM2FbBS#0Y{dHN`t}&dcA5tZ;<2+I;(HoP4GtvcCKbb#02ud zvhloG5?_1KTu^(w;_PWb-4(6t-#^Ir>1iGP9nzaT3fC1`Yt3JUU%JCgA(Et5;h)^0 z*mm9#>_>h%F)R|nmSeeaOCBe@=@dlNLe%&epWS=G_{~jDkO%*~FD$>~k*UxQ^+g+2 zAeFe;M^1VsKx$em!3~Y}sX9lO`&_AOScEb1uh!l?%NrG`M<{u^Oe6eb!!zFxy=S?z zpHS??y1{-f7}GltF1l(VD4popy@_nqVa2e&lUIxO=*toyftC;qZ=XlGKfCQR%$T)`XMLiG<~f609xRL~ zs-#7P>o=Jkap^W6ji;>=b;=!==`l_s^u$a<}`XL z->bO@@59CF4DW|MO5H#9KGWI0YDtI_e)h30ov5q7`TuoosMKk)i5sP7rq8t)vs@Ew zvW8HMJniP>?`Ja0*O|e)-CWN5O6S{XN=KS? z){?jn@aFlTA!kd+s)7GAy^{INj>Xvi_=G1u&D$#%XVy#}@D>-O|b!R3JuQ z!G0}%D_DX}fjFibvWu9?=XD1qF{6-6UJc3qx48Mo9v5o&ja(3>_eGzQTa@V;wmq2f zmr`Tiyf*POLmCA%v9jgN0tskS?PnFrH7_~5?)HlC2N?3B9+r^=t%ADtx=o(ISZ>uU z67J2r1|{2wQ1aS)kXFJ@Zq}u-Q0GVqVoiH%t?${F=Ox=(mf%(91ONG9!JdI+(zFTg zlNRfFg4J&*Je_TnGRes#aUv%l!sV-7hBV~_7k;`%<2iCN)mvumz^kR>2Y4I$ubky1 zmTi1_>p-7&4kEG_Fj;@E0TN>ly%ziV&3XV<6!nwNJQXa8+)7~fnrvAmV+NO37~kzC zmL}jm&*u}m5?}jjQxLFfK<_u z>=92deInk+3zo^IOTz?8*N;)!Rbc|1ja;>gz_T-~t{vHAAvqpG;C!;2G0%5jwnxn> zmyPl73P?;wfgW)<-*=lwNJTA;!@T3eqsTlWiLU-R5q0FDg#74iIm;-w`)-b!3Q$XF z*6u1x$;jAY;k#HTG=?0YW5h7BCVBL z0FWK}DVC%~qmHtVYrR=O6p74Qo`{10h<+qVl3oW@c7!>O? zO~z$+SZmc;iE90_Hg*sje>_}O@3R4!U;3xd`1XOZgU~VA=!~omWWy`ZCv&mwNsZv);U{z`^%#TB7 zt+M_JNd<(XSxna5`v@EssE!%v)$osU^nM!ioZ3>wqxfw{F1IS9vzjkmLI7W2y-Ni) zQf&A}!Agd%^79J)W0Z0l4d~uG~6G~`gQv1mkkpaE@1RCfkm;c z@bYTp1w#GpczIcw5BYx1q8~@9lh}VNQtOsMGeV(;G_!jN*&U&$sZ*A_k7#_^8@+W> zIC2^0+`+J@cydnwOC}G_2m3cl`_)cTqpMuCC`IidPv6+TK@Y}J=VC}(v>~{X7=9mi z7fxD+D5Gl-Ik-E(v~$qK4vmvjbaKYBvUT6#Y(jS}R9WgZ41}^ji|($gJjXDA>(rP8H%hZ;^dXy2o_$ppVHewq6 zvw|~kNZS8<`me<9r+Yi3u=Gh|NT}RJQQ$Y05&WSdX)vpW9JAZ0Z527Xk>*{zMgd!- zU0?%)1VOC)c~Ex8Prujxko7h9Sc9SyWnv3~5dU2QfD5lQo-mc66cHp5BBnpcpQSqv zry5#r^>B1g(@4#axgWJkVY7Tk0IkZ((`^_|_Lp+bJeTx_v8FalPM&+=($$#oKVD4W zD+aR~%hFOCFKiLmfd#}t136Ym8)N%T9D~ku-&1Ww$yjROHR>m^e8$?n!SQz)n5-d# zUqMbev<|JaJJT}pif@#}3>0mr#L@$xcYpzdaHD8@rE*ZfKfKlm&BjoIP1CnpAFAbu zfZ)0` zhS3+)yF($6+@0-N7C-nXbS3YXbxIQAw47YzB_r9oKvuKu*5Vo;GwS30brC=%uS{0g zr_~-~ErHkKQ#Sw6a_hom&_C^qQmZ)!R+9@e8twc~+^?2J!~`BL2U8$-r+)(J;E{5N z&G5UY1wJ|fFv!;5_xsb?O0W%vw$Mb#k< zMSnH`w(genh@}Ru8m5`)&-D#2&2Yf>n*uNpQv?juGja zZ9-4_Rsy;L{vsrm7wt)P`)38=u;n?<2h)vgi|H{edtWP!0Y}jpm--KpP~@}~4y6~Y ztVt2{Kkj@;#e)aAB?&R+L|A?uNlRppmi#d>N{wFo6Wy@2$T(o*)jE@f9H9m)=l1)3G2W1Au zjCTlQ6XvX>5*OK87_4#IRi1MWsq9|3&x6CaEDqX3PeT^*Hlm{t`vB$=vl%d)k&(Z? zv`#$r^m;y`c^w)bLc>NX7PZ<(C|{0h1H$nP1Pt0Vi`rxk;!ZUe_(Rqh_gkS5%pxh<}A9J&-{r5Wv~j6Z_%pqKSjeTozws z|0@R={`^xa_X7j#9xnm<#eGuhPfl#YA$q}*}d40jjG?kBC++Vkoq&gx`M z2-wvCktB61bpAENuQ#f!oiKyjBMPuxI{en;Si=QsVBW;wV$)==Yber}2YP;ZPb@Hm zuP3h++YZqGeVPYOvd&zeS=QTxJcVXV!M56JBoq4;Ck^ZGEMS~Bwr`em?;P@X|Lq7?fNOu zc;{7!{>=PON(k*EbF#FH&~;~6ON<$T)lK!9AdXJLmp~RYnL~D6_thZ?ZfHn@J6jlm zlnQ!v_jLTXkIeH-f`>> z<2M_eWvbu%BypR<=}1u|p1qzjv5Vuyo$Tg-!BUZGkT?Xp^&2&awx(ldB#GgvJ^2Dy zp=u})XuhUk3zqZYg86!kB|2nAyM6$AJt3BFz8j=pL z`^$|1tyC(ufcto>iAL7-ZpOgdzI*+Ln}1HGk9RUgZv@Yen@`5UEZJIg77KHo8VW^- zk05$rsvycG9TrjOnuA<>%+cMUqxi`Zg%x7I`PTdM@!)6~5m3c>y(lkF_{cG>t`k*( zm7s?5MWB_rQK(stF2V9zBQ~39-gDP+x*AcqfmMm1$>~^x$V|uq_I%rBtSFqyv?4tr z!K{LkIITXNm{_I4^DB);E}12PK50n&v2ZZj7?8g#mB_l}Y?{DELQQ-gZr>M8CugJ| za99X+5=FOwu{VQXM^e8p$bWFa#mpr*93b7u1pgOZoT`<_XjcKase{RJh*Uj~8}Drx zsFBBH(xD{f8;gxUYq@#S{|`Ue9jz5q2<^JX3yexO?=X54dQ!#VCh-z)99_U zt0h93`zh{PDNfd`bY6Yx7jY2q)E=@m;etYcrytpcg6U^(Szf6r}{UWPp)!`SYQfr1Wt-)yzsv$W8Ln3g_4I2+e zPU{j6=o=OnyYTwS)9Rt#i^8##al3H{1i!G%(#66iDVkm19l}r1o)mi`U{mdqnB^Km zGjPAmNMyA72@`)Nh8ejn5RDOgnQtPBVDxW5s$@+u=2;#Zg6?;_`U*`goRM3yS0p2zE9ktvVqh@w(cTR(_9qlngcdM=$ zwOW36#`>{bED<7c&;zflBVk(af)^vPZ~ovtACm0V(QtYr3-|S4ei?9KmC+N?40T5+qIYRD|j~jx^G*`>G&rPrv@KQc6fI40&UhE78voY2 z5%-hu=YGbU#^qy3RBceoy^OZ^fTN($sBm_ySC!wy*f-#>XkvD(%i0MrwkQFH0=14=~xvj^wYr)9TF!8PC8KntC{@glU5&%$pnE~v2pI}Sg4 zDD8QZdHibGatvscD(7-l{@kM+kUtS(-w9Os^B6i~(O~d-Nwu}{qWpo``YkH)HAYk6 zkCcVQBEPriwcYn6M~7&_thUE1ZeZW9U*p!O>g8RiH$(mD8my&cvS^6_>9>dCaUmrO(T}rY}1Q8nDe*nvX_BDPMMNFeds(5^GSAJ*_;0v z>Q|3m`kr6Gb?$LOL~2CnX^6O10#$1PtbDTbwFv;!y4+<>sYLuDH5*9cV6UQ%2Om;E6fgx>Ebbg_hP&uY}sl0lQtz36mX`r@3%cF86`3bHuQvmR%~ z##7449L+lyTc@#a93_TGtgmHO5(oh|4RWt9Vb5tF5!d%8gV>6fizh zRSnWMX6b%axMC_i@zSIjriA|ykH`k|pbu(xarQ@Jtq8yky^{eFAl~9X+@sTS9+E2s zu^>AXs{U1z@w0>bX(v36&q{B8^|B3lnPFHkiml-@M+>$QN1&)q$ArVLh)eEz-J`{5 zq*(KQeYIW=jwS7{kova<^bpG2Rh~?!efm3kT@lKttW}qkAGdYuPotlQl~;} z`C$2xx=v0ul zs68g9vYQVM6wgdgCNUz)(MyDbkdzb(Z87dHPIw$@3vLZslCmjAz42BLSH!P=pOS`D z44AVNW8X;jUQtwUX$W-F4O645j?*-Dng% z4HUCPZQPM)Ilx!3nnmstM>i(okD-;DM!l#6j^7rsaNZnb7yVV`{mGI%W7#UvZ{H@n za^Ad!LfWSsI9hA)TV>ZCM}NudaXH<@44qOu-e&`#luD5c0flFFRM=^#IKIuz`mJN? zXzS;HU?BN&ykP!pK`dj95YaI)IvyhKTmaFY#T1PyHHdUbAPIcm=wX(I-s&HC z<mX}mg{kGmxvBm1RPO>fK;Wj~m*)YF-(+*OQ~nK##084V;8!|aIL^&sXj#L`hdB9F|$G`h{$=-!gNs&oqA*#RgNVM{DMg6n?@bgGb!BEIdh)JIgt7#pa1X5ed16pbO;hM~ z+R~^L_hEB@w?(`^p1kPh`1sHxFd%4jiQAQ~pi?jH=mX*V_fjd$stM@^wTL32O(MW503>9IcdI*3))+&}%ygNKv|&#~wbnAe<$aPK zdoD#J-gyg?hfhFIpaX<_KsqfpatwgexFW7)3c|h@142w$a%bug0vQ*DXglBeY{1U$ z-gp5^u;9E!<)CqKGWs_1*&tV~`24p^Y(u|$I37fz_jrx_wYOL@U(dJ6$==JQQ(-Ki z#<_`mUSn(^cMs1w?lfw1O{Ud{up;^dL;~2KBrQK-Cf%$ecq_+^`r|;vG|1;^u_2dA zPmY<@wM)1)w*C0ye@18fm%gnlqgshx6(aKHbv1}98A^B0FSkHst&@#> zB0VDHH9;=dX%51qtd||_^K#rClmy-PHVtjd-s?4k4S$r6a-T*rIiLrZolq zwZ8a2{td%U@5440i=;tV+X0iSuSS>s7OAJ-`_WBJ-4CCWv4tTB9n?+bSXNp{xD@{_ zYHKhoR~w4ER7I@c2}&4^Bm&yne!l7vQ#CXKNe*jgIIY*gQ!76jopP74GaBefOeN<( z;P}B?3)ZYPIq%ywz-GD4SE2C8FKk+(DgZ|UeVV5hYVwxT_>%v4p{(%UL{U)$4zmLk zp8eVGD#mH{&r(M0x5rNmTnNHHCPj=La?5`koURJiTI2nYB^KO1XiWG5BlySK*}m`z z27a_crx|&HhO!qdzH@ck+TIBbPnT4Ped*eWXACi6YsJ7Gj}?KF!Ms5D*rj!9wLL zSiouDCBW{FA4rhfgyxOv=Q6pgC_|P!hk!3bRR&Pf7+aga>#fuwD8;S{xgVxh1p0(J zUOjwb;352jt$4NVyBf*%pR~u_#UAj)y9bQY9r2}Fi1LAQ@x>LSCsC|qwiRx52j0xr zd7zE(dT_>!&b*{7>?skZs>yHMH}w_)>%#aC)%Fyc^)l7ZLZhB69_&DzH27&z(W5f3 zI#T8Xf2L#pE^V5|#>koq149ey)&5f2!^3e}P`+P8nQ{?oFcZn4GO9#Zq97(|#9xWP z62f11m;1{8@RytjF>|T(D`Qx!vu~h6qk~!PzbOR$J;II-mwzU~Bk$Tu$o1bLU23+< z^P^<7*VE&i5M01Her(K)Iq0Q|<>|x2XI--+(HPHv*Exy-xN&b!ZNa`+wNfqPeh(6L zwVi$ULcd18e=+495|T~{1q#%XplczfGUzlZWz5$>+aoUbD!uK|yGEJ(R~+ zLKsGQoF2pYnr)tq<{yzP;ZW`Zm2dKTqyB}K$Fh*fk-TL!pD6H(45?xlQiSMZMLtl8 z-J)!g+4sc|<4Xm|@_TPX1W75=iXr|E(=zTFSY+-xfCIiwovgO((bMg#EW&w<>H^XstM5( z?7Ct`BtU{NM@*@N%)-Pk%FhBUO4HTxA3jKAG&>c*UmlE2Wb4VlfRagS$)#Jfdea+o@yjILfd?mF?xZ z|2BG4;&iL1W6r8Xe~L8Y`WA1gH#uz4EL76NMV7r$_z4(BfoNayza){uMz(NBCr}9r z!=r7db49h>FB@f+p1k<6s{dDwGyivsZo!8Af+a|b1P{fA*q>gV)l*CVf9fp1W?Di$hyec$m{=*PKDH2ny&EN;i# zbbNBNO%?oMt?=z3YAR@gF!7;REjpcPllKuvAs zORRPH+@%a_LxUYES-RCqv+Ky|q`D)#j>gwG`UBdcuEDPXUY*o%p{A_1MtpfcW-m%6 z)Kf?|^IGv)&veMvgLnn(^`liL?ha+Vz0rzw7T7OlS5{by-fmN2W}1v7vUO^LM_Fbo z0h>W(K;r(?$=>nJu9!qL{H5=p&Wy*Zq@?wE{0@fR7Ouk_Hj4rCwNEsfQ!LW~*rmoH z5J`JRofeVz47#h0&LCv19+7NF%qOs{<2rI0u92f6PzY|A=`4U~P*qQ8SrIN09fpYe zZz7Z4Ng(8RQ@}0k`rtcz`fHJ0(hy!nQQWzxTIc&Hg0exuOmtFF{AEHtPmu4fIaV18 z$>X}Y7Hmd90}8U8@#EO9m5(XP<@;~QfdPej0uFwSjtiq4jQ<<$~9YS3> z4{l5Ib+X^J#u}$fJ%A}CiG3FD|Fi(Ft6%nVT~YQ5OUs`O9Zylegmcpm4C3e2=>EfJ`)mX|+6x)A7lhn_ot1tGVm$0WOAu)bA zvrVPhg+4gl8iz%tRgkV#@#BA5uqbWe%1g3o&mfQ@I0cinMzL8O`cEu5zPC?$?^I8>%W;yWNSjV(hLQttvZWdiAQ`HYwITpH)7m+V#;vhTK#RIfw3S!z^G?=@N*D%p%?@ zuWt%${pJjAX-zp~`AJ!AO{J;;KU2({kWQ8N8vU4_4A*J_!w=q~31ki_t?;!HXui=c z2@=vU_C*(Dxx|rx->e)+qrA2R0e+=mu3~5N!xW<9;LcmpnBE{v0ChQZ8(#AN6b4ir z6JTeDd@j}zgnkDUq;3O=^t80-N7QGzcQqKzf)L^-6u*B@t<5c{dX4Uph>ih50O=UK z!^3xXYjUC8&+WH4L}Z?xUN->E)wdTBBsD@(!R!0_MNAul@v7kSz01+=Ha&fC;$=(B zB_*in+L(Ba7K4-6U;cVr9dE?odT^S70--+zw2)l(<4_|N{A+sQ!!6ikTm}eP)PPRXucc539@($YlHGzV&2x2>~_7DnSNmQ;6|fe9Pe^7trNxQgmDS**>hdAEtmLT7y$tR&hMdVybLSp_$ImWuMjgaFR(1 zb|@$^?S)L}f|$C?u4zx@>E%Vg#u-IpHu~;@U^upJ<3NI&ybCtRu5_lXa075nibJ4g z4yn{pDHsN%WN?QtN4~j*pc*~|pN9o-$4Avl`b5qy^vI^o*)vP2(R2lWMq&gUd71*) zfB*2if{zs5{B*HfK{@+0clQxBP6K;md!SJqeI0gzW55tr2!1Lto8mt?&{z39dxdy< z+|HLN1-Kvz`XdPtnRVTUA`ANO8?}0RaIx-ybjL||vD;5w)i8oE-vci-^XA@STJjg= z2)A!rNQiBeVU)=iE9Uh~R#lkR!Gz?gESMx=OtB|Ca%SW6@8cQfIb zC?nz@X*{#d+*fyc*&S{Nu(>?8S(9knf#WfNhpj&Ing+isQaaM~Z(`(0@V&U2AdAbO zdc~J5h@gK9FOiweBCDL(n>b|HAt3T<_!15LlFMHAoQifv5Zpn^hrP*aQXnQ8P+@|r z!T4&!S0yZhIDPhXb6!a=Gmb}KA%Y;7*P114KA3E;lIzA4yq#LhQuvnj=aXtZ@!@P) zwt&jEZ|jMj-&#_ap=y=DlLQ896-yZwh^^Y#m%XD=xXLW`enE3~d4WAH)^)GKC1}^E zVZY!B`VVb`m|-E1?d$Buf{<0D)6DJ!Vr>6lxmvxg{;xNPfbvJ&`%Yv!d-y~;9WihN ziBbxgNM4;{K@r9PA;A4M<5$;PZR-%n2)htva2~5wM*=l(j6OCt(Hn^>E;)^s z-}{M?mg^LI{5p2J=`(01mV+RaDa}=f+4!y5mUY3Ke6y_IWuMR4|7KAt&`-!zPth$;I%ej-UN9?gsIj6Fw z3)2>c&h%X={tw~Wg%37pp`2Dz8Q8C@F@0wxMzhzYvzA-&9e&p>qBCd<-FAg;6jDY) z_f8f|SlFy?QiO-!97l$|hbYfC*!wTh-~))=P74|l!D)y2Q|%thZtzKa9+_lp$fQ~Y zVkDTKPlKp$=-W6VRq+=ErORRjjY!H?HYX&|&sKf{NkPftEwL$Pn1M-G6x6=h0k*Ce zOv?+)=4v#5OhDtv)B(Kt3jeG>E~R&LO!h~cbuO;&_|{dqmeb=MTa(i*l1{VB_rGg? zZm$$Wo;Lggs;C%;D}o}8VB9@jsX=7N(}juhf@)7ZKPpF71w;H zHMIe*9pW-M-;I;vL!GlTqM`vX>YzF;IkM0-D^*L`hx=6kP_qei8q7Waaf-#Tz*u0W zcWUj-#8mrQz#A`b!7fEe2!$j!r_p*nKca!WW|?M5Kahd>hYSHijFR1b&+QVW?k7V-RXb3IOIdsJ!I|2D@;@QQWeXKp|>2(pv`m?8sQA4`F4Ac4I zSUh_LhH`r$zCWYx|LB5`J%U)f#JgynSQ51_4VkI~8M&otVFOb03_VOS2y(B_5~H3F&V9J2Ekj}wN^+{}UpMiT(oO4qb%EUYCHW-yzY)B+82T?$j1-lE&k=tT`_7 zgvI|b5EVc*cP)S z>tI*BQ}3(vIZr{x15;esJL*nsRhiJd zoskqfQE#vWdymI82w@Q>PjWJ!7^~fzpg&)B=LtB~XtLtW+Fp2LDqNAV@XN+gNH@=p zdG?c3{|rDS&I=K-QqF~9?Fi+B(5RS9;6Dzg&?W^^{h}IWWlU_3j-d?DPbrBp@+|#a zIox%5FE;whHF7mej{o7*zr-DDBa>8Iu0ke%E;g~UcUrv99DS5%mywzC#=VWelY>hr z{R^P$W6#V82it|Dj@{$m)LJh@O@&g~kDN%*3e+XEuMr}wc(sUqbrW&p09e%@&7UuM z1ApK9gGOdKt6Gg$74qq|eMWYya^#-#(Q!+a?vkO(g}T5_P^v&KkbuyFFrUDzW5VY#xJP#<-3n@-%p zf8=?;PG zygDJ4XH*9b@c9?FxZbST84yahCQ_#2;9LMiUE`U&%_tdqUu}%ASwFb08f{j6niK4@ z7MQbo&{G&yK080(Fsk}osa*g7aARY6;`Ey-m+E1D#9GrM>YEpBB4oqJrJrNFr{9K}R8nONT8BslQf73L#IG&Xd2Wq^D&i7fy6 zb+PP%3qVunK`g!_Vo{FSwm(|@SjVhGN+8f(rqT)@pfc;F)xum5Tft}w#^=FAHFg~4 z!_@vZhc$2q>=9KjtA+GmJ|@_5|HlhmQDfb5G18Rx+J8#JEgnfTfFCY z-f_nFr!bI*z1LoQt~u}fy6GkhmGq0XHWEPTz{w{%t5KvJ2NJ(K{*h~MCfA@)_tchX zTJ+6GfY_t&KW-(nnE`(hKZ=AeIm48o1ksVeGOh$gx5XnWfr2P$sLo6J-|aj*?P}Pm zLc&|r_bHILW@miqKUY?|Op;iPm@GOCqfRz*0vIme_>@THm+>1bOdlN_^GJn$PXMpo z>u`oxn2$<88zvQqfa+n3MEK!Qe2Od&L(AJ-8^AO8V^TH76tthMTV_t4KHl!zUJUV7 zTg7{yWi-f)f`P6Q6+-2ok1ZwL$!t0eeH8ieGkw#aqWN`lyx@Q!oqT4jE;UeBo}nvC zI)*fjX|Qv}n|yR}-4eDwG6O6;rzF)CO~i-m7i5mFZ=^c<8|Vt_dAomJ|1K;vzM2=> zRs>R0cZ0YI$vkNb3b<%S*dSPkn%{CJ;^{%zbB&gGfbAKU;T!v^PIz6Ee9t8GiliZk zNjR4DFYS9r;@YY-0hfd9xoWeCKm?zVTiWh9Pa)Y~*rC!(zrDY|bv}}`v$M|d+9$D= zNm;1198vd|Jk7EFM!hQN{EwPqj6!aH-m$dIakMX-SFuXP!K>>JDzD=wnI_Q&QB2ip zsrSpHpL|D!H>nyuuSp-z{*J6wSuZ3gB;tcu-n_4Gm|EYaMp6WXENmYr%-Akw1I=JC z6SZDFY7r^5V7@}?_#y%Z+$Y7}Z;QkGGv!#~1Aq^0^l=TYF087b>+^6v*jpetQf4*8 zLY}yPau^p}t?IRrNk)QUz(DfZc%eU$pX>U*wi3C5(gB3ln_p)x0hu0S7uMXFE``4! zHr;mosj#pXKAAy;^9Gn?@ptzXVMPiLB8@+R27Yyd?R!cK%YOOa4!6jmy#Cqa;xT&Y z_Z>n!TRL88g6_zsL;t$I(s&W8jD}guBf^EL%<{<)em@kaUp&;VaqBmttvz@d{zbJ~ zNs_#+sn1HEW+3(71Sz^vx<=!D8bM)?59e%<{xV4B*lBS>Ezzw5JQ{JkWID@~e`%mH zsR3$WE)xVcC$l0964e)6O%(In=};Ur<9LU%;E4BUDwM!$!}A!Ca21J$gz-{rFSlN6 z-@fN2Fk3!LSjhQcHts7916F3k?Hd)QV;%$F)m138q{hb)>xt`6R^;Xo;!}NRs`xl? z&YTnX+ULM{Q*36Wbocqnik7}oN~WsW4{V zaEoJz9=@W4qL3|TEeGu<3X9m19MGWz7H#2S^gwI}FHxDr7RPVcedQ0%G~dE`9Q(RC zD&LKsY)6E_za};y{7U_u+d3h`UjhfbZw4#3Rg-b)0%Ax-a=~nQ^teP52uykv_-4jg zwPB-N;t_Z5&Lsa9R>^4Ixvx3SfQ+SfKA;Q>8$?#zozsfa&;C3%5A za|nBr#vUylxU&IC)zad)wdDuhJ*OUc(-wl{>DYt>jSwvvDo@E@tIQ1)t{C&`#gn0l ztlsbrt}~Mkx?Kf!WD;))}>!pk-&?vSC!`7&FyU;~8M;WLnzxU1!C83c% ze1}IR?lZ}rgDia7yfk?u$Feh!$~BKfSo)@L#2ogCDR=d9I*gOaI3zNNKN{--x8POZ z@QK||psO0|i=!HPqpGNwj!-QBt^7hO@J`{%AbsT`}hLq0jt?? zdiqAb=#y6>b0c13gZVKJtG~}PX&axL z)xSY;G#folwKJSnF-@UF^Lh9?t2UB*Ph{Rscmr^$dprVqs%vhrtwdb-17e z+T)-tANZOCWCZUY9==yARG@h%qa!r}d9_&EPu?Q`W-9|NhEbw+9diJWORY9Wgm#2l zmRTMaN2~Al{Kc*V^gULYciMK&EhzWZoSAF7)DJFdmPt`$8K=>g!0m4Lqvu`q}Si{Y)XLUH!u^@Qj@kdO#S7(J{i zezmn9E7w1Ouuu&h`+$XSZ2Z)Rox$f93&rZCnH-b|1&8=bkQ#7*e?^|&i;o)U1S_Nf zj{%E*>tcDQoE5=U1b_17irwG*wSD})M_`#A1*OwR9GeL*c32}0JJ9<7e^k7 z!Q;SqGG&K~&EziBSp`5PU;y&JQf}xqw}TsdR&N_z%GX!;;Y|P(pa5nYKbVEJAb1#v zri1*{Nzzr8MXos)T*!w#ZzBS+VukXgqP9*|gXGYG?@J@l3+rgni!`=Cac;$vvdOV3ul_?WxuEnDz2# zX(17DtX{s4#^M{q&>SzFOqzFQU145zG|Ukd>2cijFQh(*nxS?|UxkF`eOhFdNx#BR zwZiQoHpPZGnQI^rN@s%0kHXYzhx$GrlEsq`Oya63iUHBb-LN2u1gaz0t{e!8wG|c0 z78t5rtlC8w?=k<*kLh1v5AOw^XIh~pA@8>#}And27ep=`oC9cV z4mT*HzPxtW4SO$v3X9+btWau{XpLiubSf0) zuzX&casgB#Sa-p{_+}xB;~d*plPv3Dz~~=B$T#kAIg0}GhR*9Ut(Mzj9M-}0n*B9J zRUOG+HxbX_fpWmSXjb`{5oaw&WHyp2vEqH5!2rb?Pwzzs0tXVOdPC!Bl>Q*2B|5g* ztwE1aaOqHIsU7Jw@-x&*LmT8qoq~f*J6ar9fl}78Rm7EyI)#N_PO}Jm`A5%F*7k;! zpTw8E7(_VSoXcuI6btlyZhLa__moE|C$&CsrL=)DK_O>>d?-_8`tDW)9=FRPB$Q4}%wwmuDG59t}jqH@U zqjan3K*}e~^3F8By`Ao2M8p+wGb1jL`U}mbACx_Lj;L)_4Lj8Ox;Q|suQl@`(p5>1 z?}n#^U7Z$hhY5|Vv?3JdN=2ms+P8eUn-P-cm@~2n3>3WSSpAC6UpZ#3fS&oft;}e~ z&QaP~2E>u^0=ake@?=^8Qc8Mz>O>w6e>2mhvqvYn=$A5rv5C8UE_iKB5IE6urX|WT zAzpD524a+3!x^D}606#g8~PHN>LX^1kR-w9M?%gg*4?#0+?{@M3ZUgZs9- zX~lDu%ia$A_STF(dcoH>1KL>W#=1i8|ENQ2#Q8lRRZ?#tGF$K{6)?jib3vTzt1|yyazW?y;4Z_-e{j=kum^;&lGekyi$zorP zWn$;J(q6pUBl*Z*TkE=RDKAEK*l95r7>drH%IL7*mtR>+P(w=nNIN{gH#L75kYNnW z$YBXOY{+4U3$DODtakeWV>m};q1%1j*2mQGi_~yCN7qNE{pk###=#d8qI&$w5U{O| zFN^p-gE#8wW&?eBlPJ!_!$G{2iO7D{Lh>M+%ueS1VoyT7SQun21Us_KQCV~|RN7=| z`Cc5p#B~*cDoAIWNY?vuQ_dtFHt*1A!b6&u^RTlPD>}fF0v)&5B8R!<@_~mC9cd$F z$ACU!Q98X1jpVIr*9ajbe>VK<``wvJGM~xLhf%)0`Z1wP*c6|^!zeBsRYZinl?pN% z*)(eLx!voi>@gg+VW*8dRN53UJCr%iJA6D{{Lqg>1aiOGGcq7ZLWl~nlUK|8)0+s0 zX&r%~%E4z_%#M;r_kbKUK29UgFNyTX<9WTe(lK3UZHb0xfzo5~`~*X^rsRYD;QXJF#fb~(UV1}iIG0?ANG*7!;=mQ>j-%xcLz&^$kT%$66^EQXj;S(H4z zcSxNH$wu*2v#QCgM;)Y&`;=%gx-*THzk1qe)-CNo3NTln((N-EW6W@cKbIa3Hm&KB8to>;rZ(gbz3oDNfrB%R;(WA7#ub#}SZD zj+a|@EtD}rMN?`Ku9IVb1I>$S+T>3b{tV(C9?qF?Rb=X;v#pgEnKS{PO4qDqiBAiM zHXA!B0q5uJa^2rr#XGzGr{F$gE{X=&th8qQ7)craitb4rJU2U#10(+WG@6@|2B?Rq z&I$LC5dXc4z&*P&8Oh9l-es~vo=O3;xCgX6Q(JyzxHSEhf{qI~opn+$jTwZam7sKWQ_Y?eCdM&ncP4xODO=<^XapAmD4 zbQ(FYRT5v--5E-a$}D7eb_n_E*M8L~d&)Rknu?b}MvJr8xnv}Q-1qgU7Aley>o(!i z$i()2);3Pdj`Qi<1I_Q(EIKt|u~r0RKjYt|3a@*PD?uV})UrjzzAW7_mFKR@n9G|a zlh{X}UU$GCSRDSY)d?Xqj<}LeDjF-1UOfm5l+Ad{l61dIRjg7C@9ysYPMIyGHdU68 zj_!q#3i{U9PMa%U%62l#IQp}^2Z$ynz!*`qTzJ_hP~h6&aiC5b3S{9Gh_&Oytd~36 zA`Gpb4>EI21_+DnO0oHP-I$Y7Qqd`xKDd{|Z3Ri7(enO#*SS$j8A@)ngmW3dh_$M; zQb}8@9Dq@C=*5!j%EXWNM5!s=_|m3jqa#$SVNaBX0$9%97}Tz61?3u^ylKok36O>Z zg9SygK5x^jP<-65jU>QA1iYR^FkCc+JX8i}j~xt$AFVX?!cKwt0I}XRFtlp1jY=BP8K~9!){F-g=RIBnI0GbDwj^!PQQJiE_yrkz` z9S|JFwx9*XVuTe)(LhUM84T!NG*SRVmT`ZVQG{|kJd!(`$Msp%B-f^1RVoS^^150j z5PN;Xx}B51U@$@A{kY4P9t@29s=!Gc?Yr}ZnoX}6KH6ZS#)9k1qdJrPt@&ecZjj$6 zQ|tcsSpTa9*on@#*tczSSjJmK|1QZ-!;75LF;d%bjduX+Go1~!)&D)F1Unqt3PlNW zil{F3h7|IRwFWU!%Pv+ zKkCy1J{Oo%_cg2qvI)H7n~^?IlH*4iO)e8)ZQb-r)zR9`dX>cs-CTxt zB=l%i^yfOY5A2UyAJZil=<8#fMTBi{_$zkmmdhUWBJg4)c6e zreHam8;h5;WF2gygGjC_{W56mrT65p??L>E76Cp^X%vU>c)eI4`~>KWy#A~HSEx58 zOZ4`9D{5Rox6Q@a8cHmR?G) z$ir#peHaU+IBzj{Msk48_}xDOkJX@jC<^=4cAsUZ7up@Euty)A_AG{$ZS$y4dQ+V`v_P8rJJI;dNpsz?5j-F z=!dz9SAxQ^Q~+Bj^+dEMd7sZlH3E02e`qL)N&cg+9UF!o`IK_`bXay=-6`#J56WBb zZEjHf0?LBGfO?wft1v2~N#PD+MUF`!`fBZeUFZyE%@4uvS{R&=<#dzzu%?->;krH3QOKr%s`&~Hs$mF${ZQw4Ft-;|~xLWuFc) zr1U-!lMO{AEOoSQz580e)L?@oHg!$n4HX_}vI9<*HL)pD(e<-bGRznu@d5+WZ=DwkQE%_K1tQT5AxDUU=Ooe`- zA05=i!;0MJDxX=x>KCmpDE?pfvz7j&$jQ+OAx7F#%6QvzYhxh6xl=a7+`Q1*R znlE{}p4dZILi1tvfE=n#qMWTrz?w$v&+)scw`Nzwa!GG%K|f)?p!g^cBaG@LOfdR& z;+G%d9cfjL;hKG%}kU zLQ19r-kFq_ueB9}>a=KnyKm6inw&mZ&XkYm^~Nyl?y3EyMHnXM9ho)h)B@`s?@eD; zmQwL5cL$Uh!%zB>b<}wnV}-)`adF5Qx5uom&tS}IVu)|0E7i_`JRk{XD;o)_n+NXLJAze?S~6&fq$p@;IhL9gqrg^>YVK#W z)d3^ofprqpD^nb0z?%JdP(&ju2f8d(iP4v*rxdowi3)v^2>n6veZQ1GRNd`dy$9Qx zU;=lFr_c2xWCW8~7ebP&C%TZG>(`Y@`<{^1;yXxa&5Q}}V#=DW&I5KJAXYajApL-Z zf1W2DJ-Wwbwg=q4PR~!?w221Cs`I2S;XIVq^EJc+Av~1Ybq9hoD^3q%e47Lvkh{C9 zY+%wL(0Gj5!PqgL|nlLUNJ3g{o?KUP!|IfyYQf{>larX@uz%)AK>M68}X8sRAYs#rkcT zOLb>ZU2X320E>tHq$eN?Y(Hy@+)6N6s^%Z*(W&hI{0`>d+DJ%p*c!LuwFcccr>=X9 zsWoo6?futnE(T{o=%z3CcCCf>_`>$HHvpTGAy=GzZvIRq<~3a^Yu{^eqx02!kQREBW$e)pYzsP%;&AE2)f+F)5%K_ zaGCNhr4Yu^*qwm7E}N#kW(-CUMzQkSH@*Te5>g#urP`FHYIiB^Av~{zYT?=hOZEGvy8g}Qv&WO{ zSH8Y3gQPb?*`YC{9J0Zl2F6h$4xFK*v|gbZVufxvgjjOmf#V_Jf^ZiFL9ch~HJQK+ z4(CR29nWFDUE6WZI$8#~p-@ko&$IfD*WF8FuH_AB!r|xDP;y>BeL}^ zEd}ze$%vv5$$qD0p?RMiN%G}&0ab(4LJ(?O+&irv$!w{+j&MLS89-U zdba(&)S%{ORpm~}a3q?(Q?WfwPgog~yKFj2LlmV<*zqNSXZF^ZN0^j@!1G~~=m->S zFWGpvc(e6x;?8e^?~u!^Ph(xXIZRbQAQIA>XTrl(OQ7M$WnbUbT7oA{h;}a)2M>*n zn64DNKc1H2gQ;vPBhLt?G@^{Ooy5XMQ{xzDwgU9i?ZFA*&r8wOfCfT7m-HY1JS`Nk zAZG_fdQ`kcYbWu&oS*}rgz#}<^|f)-8@S9!t}ty3ZsmEx>59s{kbZ1aD8i0i+%L-N`>$Uy z4GmPC2MKN6>)$>-jeep%&XYzb<7|B0Nha5xy-Kc!E+~Y3-UQHmleNngZ; zo`1w^B`HocFh}*S>ddiqx%9piip?@hZk_XH8kXo*LCx^?ePV{B3-eR-(5CTirtfSx zzwv(4_C~iPn(?Wa3)9On5JJccu>F8UxcPvgJvH*K z4yF`)%`yacxzI4;D!dv`OQ1d&Gu=A28Zp?Pu#=e>K3WG1x%U3D3H#>7#_bZ?R*I2I zXc;?S^&Ur@$o}1j%e(mudHY+VeY!M>{qtj8Q)Y-SKc}U#Ld!L?V+1-{%{AeH`tpdB zquc?{+xa(Y8wMl1QPVisKOO zwJ9loNhdPmf7zz*3# zT-s0tdyp{V|4z@geQDeF>V0?5P6X4T?;BP3)5T8Hdc-bw?|RzUbiZyoe|+Iz;Ic;4 zbSz)b^?O7@?|2(7?U}50X*?I@?#8CZ@qav)<^T=q#b_%p6u2XXnMCRCkj8G0RUrSJ zS4!SedYajKF6-7KXDF*^6<^IVON;c45NVujAF-NsZ7pld;q@nl>!D24fBk%1l&p;R z$$c&Nxi)`yjTL4ygbpT;Uvg|4Uc^A_!ykVpzZ^Mi!$hr=MIq~wZH9b#kNcHx>UWQJ z@5e`W{|t@Y?~xQ2LH4Fc!qEb@YwIK!-n_%=z$6ZOEk4x<1#>r1xzTH_;n2~Nj*)yu z9UEIyYx#{8=Ze|E5GT4uS{EDWJ@z#QqjEZVw|}X-YJdwH38p|0h(e9Tpsy z=+FO8P#O6!1;z{_A%B$b={kST>l0w?uu7im5tXs9PCOyuGzm*ioXW;=PA7s)8T_A5 z@%rU+asK~4mwi!vae&|Q2I=-v8z7NKGJNPS z+%p}5rnB6Cf9jY4tU-4r1U+Z%|9;J$z`sFqG`p<4oYm=co#x+C6CWJBFvo`xQ3h<_ zQv(0o8@^XYQw+s|9JoSv1V8{RYWh5`HGX=^2UM6IJNa(9Rbn0a=DZv2{ zts&)9EVfK+I5?pKPSXJg_59Ia>>9PrQRs+NvCP0Yk<<44w7}hr)b9`Sh!uc*HxGDd z$HDPB(PP{Cb-YK&f3K1e=F1&@7nqaw-vlwRaEuXUZZJB(fugY}sjTjF$}L}AN^UJF z0Gwh*ZuOTx&tlBGUkR9^_3Djn2va&vyF%t{pim z)r*=&(4+VeTsP4g3i2FG+X;Kmgg?EtSFN)88{@8*6ukC5$wtU4^`?1*!*xZeVL~t} z=bchp`6>U}o>~=UULA-Moo1wb$)zTbK6;ub+^Ofe8e972>fAOPplM~%+eCmIh#< zDg}6W31!-$Oe7RW7*a>BBC#DGbmKlp*Qs=|eD17ZC*`Qro2|M|A@r=IL5X|SzP#2j zU(GM=OQz<=f9KW6THb;{wIK4JV0-XTpuC($StH}WFb9nf4cdmLT{TNoUE>s%&JF4fm z!by&T++RoZndjW>u{ukOeM3WsOX$knwX3?(8F{+wsx?6&A<7RoN72iF*7j>^cME!! z-4C+h<4Y_rqFaJrP5q2Z`4Jt8QCAdP))R6H%MftFXJ&@y;Ns$ff4$qPY$=UcPeHqY zNyHvwb1?b%pF1b&^rC{=l~h}j2W!!-5Yb@6_5O+_pevU4{U^B;_M9Ov?0TCe>cncm zJRqS_Nb$>~^3iWeBNg(H(f2x~(fs7T;LaH7x1siY@(PVV*wxCY1Ou@3f5;KPHTT4gXX%QzS!xzTCly@v^`t$0 zQRvw_Y!wAnSeSSZmH;+Y0It;{8 zzyL3ARHjf&>h(ZVw;*Rjk>!7O%l4)hg2OSg`+t@xSe6(F{LIXe+k>g^zp?4RNO09M z-qx~w*L9&y&)AzjT&S_@fIjm)@%vO`E(VCbtCk_CByz4t%Q@lLbSeR`NRXfO!ggOS zDG2YL>!0eK`rhVur3sE@krQUn%4Iz~JnY_7=Dl=W<)J2ktQSCfI6kOVO|N;h zxS7!zF<)od`<0pEzJ?=8+H52}r#I&Dr({3Y8YA0KPF=7+X7aR)#s1qzp*4tz&qWv- z$=!EkJO(-NQmGVN7$hyL-4vo+?6lZd-R=b(bhypo>tr@A=ue9S2D30 z!PHK!6aW&l3Ot~As}gXD9`v**%-gUSajCQczP)e#JHRc#6~4B%rU;;(Tr676De~R` zJryc0UMr^&9a%BPRWRsYf3)P@48p&9zx)If6O{zos3M~txyfp2bW%^jztd?OVQHP> ze(kuw5mk7Z z&P}BBSQ|$muZf5E`*=qh2qX(%h(m1p`m8W)BUP7A9G>>`X#!VP3So7i|DXas1_*cy z0Hg+6WK_@3?ujifv)?7EY}$pdyMzJwVlb8Kod+6!m5=1YAMqub|7`rtR4*^JXg|#u zb?{=yMTa_s9Zd}g40I24zq_yi);l6#jY$I)qcMerj&8ceX*`Y28SYFpAx|2kdTIOc zzzPET=tMR-YY!7Yx!pKjVbz_Q2>-j#KtF8d7D91FDwbPOm5i-hl%rCs-|xiyi&+jD zc5yfZz9wP_J6zC55%LH8QA&|X<@~(*z8ZrYG)J@wP7da{#+`US(crgGQ4pD#>FS}R z<1eTo+KZGr815ch=l}UtfaZ>xaN>eYo6H+x{L{Z+?Z-&CpKrulKfZq&kL}*XjZ%LG z18P}q<5)^+T=gL&N5HT!FlkX^v-ByAXP-!JbxjN$mMDv)Qkw1Tw^sngC6iVuQ*uP# zoIj!a^p}mufl?-$n_>Q`W5+x$?w!vsmd3{M#_FA-XTK+IuN%aH3?{nZV5W-50~M?8 z*N*!xRG8(}30wjhz%%_-bhNLz$}EC&=ESR&H#6B%mUv&&DLEvNlx+XhaZ|wP?=)$qdMZAB&|3)F%>1{W}gni1*k$BO)F1^Ma!Dy6iyTjyEmgz(hcx`d^Os zy~~FJIrT3cYPTzc*h7)M4;T|6e)+qld8S++deC)$nq?Cx@Idwr8eMzMHFgExZ#Tnzce8xt z&Ep_r^jdXub9~T?^at{B#mjwfxslGpQKJ>!WvDxTlVe>h?}z`T`#oZL?$<;zs@JAg#~4E<+lDydwjMGlZ?jYHvx?kn0z<=!wQ z?qL4~QC=QT4+Jz<3Y}#Ega{N&VAC)z6lq_{I=5(OYN~eVVaUY(`;TG=9TlY@2noBA zD;m{8*$zYKM8Co}rm z=8Fv++{S;H2jcm;dR$!#VUYwsiUnQ)5q+$UPMcy!2Sw>unPkC68q6ZdtA@hojoyos zH3^4^V<`qzHx)0w`k6lBM>~VANBkA{6F=X`ds^A}?)VG!6WR3Hgi{12#sM`~caso~(}?wJtUB^H4=*v;E;|wN;7n`jjv8@Od^% z5X(*ZY?Fa`1YQgqm#`CfAzM7nkD6~2N4o;Cs1@-2v!Pglm%;p?!5$=#IH&PA((>~Q zR39Qz!0#Nq^lk}n60tmKe}EE^3zN#aOUNKXHi0HDcGW<`yT>(R#3Xhs1v+6g)?mKc zl?=%7W7Un6RmjPZ!iW-o`kX%S)5yjr21tn0Lm*)bu!Zrk6&HjYS^M{^q`oE~);f4TFp_R-E8eiD$#&1z)Nzan+Xy^F`v(b~YtBHn2i) z%bA!Cw%H@>HDayj7mhtnB9D$9PvLyfEQll z=xGuC(w;nu5X;mT=)9A)aFAUnlNqp3Oy_Ed5V-^c1|K8gJD&0RvMi39{H?y%Xtg#= zX<#wGk0SDxRUBp|{u6FyoGxat+T`KcMcjMrSC2QpzWy-4A0vHn(jnn-vr92@zS*x= zW_E>`21Ft8wj-GryOkor!6ETx@zfPR&7loF+4N654EL$d(JcYtErWrbJ{IsfhAB!< z9$_9}%pb}2flowx@`p2#UfwTK^ExaApX=lESwkV&d~KynA(T9j6UQz#QLgKGr+@in zbG^9ic$&;0lxKckm_4~&bbgo@YjtG*ZD%lOTXvbeoyPOrXPGtw-EDbNGM|d}=y=)< z;Twb-HE;^-`}=o6JY`muy8rheFYc-m=+L{BT_{@E7%Lofccndt^%7X((UPKZ{u*x2 zG<1z26Z!#IcVJBp3PeGs+9nLn?_Aa}{Ev6y{Cd}}MC#{+_h)QHv-ln&({)G9&?AJ_ zm%^W*HA{Jjf0R-g-U^*=B3+}*_*r!e;1bujNQ9ct+Y~MQ=M?0R|B|1^fmZ495=o9R zfe5_6QBEZqEDWI2e*iphzp`HVz64yKjifE_1_^4s7kG zQx4Ox%W1!fSdKu9G2%4iJT#<&3t`2|OA20}>T?1P! zl7Iq`dV|Pr$8L&gC zMNxyIu3T5Vjw6tH_1)qMKbKON_QhrbV@l_+-udUDy$TjzjqHlSC|3Xw7SE_eKd#q>SAB6^HO~7Q0WfgAn8Tip zF~Ygfa407Xw*UsX3zUExK4w8x2-GRxnShF!aTsP2aPeqmPWWAqn2jC4#H3X-Hz<5J zFJ?fs(x~V5+O7sn{Xms`Xw>^A2!Z&+1&wQ_U?kCrC>m-F3K|chA1F*5MVi$-&Ur>U zGdXZUE%TXpZIU8Od`m8gL2X-M@fu7&M}bItjz6T!4-oy&utiphi!Skmu*k67L zRYDJQH+*+V{EoOF(3rA7A?Ygy;R%rKj{;$#JF~qA1P|C-jYC0j$@>n9ho`3FUHs7g zAQe#LGkD)!O#WKi@iIay+!$$l%0?|v zO)keq0ocXR5F_8mOT3pf;>w_nBv#$G#i|9!8()>lSXKtH(T>G$&=GMKo9uErxh>A9 zH9&^Va#WYjiFeS-!BSI2VbOwJ4rRyp4u+B=wYy!bmJGLZuk{}fO**+hl4yl2O{=N%63 zc>Vx1$#(^p93dLH#8r2cb&L^yj|+V3*%JgHvxo{N zMHmVFx|X2yBn|Yewe+tr|23HI^SU(Wq{zpzLoq#_=wb+J*Vz;RP4pPBmi71chVIZD z5bh6lw4vL(DVJ!J(K{C>Dj4~t__uWY_~nut<$kuAGmyjt_7?Kc%!v+|dyAd&rL~PW zF-V!nTTIH!Ubk+q1s6B4#nY`A%m=k%v}v*neVXa8Z@t003Y@yQtoRX!F{022c!k-kvY=mGUGqEcRFlDG_j3?5PW++8gXic8 zoFl+s((yy-N0s?XZv;3$@~zrpoQkf~&aR0IWQm$fkSqRTJ<5n$GSp_(Ylcmt*Nc2w ztO}N3X5qa85K10xURsC&j2j#D#;4jZ4g$b0CI^l#1*!$Y`5ZWSmI}gcH`&O=7^m!-^9N}Dn=;JkTz$K~k0G*(5Do-Np zn}Kf|*ms~BsdlUdBvY5Sbv6r9FbHUyLsWfGK|CKy^fJCo-vrIq+K#{~_(Q|p*v2B+ zsX}MLj)M4Q_w%s#BE(=kJ#xP1)f=5rq}&nEyhg_3!HtbuAk6#@olI!`J*xvo_7eHq z)eEEQW~)6cfM7(#=C<38bE_Ns7Uc%B)FO@kLkx>jSq zKWz;ZP=azmxCgFIk`mdP9Vk$~1DthdbiS}Oa%L2^0zKTxImk4cm}n;l5I3BH6FD)k zBjw=qCrpqL@s0xRhB?6Xf_5Z@h79$IU7E7JBFK=i`x$it49R@GnW_;$^&Pmildh(Cy1Q3)vB9D`OzJea zg||K*X#=$)tUx`8+W7%^oXQ~2F9q?%Is&vj5og=|U3Al~M~gYY?V$`Zj(&ESp?-v` zv%W`riI8~1pc53%kj^ea;C!&l!Fbz&@RC^P5Ey9k<{!N3DJY>8$Z^?J(&K?P;F8Eo zYOdO}U>QJ^!xQL=+$z`8s(OZ^0PaoROfl;RgIXat{J)-XbfLG=53T^9Xsc8>D=L&$BmA(I$<+V*3ml;}tTxxuk*@&VtCxyFpH1V7k zW-_yu>TlnXm|jNbw8;Z*iMW8%ZlTZKToH9f%ZaQ**3BN5jE|1@WdG)>>2~79Au+9z zJc#g{I#6-Jt&N@yj?ZFWz{<`5$m||R>$x*qi>m`$^SyD?#3?$I1lf-;^Uk}XIUOC` zz8%oC)S9I?!M*sr>1?)oE>;|5$M;KSl=%5fh|xhvSmRTcn(hw8$C?#d@*p)O zAG{k>afr=lEsGO>?#ixW&x4q9Y`)eOk4kZ53gfO2)U8@XL-t+3 z^M_$DyRrhC3E9O=GK5qrsI(153VMhNmO1&ey-cX>1w@g(dN_S@wUJR8oR zr(ma%U9WEhL*Kd_$bd~KkFD(?V5iVI+@50TS1T$pBrN>w>Tv%24h{=P4&5N)9q}d` zj&r@uN-k))SFh)R2S1YR0PrL&zmzJSIQ~Ee{Jso|>m5 zXG!CTGif}@fu8lMD~vcykFdwx9p`71Z8mCGSHAf=Zvj+%cE1@oTQ*y{6ndzHdh!j? zd6$2a;fw2SY2OKA_uv8oI%)hjP2@WMS^RCdW$%xLqE0;4^FdwT zTS+;C7C835&%LCns)48L)*Jr&JKxc5C>VHEf9TuP6GHwkI2*TMoO0@kd=<{?ecH2= z$fu-7$YBI2d)`3T2nsM6iSG%Wxr`BJ>^1xYSQ5GYYClfWlz)jr`QV1F;jv|^T^|Y2 zn?(~Z3NIp@|9kOX%~rDmIU94^&PlmqD(4%KndGY7GAqeRiT~-(a=%cM&7oD7q+a^7 zu86a$qmd+BAyP2}UEjf$Lpu(H*&xfCZ=$);ac{e9A-xdlyIVSIU^dk0t5m@=`gZ<6 zqg)XG2b<~x{-jxg4q9P%WHwq4@OJ7e9Mkglf)K+N?%l9XqI%z7n9>c*^`ur1@wpJ2 z4kpHhppgtT%7W5QsjcEE1Bg)m42!QzhR><=(rWc#S#f8<3xgPy=hg1s1lspM6jC{> z?z*YOpwBKZ3noBXBiKC|T#s~uPC{z;r^i5l!@N5T^FyO5jmO0e$L-w}B_AK&zr{ur z0V_!Da`UZ{iwpuPv1AgXdJXmKr1wvNjZ@_KZFsUmU!)Zsz}_w!Jq`({ZZ@$s{#ng7 z#E}Gp_PO$!I2;S?PJMdpqr}b-p0BGWw6lph7A`@VS=Ag?ZXA^Lljj@S5 zcT-3KeaUCj-qy!^eyeP`Ejg$AEP-^qtpp|EoQhAiMuEWz&(}F!phR$X(UJ6~%mFCF zMX+NvDdUoneOdU;BM=NJ3l+*)?;ouQ9SqX>F#b^9=H2| zNgWTyi$*U8m~Jc8LNO2*vDI5N9$UX!mq>=M3w{Q9=PW{~CRKpRQOWJo={Ar=MHh-` z7`bYmvjn(%CcWrulH@2kM<4)Yt0fz2T*%$wo&rQtU`f z2jPyml~!Yc_vw&0b!_q|(!kjLiO_JuAVF~CiIae-x0;jU`mA6aznk!^UI;FN%092Y zg^5X?R3h(tLJeE7pFx#@oca3tK@4xJ^XfcD^fX5OVtN=K9C#ZgJyrND>% zAf9tnUY!u76?Q$C9X>>`xERT3s&PA|1oL0w1c`=Y|3Ke~Y=4*{`5Bvwo*mS=ALY7j z9s6oazny=IJ>C(EgZsme)bHn>%4CM-;^Xak>wx&FYeabCge2Awe+Jl2Pv>1u$7$|P zd&z!+3E^f!PiSYSxW&egA%%v{VPQt?kPJg(xcBe=Z7n49`wi>IJ zA`-@${pxUc+~E?d_U={uH&Mt(2F?9YN|8{iEa2a+1B%}$5`k!-5&fL{-6H@V_6;JT z7a3WQ{L=;Y-Du1V-Yo0%7U=VJUIkvtXSr$5|9*;z;&$4_C@0sfSG2CH1i(?QN~lZh zKKwyzVnXttTsWa9c+4gamzBP+N)k_w2sz!@>y3vO-F4zh%#`%&tYZ@(+@eL)iM|;E z&YSz2x=mJdXNa(pp0A;*U|A zP^icuhM4rRt<`(?Avj`Dm>%1oZJRGF11L4CqC9A?xKS6pT?KG1P5x(~$PYU4*!<0t zQ!mp?X36%nZ2ttros-F*6JC@^g$RWmu}7}|X5%szK|xYk4crdd*&Vbxh-m;`J9c77 zRV0@r=k>OPf1x{?KK%k*$Vwa{Srz-Vnc^wUM9Oy#v_7#x*vP2qySY^(04re*2K?!} zctOye1j%gA$x8fjflz$nBAbDzeCa9bZ52NNsq@se+Vs*e=@sujSZy2WWV0B7>HgTz z!BU{BP&B1kR%9B1d+;EZ8puu^R3Iu4?N0PeOxbz#=pS_WHt^x z4{PRN)_r#6igvM{Z3ySvv!gCUN>eLTtg1#~@M^j`Y>;0WybE~_kqABc%JhxRo(3JF z4G!%9za{S&uf#wQ-AqAWh!X0x@&q$kZRV;WBq|Hr3H8{%$3u(;p#o*6@eY<8Cgi>y zdCioZeYIxIqX=Vlc5@&jf)Jp87~z9DJHq{`N-|o%P?4jdD|+3d@Ajfu%yF95lXI|BQjc_p&wVb%=B-}O*5=c|$tgyo^LBA8u$V9# zwQVcQ?}_;4@Qz^h)fB3@+Ha@5L0C6 z{B&F7d7W56S+Tue`iN%sZF>8JnPN4Izi1G#zXWNg_#E#lVnCURVBIs)w_K1}vm)%^DR7`W=11HUNrfo! zG&OBR9Nu=I0kCg-{w{zL@mp{q5~_>>mBST@fWuMZ+{)luW8^)kR}!Zz66oHq!xr8U zSe*d1WR1aEz)96VHg^Rdt;+Z$JT5bDiFYV?MsTRa>P2D5p>%=4$k1OY79Hm&f8xGD z4AX*a$k6LHe^engyMROE+-935N;C_x_BxYAMWgC!{ta*_nj_F0)4A@Bbujb`qMQaK zPykNUm)j$64%8G6&o4xlFj>mq_UG^=)Y<=EdvE;~W!J@zDi0`%0*W9ZUDDDeA>Bwf zNDkedq9P(C%`lWS5(5mKigfod#2{Tmch2|bmFJxII@dY>z`0(2n$5tzcdYfudQ?0 zgvPz2kK~2S$0{c2eG8&c%1!B#6y8bCqd_8Z6ievP;T`L`(hncsC`C1EOMagXv~|qhde~Xta%sd zD}6P)FlM$$yD`02{IlMYyH(=c?rTG*kVNpCMIVouO7mhrzi!>#>N5X@uvrfjr)&r( z4A$!JE2xnw>op0($zoDpMA!> zi!J^RC{{YeO7jYddl!3&B6x$#+Od8;Z?f`i9rfqeiS@_Fd}F+DLvl-24?^q4y^ZOb zjCy;R$M|QsL?2N*XF;Jd}M7?%9@P z=h)Y{nDv|%;WH=VX#7sVnd4>a3}z)eait~#Egwm6-m82saR zFLW@NpG7ng>qU|af`x7rHOc9MV%4v$?4VcL^jO1plWS+aAU`W~2j2CWX9osAk-l41 zI_7Z;tl{>FSd#n%47!)KgRVAb%Nd>qrQQRgrCiiJ-@REs z991cLYTd|QGhMAXetsY`4q-^*)SZ;$4{p}i2xf>x0D~l1_FP|?CDXiMecXJ4Y!hx} zC~B8B&AIG=ILR;>N&84&q99JqVd{lsj8Ch}4AL-hQDDzor$| z;<|{nM2ORmo&jgR&ms8HE*GWKHs=xG`NHM>rzShcdQ55DI)kDo5x4?>GT)*0bYGSI zvH8B8L!kO7us?JO~z11WMC>mI>ft=IbA@ zEn^%9O7OnbDy@7K%-{gqiiE*j?7RFFw{4`PsY*6xa}`(0UEk%q*ANc`60s(fdMnG;E#b z+S46FzF;4BIHfY!B7hOuu7Ptn?FkNY(0{u*u{HEkw#r+bF?c0W)OWiML@V0dc^dc! zJ}gU~i@WLZ7P<+As%4g!t)i0MBhN$^T9lht&%S?xNAEZsdkLX0#nx6J7j2|PDw!ni z7v$&Da}*DPJ8~V?1sbi`+8(`ll_?Y40hgIUvtW^W6}u(=*ugpW6~3-D&n8GQH&d&# zEK1xvp_f8nv{%i?O3h85A8kRkS!%`rH!mw5-Z90dUkqgN)_!o;ZPTIpOwY$~J3zx! z3jh5b%ng}4!Fi6U-p?_qfQ-DhPpwlqxg0M~C$Vek+EgixY!?{QkaY0GH|D@_q>TWH z-smk0xr@Vt{5B_Q{T7=c@I%H!9wci$CcQ@H9>YW~{dU`!O%aGi=_*Q40 z80dO-#BUP1`U@x`M3~FR$KkOa&h2Q=x|t76GP#zW4ZPTjdHg5x-6%t(M|*;f&C-`A z)I&KYLt8Gx2lbmj2(2&O5g3t8LMj4*&Ef>TC0R6>ku4(U)@?ninMPJt!3?wZ!nj-0 zRd7C|>ade(mer4VvQqpI%H|7EzNBgUrpN)&Rn)F)S!YkfZ)9Wyb2wc_z_m|&slY^_ zYwEcWFpX8y;m#5S+{CHrhjMBVFd>M+MYQ+9Mt;}vp|c?yRSpDsIKpW#xLOPwI0u9| z@&}2q2D3qC`L64vX{fZ)=%bVkOwvvyk|3xNRgv)kSW~^sI#h+CR+{*tI@IqTUg^_} z8T!d(8@>nIGlg#M!F!zcFE>$8h-1AVpA6c2Aq;=cvFWJ#bf?WEXLt~k)K5t7lhE4F zk6ABXAp{uhhFe2{t9C=JQ5p3+RY@UfZjxnRwyi@3s=Zo{4e{_zEA5 zjb=UKWZV2Y5|fps`y05F9TACMfjChtvove7?dw{s!=Y&ZV5=dAdeCl@7QM=VP$9Dm zsk^L2olk0%bhY@R$DjTp?sr^Jzi@+r#QO7%qN+ipU#Pe_XYb_}EaoB4Y(vH~3DY^z z8djwXEgPTV^ zEF9~>_bGm8XS#HRHPBv-)2op=y|7d@PCD+ZU<~W6o9PgSwRLB`Z?_FM?R?>;**40l zgc*im_#J(z z44~TZ`{0@mUR3Psi|1e;noC`5O+&w^@9nx|^g%qn5q-_27|Nbuqgc<43xNCntl!>f zG>LPwZFgT!|M9aj!XhP85ZnDDsbvOTeYaP^juFXCRx|lp&m8!gRRKEOO!R~slQjH& z)dL>(stRDuGMI)=opkcV7rm`OL#OHSi2{O^MAocR77uy&Ts>ddue3~;Hhj+4(NAAb z_F>yDTZ~eBc(m2#bhPca6Y>i5dqK4$@M#bnMQxRl!}AY!XiMoU9&GVD7*$WjGYbiy zI05?YnkMdn5qTvt@^}b`qY*!^iI0MfiFu^ub2Ei%^(M`b_s1orkV8d}JaMHeqpBnCbreVUzyQI+=?#3d=z}&`_<1tpm^_-ld+OnuXQS7{icm zK^c6&CO<9jH=c0ukEIUP%2~bcv@cnaHo4#Jr_MU8QjW9BT0Ul6pHq76?h2GP9SdzW z!P9;Ba+4%aT?->46Vr~jBa*|}n{_h+&cWBdC$ljmu2VMovJJX8g6vq~tlu#J{f@D1 zvfZ3KJX+%ZL}BQaF8@&FxbCeuX(l!n1u(^EsgBlYLL~r|&%;p^bk1l%DaJ)HTA8 zVsEDg8Rh!=;sDix4%EVkgnw(06NLRTYfFyqlmWljv%1j8G1EwSV@^quBw%SZq?_q- zPuW6EK*OvfqN`1}X=~%jbC8-|t=qct4iX;9(aXUlKUZ1TI zJewUYnn&h@DiLN5A>cmJ-wxdG{?)pm;Tv5pzKCK?5@^?d$vg(s6L?C`&rYr=JefTH z5l^HT$WbpPpUj<@?!6#yM269yQF+F}Ulb?qHgWnj>EBp@UbcX$MO>rbJQHA=s|&oL zdz;Yb9e?;TtMDs!nlJ8~gJ^R|c#H>aWb{4gRZfszCKj}{N^XnFK%&S~O?>hSR$a%6 z?mTM!s299kmmVmrrCK3^4vLpVyf2)f&&d)EbQ?BRy`&QpIz47wI;A=w@Xyl1;Wg1B z$F)E*K;mYa8l=#xzA%oar4e16mCXq9i=P%rSTc-Nf^HIHp52Q=c2I&3V6nyHamjRV z8mU(}j=;&MGOM~x(djIxI+DQt#G183NOYTG=`@PszypfV=UnEsYYd~!0NS$=m=A=Po6fV_oB zC$rnoTv0OfrrxM1+Djus0Agjt{q&uRby?UoPt$-J`34uMZlw@KJQQKsAtosfL$}O#x*iP*@7=pc zYcAD74wh~`Pb04^?A^nsEEXea{eF>QiZyxGq}OBf6xOXq@*@kXCiGd-`5IP`Moxew z0o+s0(+EOe$mw}?QhLpl#cbAZ7L(=DA3Fml7xnyl#jo>Cj-jeHvgcmYdpi!goB2mb zs;2#oma!ro)uVH##4ppRDOg);w1};|~Z3T0U zE>*D$9zNLp%X9Iqra|NRH+#oHNL-Gj$NV#|(z9B`F0b%e`$kH9(mWOztBHP17@9|} zxh@MdA5Yos)p>4BOOwQMGvl81J1sn@=f^&N>%Cc0;|^pE>9p#Rh!GAInEtJLVPs}` zw~fu6J0x<9Zc^3DLDQadeJM^gid~qG@_JQ6b#o^u$PjKApd3%=lZ`y^O%fPa&UDdl z>3v4ZXIl&~9BWM{b9mpo$i3{JqU!2rR=54ORcev`ZrJ?ngD_}p2sNa^*Dx+9g|+6= z0|FwuGfm7p>dZ^XntEh0N7Xsx;&e9mSPjU;?9r^4S^?~i;edSwm1}oY3M)i#_YM?oh)~wLy{6hkO+X#p<==h*vpL z<8U=L@8w6lR^4e55^`b3AAs(ODp08d2%q}OC`5WM{IJKMf*vn!C6J;Sv+4pwid?$O&{^J#T(%x2UqvX1`n0b^>W zV<-jbD$3;;VVdX{Ft}+>>i~@hu#Zb$Bx9zjLBGJx&yUjQv7V*} zj(3gsocW1}Ie88k--a)qo0_fq?DSa3wL2?B-EU#$XtjZc+gu!d*9GcK6bdDS0`b~< zFOTceuvQ)Qj>Y%p{_(m~A?~){oo@{{3M5=StXF9IsjkZI=ac5ru`cxI{XdJaV;dlu zMS1;v2bn}A@vC?5PA_#c%L^aSy&Ox=-m#<&T&3c>mBQM*dHK3G4xC6W~<2O zcc@~L!#I%K>Pt+dVQ1iLKB3FhePOco#5M+Qqln#mPUr>(lvxglC}CIsZpUfN&t``i@|?^*(?%m-y1FMvKJM^H$7FMIG3xRB zLT3iU=8T&|pTT#4M&p*k0tM8TR0hPb`d+gh*%2$9l!1@-#_ko% zk_W`62dwBluD|khsGYw@-B_mq?!`0`T8SXRNo1FI@r({3J1CR0eA50QslA`vYlbt> z%7lh-Q16BRMqz&CdLFr?Va5C9)8j2T2j(*fp73wx{!enS^O?upmVE5ghx&&?2LT<; z29B!RN^CXmHOZ)h`cFM%{-8gC6hw|!Zcv{Z5w9LddoiG+jFUA6O(nR(m)H)K^Pja4 zM(cHHg~J!0$+FsO;4!NUNA|xLc1=mV?XYt8T5m_D`P|NGPQf++{h-_TTsttgbx*liGt=jeHEev$%X9xI^d;fU@yj#|A$9^I3?%kJC zz8J@`GPTP-JnF`QnYFzD#w!t3bz*v876GUAp_CfgIh4-JkIIlyLxvd-3ZgTYw(>Pm(a^^$U^(O7{`sGb4IkPri{@+kX^*bUaf025nH89ly> zn+J7TusQQL?DeUADdc1yfP`gs$k$%8%p;_BmC?#ewhmJr9bF6YFyY3+gGN$5`y6(F z9bw!;u!)aE#)l*VF|LY$TM@Wh#?k7#SwabZ;h1YTaINK>z zaNhdSd|x7v;*7cH-6hGzlwFv}l)jI6sPCHRT=9Sc# z)5Qs&NnN;tihK;MYCVAbEmo6k0cpGorRvR&Yy-8+W&C@_HPcRWyg~z~>1OC}Jf1`# zr1xTfSJsqSI9s-IlMgrnp1_~L2R%Mo;2ke?%hz3O-k$w|%#yA7jT>$^1TPW1NVn9O z{)i{~QXuz)5<=5pbX>n#O3(^8?AMArEho(@iHMht-vOpOX|hZ70tK5dhiy7Gba1kn zof=YvDyPf}1)T2U9q#vXtQTaXzQ+~Ekc{Ss{8_DQ_|&y}}K)~@7@ zd}V&km-&f_fzmynE4Pf*1Rdky>kG8dR9n9B+bHvt{*^slX9_{rPe6b;kzMPF6y)3V z&lwu`VxzfG!0j&OoC{^^I|~qXTpcg~Rc3IE0<;A2i5W;oudk;Op1)dcy`|KZWb7{= z*9_5IHa9P)=Df45J$^QbQQaPh9)OoGE;-6ZX&qOAjgtlr8%~hFTppvUFC1MOz7R*9 z%XPl+v)9^mLSG_(eXQEBEwXL7I=-k&HZ*)zzRSB!G`UWCAkw)|Ez&kKC1hj{T!)k< zcDmTfgeUK0;EA5T2kK=|p3t>4P6P~kd^Xj`-OLa>9Fla2R*YVC^L9ADUak`+8i;c3 zNNHH!YS?MkLYlJwb0jjfIf{@uj@t9R+z%gIyk4g0~p)4wsCMcOnL9lyokc>Nsvvhq~Imuw# z*KM1_C$K+_n{n!WJ!UsY(6Cpc?26yW;u%gAfAO`EN7mP-`*|whr&$sQ3HohuqLjk3 z;`OgPX+9}3{jg(!_$Z-~7{Sw5^@l&n?9hGYUt&vo_VOSPq7h_DAnlyh1DOs49dhUb zX0vG%&2*7)=p?WI%ukZXV`^-2=(N{$Q6|!yLJPt`Rx^-JZWXz*)<+s$Ra{wV>sUDS zOes%AZGC10KRK4;;sBf@N!}KZM@AFxAgfsc1kXK*qicaF~c`GCNUj`JC>C+2-nO zE=LzlDovtX=F5?}XZmsnJN*SV2P>w5sK<&6ZhOA*d6Rg*XY((YrtDe|4rRF9UgHeV zhS?P7jsD_PV?qmVR6OvQId`Bu5Hym^Am#35j`$r^aHXaJOv>4)B_Xj znr4rCZ@$n-w^Qd>luBQ8dK0V;3Jx4U={D3E7+@~GG+cSnH@yhvI?JC#oxNyo9@(s_ zx9fKEd`^sBbSbV-*wmdft_jRNc|bXxE=3eIazf9^Z1RUx(TtxZFr8djtjP;ClRkqm zVVCYRTr?(g3z)MR^A3*UZhn6Dqqh-cITxfJjM$u51{v27CHKv;wXunwrJP7Fup9E> z9~b4k`B=->6!?O>Q=p$q0X}_bqp^7X=fIB~4Ce1^PQP^OoHKWy_65E5i3A5jIY1IQ zn}YSFy!N`hH3*oMv?ti-eECtC?Detr>EL7%XjGXm?2%M7?F3>egGRLQ4Qg<^L^>=f z0{RQz2It{erQT?*%4JU<<{>Bdj$m^~KWo##WA?QC)kN&TgU<8-lf(05UcbaVrSzu~ z6Fo(hQJWp`5V55A0S0=NV=6cBd|Md7hfw%wD^&Snrw`ZUd%V_+Y_9^XF?e%ohV6C! zPA>)MyoN2(?fhcnn%xS@X_76^a$f8bpZG&<5#`c{7KZpZTp&?I8{0ot_W7YKZhYCA z-}ZfAaL~$C2mISAWe{TukI^3|kk$+4hKjnGR{?{A*U5YT+_0Z4FYjWe5b`)bA_F*% z^!F`~d`Dx?u{BTFgXWK{#0~=12S?ax#+w*L5(i`K9~SKhJcUg3@L!N4NVpKI`ns&6 z990xfD}r`HGRK!1xJdgDj3*-_gPrkBB>O?2zz%{ROx(0-Mf`~I$RbsgbTal-0J(&?ertRL56+yILkD`Kypw{CRsVr;x5+`jo2pN*zgm39zc zpxZua(X*4r2kspo6){!BANOloAkAdKIt1TyHr*?bZaZOcc33Jcsgn9z30YMQ&gOMf6q0 zr)Sq!rLifUi-0lgj?a4{^o&ZAQWjFIcr2sXAfO&5K^fC{AzZTKsLzi`o+1d3f4g|4 zpQSpe6*GS?%{wv}4Pd%BFWD4fOjBGrdOKQYr%y?Q6K8i&^^yZ74wHnJs*PyC?YRB= zIePTFU+iT0m)5tqC~`%i?D{vk3HxDa3b^~@aZjfKQCW|mq#xmwVju5dQkBs>5zo|% z$!gc7z7wqfAjbsLZmKNzz8pU#7;QA0bh#0wF)dip5@AJ|T|Ed=Ne~>x$9#w|7 z2BuRq@QH#u^(R3Uo!X-_w&oQAt3{6K9)c=H9TjDd&6Hmg(U*?5yPKM;23R0Tj!S({ zwh7ZdR!_OQ^`~p-C%BXqaF#f*jq{|}w+Zy0>ZVrJzKRMbXs9<93x_3ggW;C;h?BIb zQbfu&IoPmhG2seU-)667rj@i9`fh1rpPrtS(>3S%5^(b4R=-IGk}U_jWuw>#nODPS zt4bE@olAQIs4hgpU6Fl9TYI%iz3`RC{D-(1rEL6jhOpI%tEpm~!H|-KzKikL;&OWO z&Mad|9D})VzaZ$5BE}7GPxWmP6W`kPwfG}Ez~lwm_^MGjI7g#P-KN@8<%?Ff09g`A zuZ;guoE?9+z6yJBKNnBzlfd`C?CH`%b3x`hM?mVzUxptk)lPZ){F2PZ=^OhQ$HO zh+l95%wr?q3z+IZPrLcm&2)eV10U;D?gTTyY1>Y3+yC{||Nim+r;GEB=}AF>uEPBu z*zaf0mJpx7?Egwbxa6H+E0=;jk{i(g{JduTvX|yY9i)<`ru$CrDfQA~mRiQ58PsOV zvy*%5w|_)&;|%`J@_qkMq*nm3d{rqA8fmk@Y^sZP!hV@5MECB>OO_|EiG()i<>f%~!`7giTzUSWb^Mew{uDd%0K{ zErHhfQt^lt#=K-Ysn%=_HkulOl4>^1#p@S5B#vda7lSzp58}4rpXv zvuyI&t&-c)zNH^{R=7KRqIKG}$b9Ln2^2w8PsQfe>iC(E_p6FLZjLcmsT)m)u6V1V zPn4^=3~|WXcf4QZU&NNw6ST+KqRO{(V&51B9z^*Dz8By1=uWVjPb1&|xnR=m`l8cf2@fJh0?J=-i6QX)=yu9CH_KFBG+AX`$GdDfAl4 zi8@jO9Jf1EhYuJE?302_w{5|vU-t9vF`sUbC8WBf^SD)OYRUn`_rtJ|WS?dAI2mSg zZy580zGRAU5^KsbA>P2vsRyist_rZSi3Hv%|F#_gql?Er^FvIwmg~xy{7D}DQAT&) zvF?aD8~-asZ!_+f&R)e|rNzF98EEH?+~xmaHX4~Dh|Lp@8>9OFC4|EdaxnTYXrBh> z$uG78cV$9IK<{;vT^Ll(Vf7Dr!_Ti#Bn?tst3Ni+e$ZCaEqsjzinVSw`oxM@5>>tK zc1spyd176?_C*}FR+RF8J;eJ)(*3c)w+AN>{0D>xfG*$IPFd_>rt}m?dF*!i!FYEZsZ%L6ZxF~&eYt+*wRv7@SB*)^qK8b5NmOAcxO`qR5P{QD`MILeLCu& zJy##qxtPJJk^7I6M5dnRbtC0p5qPT#0OMGkIM?Ib%}aa0`Z$<@P2ZR9Uc2AsDI=pPuT+ptoRdbas_v$!yJ5c<5 z!>(|ihM0qPXw2tqU*>i=0rUV0n$Y$(-ogv-6J6ldRjZT@xboa~WKUKeVxNpn23wIU zs#L;^XUvF64`6!2*@{`iCE4D>!kV06YHpg_xdRAcj_AkM##)6j`Ob_$WanFcwv@XD3!Z|AbfSbbr|by|L6n8=j;{XU z;+)%GrNn#sM&#Rbd4K}5JcZM5MtndDAfuN}==m&52I?W_rdy!dPY3*dB*)!5{}Cl| z%XIOV$BNW32Y+A<5&|O z%rSh3lKw`-BHvURfh$vgsK0(enPW4$n#3ZVH}JYpPovOiI*0u9G;9POL$e&oCsIBuBs? zC#Ec)*#4s=cYIn((KV7Rq?DPgLZVHTlE%BfJF1&UQ$ zoU6MSB7(?=lCw6Q{y4m3Q4jUV{df{Lp~uqw4J^Ra?dg)(&D1IHhf1+1IBlWylki<_ zk{T+{TzHh=S)_O$MO!j#%*+(qj8^l#UY1%D+;O+*Wy|4cj_(Mhne~YtYXrLw1&)wz z#TGwrL07?ZlR_EHh3g@QzZ(B1*z@=BdnS@>fKEs#5`H%QGrh?A!K3 zX<+iCI25BGIis2w$6Eaj4@DZQ$=~$05aug=)+itx&aAHvBqwaoB649C8(h(^Eq~m1 zR71C{HXE(jlm7X2n#DrI70(m#%M?Lwrr;?*ul4!PIHkn2dIl1nf6#Q~0R`?u&|GvQ zOVd@<;bFM^y}?pp1*dD-^F7&h9bpDNj{G!6hf(?Z>#tI8ef*LSf2)qPIpt>K#ZBnb zcDMQ1>2hrsal{zbA0l_9J|Wz6)v-c39Kg>JRrAN7l+mY)j(Ig%|GyTZPoW zAZGmw%2YZxR+IuA@%>wn*88iCy~Yg+NhUAT0%8u4p<#a(GW3?5&!V|)?TIcC&quDj zrP1h~UWwH5k~=yxl<3Qhy`8Ba0Y(R2bxB6Bn7o0!`}h zXD+EJ9rLwZ2Pfs=+9`THj(0?dyAS@Oey|dDXROjDc6QO8@}l=eS%&*qci6X)Rp0er zvIN{Fpu^hB^%TY2w3?(S0r_*^RQHA9k?v0U0LKI*d3xhc@tk6duIz?qqx+laoW_kA z#W=zGkE89Y^3x7%Y1j7^QWMAZS6<&9?!HohokW2ZS9p64Y)HM6$07v{354gaE{{+` z6O02yy1fM#Y5>uVrAC#d9d<3sGmU24SICxOq?g$C9?K~ov$R|P-kC#oE+0J$@g7Qb zmQjz5Z@xqW*Jl;Na7A7|v1`86C*`MRk|yPqnJW8um^7X9CP)SIx!<6!6vCyUZLR~% z-J)wS<^0e35-cY#GB=Q4F3Bh^-UJcKKxplW;Cy1@e@O;S^aS*zZ_<8JV(=U-l7v;D zF{s=|Ttg_fci0B+=oGk?Td&;4=JC+~)cD|EW9G)TDt>T_w9Wt7OG}wev_yS&#^EW! z2wM%q=UO6Rf7G!_7 z0$$s68YU~>A|@|%)o9_EjJZ0U(C&Y0bSeTHXBD=)XZo*7$^j~wg0IY+vmjBpN~k`~ zH==w+u-87D$XfQo<%@gUcVIUa1Fwfna%zw<=g7o((GrC5RN!HBAJBp_O@1_>s9I(Ndjo-xRv$Gd&# zJ{2}%+`x#@ub`aU+!WWB@f?T_yy!<&!`v?m!|tn`nCHetC6sQbd5?G-A1AxW=KsP| zOfsQznAWS`eQ49iC@()wzp7y1M4vYQlo6o3c6;7+-HPY30x-+Eh1I2h+u}FCg9k^@ z5vf;i#S>rV1#-Ks(CP6InIL_1HvAfR>=NCN3+3hGxwZ3@6cxVN)7YD?rk&&#vB!GO z(Ld2j4}3$)&BsJm@w|VgE^MxMg*;d1vw}t*L#`})f~$ce4$n3Nufyj*KKVAMTf!mrvH6}`!W-rxeCB!1tu`pn{UH*CDiKyI4 zqcUjyfFsAwQLfR-J`m;jmNFpKd)ghz1rCbF$@LPW`e-G{>Y(!A)|!g}j+NrBVRO{& z9NVdZ;9}(!!5XCcluf9VbKy(XHe3iwf6W;P@Noo;7V=sXn%MYfj5{tMIvjS`DqXJP zG1z88)Aj7FCuA#MAwX?yYqDMPeIy_kf4u3E#)|IZs@Z7@9 zxP{}$?rgqu$;%PC63NstZwgdt!o)3Ku9al~p<2@Qi|fS$4p% zoUt!QzWYquh`u`=i1I7dxNeNzIyhS;@?q`ES=}Sn=K&0VMg3qj5B(E={i;}Pn*?kg zii5HBur7 z@L8OB=n>`jSndJUdggK7QQ8A%B2|g^Oo~!OS`V3t*wyEMx13zCE}gyzgrKLh6qxsO zXd@X$H!=gJv#C@^z?^_&V_@ENs0=r)R4&GRs~yaLtcLR zg>Payvp%rFMfCC6=J`G`Xh41aCz;l~D?69%p~Cz zdSb0!o*hMrMog=JXE=CH#K~oX*wLHZfd#EDvZ4;aEsA0WqsbB)Kb|FSaDA>%_cC>Z z;=mPRm@!k7`6Mz6ak!EH-1Z2%A;k2=!MJ}<${W7H8t@bUY`QSJbbcp+#iG7#e2US> z>mW-^7PlZykR{Re9;)pfpXr%ED*8L){`L9s-~aq70Vuh2*t5k?w>}>m29cSeI=5f7 z!a%(^Rz_gC_2+6uyB9AQsqxE`v%lhQ7F41i%im`Sw;s2=`|Hua^5v@toMp(*iDCZ| zdlH#k;d!+>l!T&Z_GVFb8AQgt>F)y^@|1PXuKfy8S#DkFddE-xMBFM~Dq!Wr5tzQi zzinG8WvXW~`Fj+6g>JAV#J^prjF5cmAq46H=zY{z9IfU9T);PF!A*VscLZgrH@@cT z9cSNLOm?Nlw^YH3sZ(f$o5#FcQ6ikippEGV{bm!^$u4$Nd=)i6PH-v*Yig%^W9)sn^%|+1 zZf5AP1{Sy#yx8{vZ|y&;YZkQ5(`x>Q-Ff%v#+x?#o;Simk0o=aF`KAjRTx|K9LF@* z^2V`7TgoPQ3F|IHyy9096kWSDW^sEPZVh|AZ-Eji?f)AqQr%*(Kk$*=C4DNkyJr-L}R;=>qYBo{*;8d3^XFDc zd8LLmhkmIHrs+>tOv;~{h~PFO<^85#`Br)}0dR(X_(vXxy;@9y*>iz%^rR%8_av=^j56@pKRwXJ#UB~SkAtM}sDH#ARE@++FZ`*S;>zkTmV0LqY#mAZcG_WpO@-~4X4E)IqW?7uVq z7us$*2!4ITr-AN*>i_Q3U-Z0v>=FgA#53U!X#W-N|C-1Drue^I{GXuyPZ$3S5^g^N taPx4bkEx04MgI-1k1~VW_K>@;d2l5XCv48-C{{%>JF*7i92Kc%2a!GLkxxAhp zEx}#&XX-bim^Dz-HBn{IhmJ0j&y)eh%1o(?-Bq;{{MmC!sY*qmj5rV z{_o?4Rg&{t>a>_GxmDS9tXCS7x7|xL>|AbDG$E4-U^) z4zqNfFE}arOlw{6RV!iYP5T0VqpQ!oiY@(JSl3r9Z(Q-@td!RmHZhK}J(Uh`#V^KL zowWTBa-sEs)`7}he_2ao=Zjb{*SfA@JD^Zl#9$J~@WL~M$%6F&pN!N@j)tO`Z){5* zEBA9Tnybk)`W#K=op2@T;Mk{;I)Z+!p)3$!}SoVn{qHN{v zhKJTp#!cqmRx?#!nSbi2`8~H>0aL#-S%t;N-pc%EcofezDR1r{jo41vZNGH)GHxn( zX#U`qXDKkO7(8A5T-G@yG+~Jh1)#J7I5HYT(vJfp<&brLY+r zlsEbw?QZdF4bAE`E_e2xIj3RPG{=80AH12}F{5dNSN9H+-LPhQ|yR zbb93(9ueI3U~%QCniKmv4W5X*<}9&Goqjgtqh-tc`28wZI`W>VoB@UmzF-8UdI4}S zzP \ No newline at end of file diff --git a/public/mobile-screenshot.png b/public/mobile-screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..2fe03eaf995f050acaa57e746243cb7106b1862c GIT binary patch literal 180460 zcmb@tWmILk(g2EU<1P&ccX!vut#Nm!ac}ehjW+I$ySux)d*klz4v(3+-@P;6UEllh z*4u0Clk6mwN=Yh}R8EM3oHzm;E*uC52!f=9s3HgmxE%-x;mHSWu@$wRYEb+q2hm0kb!*{goyY zkj#ebylH%8G+%AWbXxM?8Eo`a$zP5jU<5%Se}XJ|0=0)jLgAn%p~ih0Tsg8hYON5Z z%6#tL)n-sbcfdfRD1&DL9E9k5p+P%SAQUwSKt!o_#tQZ%3Wy zsrlV%Po7(bjmQF^zNO>)Bg`O^2Z6jadQqUx2aH-9q$r_e$j?G2u_-(nFqhiF)|p7D zvE{R71+SU0mmFiYLbChhxoq^6vs8mmPE*;!KP|Y~PNOtD~?@#w%^) zt0{u0sHqV|&EQR+Qj7{G^T-bN+L7siibkPG%z2j7BmcloB?AulCF&SBUoo*(>m&k(dq zh7|Tr?a(OiusSoz`#r7c3b;~*mTagiD$xEb5eF-~7~@W~^E`}j&(ArGH1z@WbF`=S zgCM=|SHVnb*Hqe=-hpB_ZTVmOggLlj%aV@SPp|eqU*#%eIQ%)~(g}GO*#(g3<>L8u zNyoxMmHI*w%`Qc9lrJ|tgg7_+Ksv$TeouEAM?vD=mENX?-^JP1ND`@(SEuz-`G zK7S{@z=ntG%s>wD^|VX%(W`*j5qUdCRvij~=9-%V&Aq>;QmO7z3U(C29t19g@{_vg6RKKrZgP*ttf+t^ii!m{hgz;}kej4MIk`3L0*D&B@cl&5y{4fU&``U@bQ}VE=96|WYe+tS-~q7 zF-Z-<1A$(F9PjD!+8iy9+PxbnD}}QPzFTL0*hIX2{+dcjX@cDsX~^P~8<-Y&oEcg@ zFEB5TVYQ^+*5uD8vcLbP;6=n6gmBx7X#id6_*?P>Y(8KP9Mc8gs#CKvM~b&`EB&Ud z5x8jhv^5mSEwV6r&r?#GyHeC&G;9GTR!>hHS;eODS{)Q9ed1aGk^TKsJ5J7;>5+qfC zR$=f;1;3mZc_YOiF@xVr|I;WCVRQhe5tLyA8cc{X7{VR^D-$qf*6mCWuGA&Nh=dMA zt;8<{-PK3?4OiT0Q%N}MPi}{r3Ypl6VF$kQqoe@56=Zee^TSU73~UzBCs9HsAzBoV zUK|4wehC0-L@z*6f;t8$feguvmK+%epow-chF1(f5kVxOh=!NIbAWaab|S8bmZuCX z&fzXZvHTGsx=0C)AhJCPYYxQ?NhgSvDLutpi@N$_K8s>X`T(K!vlsAAA4I7qDT!*& zw~C1#Glb0OFzHiDIEGQ4I+ImQkD2bLG9Nz&r zFlz|YlP1Qv#zaO}#AHMZD6vu{pvy~d?@S=g)S3Go)~$aQvo z(wvp%7a?78g1DAcNq$;3U#8cjzB#Am1#1AVBP%uQ5o@_+Yp&8kf)k<_ahtEMlz?D| z%=vV#xu%5!+vBeqHX2qWtF`HqDMRz{>CoBXInC@krDMN&N9&mSc$dt21rOkz>Z#IF zBo1~@YL^KN_BGBjwi)(kZqd(HpVQ?M)q5(D@%ITju95FXV4BYj!&mrvhF1_@(2qv$~uHQbl=-S zZS>8Mtr_R^bGmT+%Qv}u+5+JNv5?jUUN}T%C&wB4?E*JddoX(lNQ`pyNs6YpbCkq% z`elp+wrRKL`UigU$YPW8lN-j)kq^ke=^s{emg1}89J7`z&rY)TDjPKS)z012B-d%Q zYGf@E)I9GgJJ!25KU!X!UfaNmcQ*Gwr6Y{>FPMhP=8ZXPWz#LQFT41kV(`q4&(Y76cb`@BS)Q9R)UWHWv->f2 z8wD7P?gnci9wFifc?RJI1x3gV*bN8|d>=?8p%WvI)MmO`8MKuvm*bLKPCbj5Ccxk> zwo~3NTo`v52iu3+KhCkp@fVxGS!H~R4{Hk>G|3sURtr2lA7lAARA>S(RHSfL0+wSg0{Au0H@gw#zQ#R9bKkps; z^`3|ArOmy;WA4+pJBxd^+udi?C;lszd$cF(dyoFAU1NI}d)+6V$B`GL$BzB)4rcc9 z5c;59pnafaz$M@%a2JT=H|odiXX)4Muj6k9kpV*#5b&cErm2r*3)XF}^-SS@QX{LN zXST<%XSj#p$MTPnZoGkPBawk}Tn~nBW?|H?gs{Z!(Iv#^;u_+zA>634KO;iRgS~NC zs7*~ro7BZla(|~)oo~HtC-kj`H-xD5a!^d7DWVpmtx-Ucmdku26pdetWP70_eHGQh z)$As16A`0p(W@!3Ni`ISsVToa)U)Y^5>nH@@wzYVuotz}N-XjBIS&7#TCHYWbm1b- z0N4)B00o}t;PCq7LxUdqA2A*Y^T}oS7-g+~8EcL>wH$^O2++V#KbS!Ai!kQ6=O2!` zvk;DNjV>|cC8x2sxJNvuLOOEqK~0qX5>HFyJ6{kk=#KwkyH7E0tF2$Ff95wJ0Qs)0 zl>3#Grnzp?YBT@K1My|{d|wV$h1N@%y1HjoZ&7aT&IoE(Oqf9AQ`5=*THc|wR$>#~ za${0DpQdUbB46M?&<55d6&7{bsK~o6nY%heCWJ-n|ynUAcP`wX}ooMEglwCX)|UI^`; z*LR#-xLOH3F>V-)yxx%>OyB>pk&b#S=R${{#-&a1QwcYmTm-Yw$x1i$4 zlgNF3GVkwq?nhYDiPaVLdUzc_yjm7gmX~REM;^R7z_1l;tfxWU+Q30HQ9(X6+U7>6 zogzJd`g&^djQk+4UKe!2!U1BrDd6RV_0rM=*|}y7qAuk19S-CxE65fv2>16JeZ1cz zx2HVuVgVlhV^exF4l|t{OmpcsL5)G_K*c%8Pkit2oCALEU}GUWADfF%6Lm>bSy>S3 zk30+r1Sl>Daq#|5nBfn06RS+JtHwc8~^~|buc#NRumQc7x>2) zAF;WUlN~n$gR846y(?#79j02cmyJe~r_`&Eh|pY#jeZ)(3$Mf7CEA(K9mqyYCNB z-aksY6)fCLzG;YBSby;B0|!47D;Fd0p8)?=^&gaf16BVIC@1GXApchLzado|O&mmQ ztv_%&@&89&|3drs%6|d!GW`v-919fCz#}iV7*afu86<`)aGq@z=C9oY+WApb8&+22+Ft zJ*0$Cc)>s^@>8S>E)1spjDd`j=kKcwdYA^_BP9Yx34%cgOUSb?a=$;GrLZ{epMFao zOISQ{HP~-+UH5A6yqDYaJWutIBQ2Ip3I;&|fQkCTAcGPMLj3gs*hUGC>NI)5uk!zA z#UHJLKw$B)!2SzH-xq*vVPO$sYGQ&Abyl77Ux2`_Fc3C7f7dfEhkqmb7gi{2u;}^u zd2>=!9Q{>O*O31jkv|eBYGW72K0ed`#tV)P`bz2z&ZYp!F39*{a+NZX5nX|4cMUlNA!P6gz*6x0L1fj z97p-D8bOo|f<{no`xEy6Es6hE8KM6F2Q!5Y5iJA`3A>V+Y>626caCSaz^2NA6A>8oJm#oU+VoAjdmy?Y>fQ+te`nntw5e?;JPD;T{Z+g zYDTm&OROcPQam1K(uV@2HW|wQLxG-gE-g4ROf}Ey2}|J4J@R*EBnW4!LsKq< zAr^A0Iy;;RmBz@tA7`X7*H(Cojc#l@K@!%7oRhBmb^jsF8)7io5!GN?4e~M?Rq5m5 zIaF)&D08JS636_okG!f%kAa*V+ zQ6dMmDKNeyx6UBEmYo9xUqoY^v!FwfhJSWz`Ul}u6wakT){c3`T+2GrF_)%ibc4iySauqHE5n%L=RLbyS)NUTgH zK`w*nTK6eqw&S@S-Lpv@F0OW$oued`(A@UtP2RWQWE>y}rG{U^CM`8xQxhr`Rdha) ziegh=zGC}`=nx) znn`&(hN0KiO0>r`^Ri8hL^wk|m#pYgx5*&~bOu*9JdJ#B3Gx*XC=|Lao-SQ#A}8A# zTU?wj)of;3wxKhDKA~{Oi%1Bb88nerCj2C@+(vLSrWBo!kYKJl-)x4r#BouD@ptY6 zfxf;o?NnS=*5(QMP1igA1L@I^4Da&8D$A<*m+*#jv!h5a0lY#czw3_BhHyMSkB$Gv7I>d0Vwgaj9AHA%-~K{fuBZ{6Z%Lf43`w_sB3eX2q;lHu3q90@2B?0<_X^ z_knTc+C)Ea2>=YaVqqcoazmyK$b3I70K`#ALdSfD4@8Tp>_=}6d!Y_EZ6j*AcJE$f zuEyakCAC+{-?jH)wOzs9>o_#{G}Jt-88iMt)G3N@VR^pk_)gVjPvmZVifv*lN51sf zFE)EAQ$Nq;`5UfXYd8F&SBEYyZ&PBhs-dt6_5`p|>MDBFT>Ly-C)<_E)B5;nw8-d_ zBj)`bQZ#X6uVHhv;rdFg1|xAjw$Sd7CJE}_7JQOM%DK{t-v&voW(_Kv>P{N?U>H$Oddj0 z*~wPfRIRNKQ_*?&GKQmBb9=xde*p5S#%HshCB2hODGNEYQB;^Hyd)T#pv($4&-u^+ zp|Mdh`xe*DUe-Uj|HKY$W7v@S1v=VdfwLh%>J~`|^!l2tq)@OrG>ojIbymkH$Eb1< zW!De)XMf+jik<6&(BBQ}7(2&BB|GW@V~joH9Zu*dEU75km%d<(jT<+$9;`6q!=Lvi zW2H!WhdJ`3#S7J*$%E8n4&mXbUwQU>q2|(}1Z&I(+IrHqwn*Ni)q+pe)ntZP9GVPb_R6e_OMYG7D z3HrkOBR-!|I6VRfx_}@O+R`@Zvo;O>=svD7JJyUcyPjG^$^JrORvSy*aiam*2*0DA zl07e9Mws8n8uCo05>a)kq^^GbTFsx;4j(U!{v6W^UsqPMjgKuUTn1+=ig4syt0Ac) zXJ53VqB1;*Fd%tp(;~GNz)j}vF11(dJ7({o#$yxkPe-UZ()V7GFuqi~U3=~Q`Ly~d z87r^3N^*=`1hO^3b82j4?+_pg(%Ye8@+#pCoF!bo`CwXsOdi@4+_>QtugR zOw{RqIIAc3D!3>2f<{YP)k3J>qe24@|AF>z=7bpo7?|v6+>fy!>2x-rxFHAE1vPG!fl5GL#?QKNWQtNJo?F$dDR$P- zfPPk&VvID!=Lp$+ImKOf_gNp|9}5-{1R#+MML~XJ^6a!@jdCi8Adxs8+ZVG^KE(`oF9_h1>0#&J|>D>ansPu5b+SU-7U^ZuD7v9qru9F(){7UAj* zo?#?rnJ}t)0<*A*)XhGM7$9lTdwYy)zT>B5ZL{2yhL3h`D${~xpNmizM1i-U@#BYL z)wL)U{}JQRXO$A1UtxGzmrm2Pw*T-OoIpWiFNu#D^^>`4J&usn2JsmIh&xZ8I!y(U8xs;RH6C`tt~TjhrQZ_6 zaz!f~(G9?xNbtjXoR#yf?k9h}PY7-mW7xXJiEi11-NAK%Sh=QB#;>bk<+5SmPVu!^ z$yTEOO|HR$4amWkvxN)ZURA7ZTwem&+4|cebE?Y+f38}_A(gej6zU@h-~;U0p3g{j z3kY)B>6P;r%IwAk#04}LP3qCmehVKh$HlV zvl8?5X$9ZHDCEvA5LKx9xe+W`D>;KA=U(ZYEfz86qVKnpIjS{Kti+WxCu}`1Op5=z2bk5-n zgYnT9HOXUW$J}f##*~0^c&1hTHFG^F1u7Elga-B!nnDJ~#7}RKf+a#@_EwgSElwI@ zJ9fYhS~F7(MOCW2ch_9>)3z`<7hU8jFKg~Tvwyg-GOW^oscG8Cb%&OnwO2iyxyhX! z(UwC|ww8@(7$;vrJPpEOQkBu#Bg~>DaKyN+p8Leqqb*Scb!{LKVSAzt;4J>}>v7|H?=@ZhP6Mg~H_U=7KUV z8ZBy8MUSChY(iP;8hpLuwE%K_wH)!0V6@0YKRS*~syvYZ!oSUn0}TjdtcPftis-Bv zfhgQtURbViMft%Ws#uZ7>|l}*7ntPG-xa|)4mQ5~cY?l~rbU%jJA`0jNX`YL#PEF2HAX6l zFCB)n@U#x4{eDvArZODTnP zMl$Wpn|Df__hVjMeLeRhZ4}x6|ka=0IGqn&SZoA0o(`zOHe!SBaFhudZ%^Qo(vRLGeR%@hOiUHc>Ku877Z zLy4Y^^*9a3s<6}qrzG(gcN-)vQngncD$p?Y^61F&4xOFL0wq=3z%-z)!u`eW&ftUN zM6_QSM|3GFnZ3*hkDc&9YsAkjArBMIE!$|t|60vogM5d4$pyR}dUUD}&Y<%$^QbWK z8p~3D&$KyTd6klI2I+@lJ^z|nsLb8RnWZO^NyUgU=*|aSW6{!U8O{X}(B}={ zF9kZ4saFZ->$s%Nwm(=7w?9H4>glu9#toO%$NZX+Pe|R|rOG%wm4T^}coU%XCitxX$Zv9^zp*%Mr>0RaSA{k-bjw8QIj$<$}u)Gla`bWc^*-WH6#Da zVODoVzAzDgX%RS==a4#^VK~6V%lXvCp*nb)FA0WYF}a@f-OK>P-hN+7GuvxA^6cm2 z&gq&k>@ANKYagUmq$(&DB(0j)FuJ*JME~CL&(5p}yLZK1XS0`8ul~K(y~3Wn2N-7s zb?wQDb~(s?z? z+n+2o8tn|GpH^I!t#`ZO8NSWrP4GXT6 zWKiPDGoniUF0f?B!}Z*|vLY{LP7=zfW+`bJQroaGV++Z0sbCZhM(04~Q9Vlc@i0G0 z_d}PF^kdjV#wP2MDNTv?WfnDa@LRQ?I5gqTBqp*wxQ`BZ-w+_{WkOY;WJzg~2fH+i z`SXXRy^C$jrCi@al?m?ohBPX)Mc{7MM>ap^MUrs}c4x=lY4X+h$7&t{XS^$kw#pJa z6a8yGnvhHwVYpQ+6vg#!Rn0_Vh#viUtw=``Ov%QEwNKCh%gO<`k|>R8B0T#os?*P|>Efra`{^E< z^W4s?VE1`vW*15x5NGpRw(&e?jXiCdjHSNI^erdE6zOi+pKzFaE6BIUTdEP6%V$oI z|5)TQ2~mP2O_^QKw3BaxN=#lg2yZQH1-}#@vByn2jw=8O(qT!iI!4}T^Nu_#7~weF zR%O|l^|;S8b?yS@kiCm*o;R;n+s2EEqK~${0gow>Y6Ym_S8r(Y!`06O@k{Zya*|s+ zxD>Aqrxt(k{McrFey{1pemigP=M1Usw>r_Q=kq?heq>JHkRf2x>~v5@{13Hvk?L8p zZ}lhzbwWJhW}i2w>y(+l|BTBhy(D1AA=CJh1n`ut3$pCtdCpVY2_LD5wodHftiIkk znl+rFYlv!glvgn$H)$(&ffRb)@JHGyZ#hFnhEBrt9nF(^0K-5>=VYk~L8BPXm5en$ zn9PzSw<=0E()|wO+p6O@#s+q+C6I@@q_q1u@tbQD?0((H=W#01+gRgxmPrT9bzZ}4 zsMca;3tQisBpjDb%KPm)Ls~~i=S7!1-HG-5^Xf=%Ri*qNstjxw>=b?1IPYL!@qVXR zJc(s^%3gHCi|7nb0hsKkmqnZ@*U#J>5SGVm%FDaF;cY=aUywfRhLwC?s$E%p?FFZ_ zfT3_``L5cuo1o~hg+%7694~rRZ8ENG^(xLaU&Z)`M zu0x>m$YjQ=_7yvBK2dk(#$iSr3dA@e_g#5wg~$5Uxks;Ti9ob>(;9bV85PyC3lEhN zhQ%4B(QkDzJN;>5!WHL^(YFOJW^ZSsVH@>~9{39PQEVK?Vc3`kdmUbw%=juZMb#uR zau~)zFqsL}3f0_{iwRv}Y-B|O> zH2&O~UsmP)`;ged8dhDFht9q4dHk8Yc~5I+cD!Cu8jLv+@z`a?`R=s~Eb2Xy-D=;q zf)g1ziE&UM4H~XxP6VDs|5!&3Xdq-a}WV-)zln?;%fx2UOW? zM5vzgP#eDjBmKqS?DBrPJ;m3;YP*F+GGLMSTQya!2mJ=1-M6qGHIm_aoBfnIvvinEWst76X4e|SwmS8Q#KWNYNTyG?h*vY`q&<8eOxF4z%C(b!tqDP+KkL^ zuW?#p*SvsfoVQ-9)D*&{Z>_AE=Sn-9!h9@75HnD+QzN*I9w*YaH{Ee$ONXD*hQaS* zt8F%zZ{|LemasA% z>YS@AC&&!;d`7N+KJU=8`Iz>(e&pEXCjIoDe){_WTL9$tK*>@{kvOv3(_ujx)HqD4 zfpvUPMRX*u^cyb;(!%cnPHb3h5ArxH9j9pC`xQs1*^tLhkhKh!NF*f?R(~1 zh}Se0vj~|qZk6_jEqDtX#JBLGuS#(h-nS)+Iyz}ZI%XYzdZAvSz6?BV*W)}=8|85! z(rUK?z~>y)#)A2X&ZZ2X&zVzL9I9=0#^R3QCqz9%aA)a}5?dM^RI1UsziY%2yJG{h zCA_UUAU3Rzf6xXJYJVi43Z@QLdfQ@2I>GOrBvC>Yw zE<6WfuH12FAWJkA>6Aek?>s~6mN)toc1e(0$#*Jd=57#jG$!m8%YX6fbt<_FH&0 zby_y)&*Wr5KC(tb7!Z2R${0>0NWVq~Sm{^8Io1vsPsA`JBfoXL-d)XPyv=fP!J@&w za~~4v)(U|*BDE@7Y?LydL0gdyb~U-n-dvZpe$E2=!|qZQq#FKdL(qobU(bE67CPQk zHb#3<@ssiGdr=%VfY5NQYD=EKUuAf_-yZkJh2Ui}Uz^t5w!?RCX5UIv6Bh~p za4!TqNPOGgJ``UVHubFHs0V_olG<4KaZnSLv#!pL6kd_)0Aa~j8}@M)wx7I*8&pGJ z1)&XVWtIeD5pYr|SwRnf1@q?UP~LQfwA4A15P1!NMA%|+<4;)46FJcs?0jPMo|sHL z0W62Z&gqw4<`!tmD3v11p?nuSt|aQF0>p?vuQ+FTo0|ou`D6t`;j#RN#n&GQfQW6B zk{vzcx;3jl9?)xCIg^p9)b@KidDK57C0{MKU&r*@#lXUpT#S^D*=lo{<=5Xd*HLHv zZmzRP8QbwHQlz;GaIgAdY+dW~sUK@>DE_DoDJtfifSPOWho+tb;j$0EeE}aRy2t9< zO@TmD!+pqf2n$R#z=VVqz?GWViAT0}vrWin{-c`|Y-i(n{kZY{qE*9=~ z`-|RvMagN~-ICR~2(g`fd;+aTj41Cnerjs!m2}ZjXw)TiKtupXz}Xc+feWfdLjw8ToEc;4oUxI5(XhmlA0VWq8|ufq!s^_LA06j`di$cguEu z^N2Z4m9P1+0fWFl%VkhOp1xq(tp1xHokaasvVj%{0)x6|; z@M5`G>iZ*X|Uz7^PWy8&+#47I^4Ff-qIDkA!+; zobX%hs$0-aiQ!dNQQ@i)h=R$#LpcbIif9WlMKn7GWn1E^Em+WT)p=PuJFS`EziK=8 zn&3*7oC8PZ2>>2YI_LS^d2*Ya;^4PDr|OA6@alk>O&Gmnzg50@Z7pZKk7o(wtJHbt zbHAP1`Z$WNx3>h+u-O$&8vc2f3=qupfn9-;+8CES0cu%+6;!9h#EZQmSW!_Y7-(4& zLE`dLm_0Ct#9}?T$N~QziHfDja*%J5JXYm z8mG%q(^f=<&d4ozmwZZ&r6c5hsigI|fi1E&pSA?!YBQ`U%RP7&Kd#Rfw)h%3<7nHg zgFD+@X5MRu)4XgG(=sF$qZ88h1K04|kfO!pDI`mVk5D!|rc`nShaU8z>Xv*#;wsHC ztKD)`Cs|ey$G$7RPxDDzVG0CdY>_RZ_Vkx>tOyFWjbnwc^j4u^xpuP>RG+zoL#+ZS zlSOdi`o%BQv=wO|wQTb>nIjuF!ZI7o1m1qqHotHeMI_4yb^r>CR&yuRPU|C48*@kt z>PhEqTJm_>47yie9QK{KAjmv&ZZw35D= zu*Ap5S3jS%jBvDHB7la7Sjs>AmcE1_@kKMQ3UFpK;Y_W4(}eC z9B-5_xFP5kl4AgOR&q6y2B8ppR{R%a>(RsPFJbs+l+Y}qqmX-bt*t9_DCAM9ksq5t z=-McC3iXO4+fqXFkqtUjpCq)=I+Vupeqc}Iq#9`l5;n!tx9wVb1GyeuA$z1G{cnZf zoFM*@te*y$Ux7X9Rcjk3&<3!Rwxk_=i73w(*G%Hr9DA_&G3siAA{`10Pa)@9c($#Z zPrlBPx8dB#Ti~MJ4;P!>x4i#4XZ@nD1F(Bi0!iOel$J|~lld({-R{-M4T@6{!7{r{ zbk>4oWGZ!on_|2f7HiV)A1N^vlu-yJJ%_F-=ff^6$>#R7%x;)bA$iGh7h76w7{b{@ zpk|?_= zwgWGNoitNj){wpv{+Udqqd8^g=jWUVN#&#&hM*^=IcL!Bpad}Mcsle}XFC(&G`EY; z5|g$8T?uLMeYH)P63r+}8BW^++IBn$7hWVH=aP?u zh6=A!D@8RmtOecLB6XHbS+J1r8tbC~JLYkvWa#pO-z5Dj<2>glepIf;!+}1&Rp<1n zA1f9E*Jc13{-tjSPJnjCfe;9k{jy;go%VXe+V^A9ZaAXP+x|E?9VkrOtgnVo(dxXbdl+q zC4d?nXyq#rfJzeSJ-w`pQQiOWY@8SE2R`qfHmu9hL~$Iw_7J{pG#}q@X8I$>7)A2U zN6X{EM=a?1w7q<+(swm0j}0BK){o<^?Ibm(V=>T#o(j62mwoJ3cnt6te850-EBxQJ ziGtI&Wq% zx30`FDI^#?r<7#kghX5Jgj9#}`WK zM_V>0wA?v}AKRu34_ENMmX4SJk}V|kncraXr#aEmwV;qsjOq%1TD+|I_Qu~HX{144F=%ej(V zyl;|u9WUdVPyCw{(PKTDSE>joCBPEFdh5vSyyL%`#~$@dcNyp<`dPEj4=s2xK7D~% zvpc~0q9$K`HP`s9nh_JL^5!nX$1_33Q-0l{m(|YOBP}gwet5N=K98ahc6ZXyW6ICQ zi6_f8QO6~j_i-ool3Qkyf5R7ir*S*Nilnh0{yW9>-k9T(ZeSQ(vL(%*sG-|1iIbGjR{mc>Jwh7$Vgxl_!hI4`2)L`y=8ucovS;%zJ zxKU-BlD(kk6QV^+?_fIa5nXRt-R3=8=A)5a#nQbWzjlwTRVzZ+w5;jK2HrDvY%)!g zmegln7>via<)ycu37fec<2rX|RY#&KzMa!fR!eUb2+>TgXAenj94&-)mSK_D-IJnl zmg%tBeK;$KFsaSy0gO~-B@2Tq1?h=-wsMJz2=G}tQTSwub3Esika~+kCXbz0yRj5{ zQ4I9$VzN|KRK>Pvu-b5~Eg~D07fkNzFG&`jpp{HDp3kSbM?vcL^ zyA(TGvfkcX_)Ht+T$jp=_HTwo5=Kbc*?~#0yCLF|>@t*X#%)*C%}#JxDBbj_`s#ic z(3_~jG!ppbGm`DTHWL~I0UGA=g8BO8rjMM&KYl0(5bgy|=BK%Bg;0%QhIeYD&9lSc z4`NCb&zXr^%?xkBoWiiWAa|GHAGL3V(xg7->0xT3Cnf!|BecOAH@LvB{n7|+4HE(I z20-z}fA{Nry=&-j_UggMj`lY_84!4@!t<}F6YcNVgziGaIVRPy$a!I zYz#sh2?cet4m3d$rwl6K4Otc&+yJ||uKH|KvW)YUOIwYr7h@__1Z^UTw0zaNB%1Q_ z_-G1zk}oYbr@goNk6}CEvExw=WS)DyWMzouUkp$i(KpHvfGoeJGtqP!yWDUdOEM(K zzr$u56X(Rk|B{amqgA8y-U_9k?0Z|6ekavBdTV7?S#%-x&&Sqb2G)3!HpE<2xv&^q zK{+y@fs_I6_5~{gz+)p~V1I7zFMB}k>2*Ag*+Ss9*!fj{%KiZX1{5e+XMh(5w&`pd zLm)mLMDm4sef=E?X$`g1Nr(zzjAm|Md*y~{>IEZVV_zc(wvmUH5A^mkz4)+DHOmtL zo+T6GgkCpa3n0NjtN4XjARNC$VRp3Y**5RTN@95@SelL1w327|x0dpO~bF1w;zEdSJwS}lcvbPFgIKC;ob1OtoevPVo^3>_6I#9gmY@;|stCAK%t%q{m^U~JL8Az4gb%<8Tq6ej>=Kbp3syL^s6L@RaE%Z+`DcNn)(*}gs>=&XX zmh)iBwE0bsjKP2vbgR!o6x=kg^W=S)pe??xqXkIys?9(}`^~1KIr4RjRhfqxqgKxp zv<#`u6*?R>I5T(xFEQPgH}WE_Chj-YOj(RH<3>KaVxXg(3^&zs{4$H_sNH2&w~3XN z)o$&KT%p|*;SA+baPc*=p{I8LtU}h1*Q3jKrgP^Y~VE4_zpO+cEwR2wR8dkPOVXW8V z=U&6~Ub>UJKP-a~ekR}JhXt_GID@I-N~#xnI4hcsg&03aON|hO4~jxbU=(;5C*j9^ z+Ykgd>hoqeVG3Z!GU<=_e5?!dt#F+piOrA!O9oD;{~KZAW(3KdUzaEbE^Kj?3MU)Z}cf!hMhIbF2-Y+Z`m%983^7O40o5naKeD9_^H-6X7zvz|#-q zWAA1^%9m>BI?dI_UZ~Ko`)Lf2%kohY1`*5PYCd!@+ODj2Iuv#^33Q1_^c}iabLgxb zOQ`B|eNWJyQN%p5aa96*UtkS@Gn{fQ7m6CU^E`^nyfCn-aLBMB)SU%-0v}4{1s18^$ z>cG6KH}Lt&`Pu7c$|f?=T@qpuJi3$frS`bI1x_M$&gx!J*dPX4*Z|g9Xa<6X2YKOw zMU{Tl$QFh32FcWW60;kBg4fRwAB|kbPL7!okrbIVX<*HHK}W6x;&kPAmC^PurZ~_h zx3i}GRE>;^aA6*R4P$J;488#H#y6>R3L)lQ9&uC~#THqYjxKA>VkUnm95;?&T%fzC z05Ft@u3 zxz=+t;PxjLc>ZcXi#Zkqe$}Sn!@mOGnRH;sU_crgy4dX4$i%I-23N)XtM@iKmWdAa z?d-b3(&AsW*vUZAP~&Nfnm4(~*UQTz+FUtVf*Rv9Bl!^?pB71WdqjEB9>Z7B(0i50 zn8(Gd%UM^GJNLxl;P?`4PmX6g5giHD{qOtKz?8DJ0$v@(S;+R?jOeyVEJy{Rw0Y+c89T708ZnS!D+H|l4g$8^6%82XA);}t!v!}y_9 znY+yw-SBC?=6;k<#t`KcY8(AN5h(I1VYdZhjT>yp*@e@e=DJ4Ju$Y4-=Av#_0t5_=AfKCd9&_+tKgRR}_TMT)Zk! zk<5HZFk%d{ea^qBSGy;+C}X1!g*?z;E0UeQ{lQRNp|o`lG8-lwP@8X1)16LkH(&ob zYZo%>Uc@$2uM_IE&&|#nc7FihQD((+w%->E{{3m8qclnD-Dn`fS#yucsK5966k_7_ zqg2iz$=?HDr>5hq;z^hqzaRbAol7u?c}OrdT_(}c30_$^m!;n!q{;Xc4Hn^#jQ@8yVX5cDw>hpEYG`-ij6a35uI(XqmI=( z!#;xtPi+0srIzArl|qosrRgMg7s88d6y#Cw`#QxCXS-@T9aBtr4CB$&wX0#f5fewQ}(TO?zYJ{JGaXuVo8xs<8D{p@f<71qDBLRhu9eSaSQRju9l;36W2m zJKY>ueSAqZM6;kWa30LJm_TsT-_Ow3{pnJjP`K1dU!P!ikbnDvEZ#$D7JP)N)-AFx zQahj+D<;K~p(ZQf_b1D{XXjlL{9o3{?IwAJX$~l~Y&q6FYi1OlOd}eh5t!Pcy}P9$ z;~MO@3GN)X@`Q^gF+Tn`ooYdiAkxa(_;C`_g6}wa4nFbcog;rxptE0R(M)7aMp~Xw z%Rm#A$96ss+4J4A(#iSsx*}Z`&usj+!;votNqjGbA91F29kLcuJ^nN{t#s9yk+cLT z`UmlsGveFc_V(q8yDJ}pc&PA0c2l-&5(iY`)=vg;lr6(iecbU#zz~r8#X4kB{&8D{L1JFqtu$b7{El3p+| z$odLSbq$OE^aBf9J?9NOv*`IF4t8$WlVpdaDb>5~4@)mYOh*(t=zEdx$Du=##{>AfDF=TirhL4xpe$!QKGT|W0zD^+o zy&W$578se`@;nuABq5RTyC`l&$Be~>%nibktgd9w_-mc`M*3GUSFH|I&f^>sJF{Y_ z@>JYLP?-(C!`a(oOuLVJxll)IT2k!-lGRqBPGno&7mLOAEH+P%kJXQ*@?Zc`{ArSBN zvtgNctu{_@@Yj9by~H>8rv-O5A<%f&HQ-<%FN8-~NJ-!U?vwM2y0n}Upk1}h2P_g4 zG7u>Dr3FeKmLX{!`2Vo?o>5UP&A%`VX#mL}D#0P6ARvMSL5Cn9IU^a7j3fa8i6cP} zlq@+ZIp-WkK_r7nkUV503P={X8$9QKHV@vl&bs%m_xXxI^0Y2)^LO zxvhOS2hnm!$$073YU8wdwy?d2_V2jz1ry8xT*$mEtLJhD&CRH_v4g_C99*WUco75N z$V*|Z$uPS@aLp3_*fFK%=O?N|NkA9%bexq}n((PD`ij@G2NQu=l+EJOt? zC?GEm9IM-RKNs423)_aiqmId?dk%p_l7Qm=gWX_EEicI)HHsnfo@s(Vh+xOqzQcamL=9 zQ5HF43c`5^Zr1ZM+6#v`*p)d%vIs4&jq)b5hZAI zG+UR&sk$DZ?8s&a_|xJ5)9JV;#Y6oZw#Qf~3^84y=NFJ=ZH%oyq6Z>@)U^(gNJO;o z(e8A9?aJ|HfZ3(TSE)*|IvIKDcRk|lVKcW#PWK4Fxgjy)DB8nmHSS+ot;(b&KOd}` zkFd2QOBtulDm!lw^#?roG3EZ9&8D?OU!R_$nnlPq-t?`0zzVA~p}cH!{Il8_8-8^L zJxQZg&!o5JgA?>|xmwdR{VDeZvD>54pbO`U#spgqxY5thTX> zI^hd`SyqvmUxI>Pk&^;uEFW>_LSVA~DyCb$xYQe8h(<656LF0tukf3BvR{nfLbu*P zT$T!C3c^?&D+ePp8)P+sYF(sfWlM|aslLEg3PDbjmHAzl&$d1tqdM&XX%_7Rg~e z!fdOz_veoE=iz)vZ*%+$(mKEeG4{8==z2Ru*n7glq)?{x@ zdD$A9geoFiMLlZvJCp@bAh~t%fho-6@bEs$i&F}F4zhZ5=o4)mt+D*!#er)_Stq_f zN5|1GO#6FH>m|arnN(V=W_iEdot?3_3^*^9Rs%tT#bRDV=7^Y7#L{&{$xQ=U{?Au@ zuQBS;!uAeu?FfWIek6z)*w#8D8mSGsPRp%e5E_P%2UjX3kDP&8s>R4k?5@Mj{NhX( zXP>6H-Pg#5!w%B6n8DVzvK6IF#*Yi#oVAHt?&!&UL}Co);)bn1-M%9=q{)>8={&iO*xpX#3%b z!><_hE0r^ZqS3X-KkbdD;uRbNutnvb29#?&Y_>gah>?ix=1?&Zl9xyY0*i{>LWiCOgEiD~Y#6W0ZCsG+ zmmUcl%WCBn4JYpRUp0C>RxzN2H!h6ACt?2*IlXAK+3xv%aokOJto%tCHqBTz(OiqS zXQj^VeWR4@6cr*qW%c~fW!|Ia0jfK^_P^rN)$&{pgk6q%bM9L$rao*i8P-kuf+nOxlfLoLsr%!*RLXhnBBpG#-bWc!xWe5SMuW!+mpZ6K z&^jGRL|JPWFYh(>qTlpMCt5`*-P>5cyT1{%pjN5(_gMhe9`~1Xe{g#<5M#Fbz5N`f zfMO?-LDu z!qDs_5`+2lBu4GKg}Z(d+dt_}?n1y(J^K7U=;#T8j@hnCUTfsFcIjHderlIqc5STO z4L+@{{SXBAB;j}OWRIM_tq9psVX_s;d{1d}7}ZxVpn?~R;qoVX1|tNSk_amEuYS`-I=xQ;Fly?w`F4IJn639JAB8} zwXcZR_eDRy%}`*8Ad;I&YA?5Z(T9lhWVDUoU>uAEqUn|G7+3m5)^hG%NfS0wKumERyojk@36!>|{mNJA~|tFR=b zh-UfIKB=KyK2w>lLM`2)p?#w#jtdnG!#%8<`Yv+gb*m<=+V!Fvkxi4YF@8D_U!jU{ zmi@Mrqr8#OxD}WjI53DZkJ+cxixOyP(0Qtw*)&4LSZa>X)nb19b$?j-j;e&mam^xu znWZ~^*vJuv`8XnG7=uU%wLNFht;GMqhg6H#Od@&xMLOn(P?24|frr{$NwQniP-)lxX$3Qmya*;m!Jofxc0oFM-$qP)s*FFNLVH2&&AUI ztUkCksDITd-_V8sqZDjb;GvKEOd z2FJ@L2glv#PJ`muWROC}7>^H;#omHBOF2IJ{*~CPQP~J8wN(!>Du)rd0q(KKNy<_| zxS<0N>U1_YEH}36c4S^Ro3wvj^0)ZdRz4xoR-Z%LF4?zG)>gFdI#O&FQ<{$m${<1g z^fh?qk|mC};V_|HlG{h=`_-mOyV$flk~>mOiHLMYVT^@os0vHDs#{Ol?HhV_UXH_4 zYtDW?drtU7EGy&M1~t*ui#kU*hbFUR3>h#;Ew8YrMSW7 zWat-?7;L#xa&Lssvi13FOl|KV(brlCue2OI8C%m(&qdTy84Vi`{&a!aZ2e+o=xR{h zsJOB+HG{?Q{h&LD!Pa^6Xj0BeW+`DOE0+J8fjMRil*T}mHvhF0FM+2+s~l$;TF89rw^q@Rwt%QJ&_`sw+s++6r6; zdJP!0OUk)PlY;NwNGm9lM->!)^PYfGLaNzS{Mu)Vj0@=$atHp-#u|DqX}4aM+>H%+ z$skKZ=RXa72U($lhA52w+JL$H=b5RS(<0co5d=zreq`~Z~vLJIr7G&aa=d`Q;%{1xqXY0jiu9JlxB2P!ylClZsPQUK3 zsUXfuLWfQot>ySp+h2OtZ7O4h7ESy2EkySMOCp{`TBt92j*K`+d&c$o_4XJ2Dl(n* zJg(G~Sh$@8naP2F%YEhZVrwaNyGHWCc=NO_)XV=!Zz}N!hI-j|h^Td6|0uJuiV-Z; zTD!+Bo)8UVdXCud`Rd=7Q*78rTO+fsG@-~=NE(3DOggxMCoQRFIrwXjl6!XUj?t!A zeadk4m;5n}2&CiZfCqZUk$ssqzO@8?f)nHl*=nydT}%@MF-j*&+w%H-HhxYs)l{p- zYH)-PMd@=^6{HRzjm`D#%SR;q5~wi6YD<}dwD(R2y&iQe&=dQpj3my*8F`X}lf-8DXTz3W8rhipU7#wiy9#*u?a z<*AORA0>sR_g}vQ&RlSuPslP!%ud_r6lx@L+}sB$SM8a#lias8Yk0p!VORQuk9lWN z$`Uz^SXD5hU)d?rCrl6C{oK0qoDzB;urunZ18aP1jt#5A03S5irvM{L1cRIw2qw!EK6rg}0X2 zE2`ZV@9~?1hb*uVpdjY6#O=?OgEWwrM}D~cdh|$HvXz6Z_x!*|XxfG-E&;Wu?(U&@ zC3@|T!m`YY0l+pd+nfJ6w}p?XCLY(jcL>k&8~+; zxx1*z@s{mjGrhiV5umminZRiJk)KI4+gK&0(s55YE9th_UAHaXfNaT)&hCTPGd3ml zMp<*qzMqpqunCTIGlr`jlszzlN(V2HRV~1dDNHSv zXg6On=*N@dQ63HAUnzNuvdKItN+8)~y ze7O3N2Xo>Lsp0Sk9@1E$po#tO_f#}ASWFXL(!cuc?g_gS&U4vjzc6zD0EDYjgp1w% zTVx^)L~&Wz?%usb#FLru3E|B^u-yNGxyxzMaK*P$yLx;hZx3ub{07n^SQ;K0lv)!dxT%M#>@Xoo)pmovr&e1kB{!>PY zsjc`ffe)WlB(Qa(hj760oBg%YMr5m}2x`#$aC1{R;XU;>;$u7o=dHg|lSqGQFHAj- z`s2@*M($%@DMF&g@3%DZxA=x!h|0Q9%{W+++v`~&QW}=`!Pd98MN%`qBD*A9eXN98 zIdg;jHdytQH&mWGZExyB5TUnIa zn(VH#6uUL-rA#8oWMY9_#kkhK<9!X!Vy4 zde}u2{RSF$I=;mqq4qcU^QC5gG_8@#az3*0I6mCLFZJ;FNZDI=4HwSaERnBttzK$h)>+op;c3Us&rsPLBBXio6OzZ&2MuuB;jfG>(5S&=qAk? zR{Tx15IQr(3HKdcNx}K=ffpmz%RC=JUYZsukZ@8a0(GhtIA5D5cPMA!f+@oHj{v-< zBAT%}l#;}Fx!+4?YlZ>jY9j7RWa3<-K!_dDy`=8-Lw@L>oFH>fY0^_UuJJeReZZw~ zU+BIYk!-lxZkh^F`{@xQ1NSit`HsD1j;@PMNDqwvY<@_`Fh$f*`k~+kqcV%YqN%Oy zSiW%owlz%ux*g&|T7y`=-VH(*Qb+82OR(E!cPgJX1n8*|^WAVU^jc!~=zi*G*-Gyo z6Wj1KGVETZJ}&8EiG5J2VFpdwFH8dC_jn7Z8$uGX?YdH7kmh=H>F0HNQvAk#XDBgiQj`U`DT_2a`z&A~V2 zWAAJ(zs)9#{JwLSl_H5V$Yt|^X7&60PiwpjmM@2Cn591jztLb}LqxsX?bH)QgcF*f z!KYwCe$y3`fkX(ZkFah24{3LJ)W6-qenfJO!sKnRDP2gz-dtSQS4JNfPtKSe_`O0R zi>amn2t6jL>Bo$*o!}D_@<+Sr^A@Y==JH3{H>!m=M2sZ)-{cwx$1mmTI=}aMz|!%P zy~>l^Q3=6=xbSgE+6KQJh*MjQe1Yni%FCj@uk$tRy^gy@h4V(&&JYsBmDEEnyxv5% zag{)eC@=n=3Ceu;qc^K8n}{NO7bS&lKTj4>h?};BtJMuuM~~GRAOo>O>|`>@ny3!u zlV=;-5jh3*g7T=`c#_H=qlQ+=x=R(0%v@0)EejY}n1zdQ2oHT*7qo5aW;-|@5f1AW z*YEFy&W9VCO?vFL>sJf=-Iiz&`YUxxf$ozW>pFXnaV>^&%BblxJ@JvNd=HV&UNV-e zc~Y{7N4u`DLSHn0V@Zf`=o8GNm@!^@BXLgWk9SiX*)nPA`z7VVjI$eEm*(!IY0Zw( zW!H(qY@$>N%~UVvz<2WcX+47kM@A$%F-p?xwuM}P$V^1;_qCc0byKI{+jyR;&&D+q z0!+yi&^DXYOnGz1+^4B{uRN)9?nNMWx4pAemR=l*b$(yy?EE0B0)tl}*Qlyq351kFoanfwwz-#yF%t|}c z#&BmvTeikT#3PH~_yR|x!EF2;K?d9O zDsOxIXc+_9Oe&Kk*ejS04bxJAKDLX$u3vemo5+=6=27pLP2=(lILfXsT(avA+!vSY z^)JrTl;OCEJSmzW8RkdnX=u#1xL4BFtY#jn?u5MD@)u|t{_q^Liy1<2BSMYBNuBpquT6*|qvpvJ!TC3P0 z5jV=QL3cZjxW=5@s%I(M%Y4W1vyV=;X(duDr7u2?rIE)+?aK$(s!L4-DicwIHkA*w z?(IK(`g1n#sHajA|0mWFraMAwx1XlJG0o3c+5WRHkub;AG3S~Hp4&M>)MjX6{Tc2t zmo$chpA%s+tXV>$64FM>x&+l;)mMA(cPbi7;?>s4Z!elltRn0g2C%liKkjbL@vKp5 zW_TwwkbX4Odm)|UGF1hu!{zJqVa!b&TvUi>TX+Q#~ljr4f&Y_+1dCt6T#)!Uyj@P%SMpgLgblJo~UrGAbYV2@(3N=3$A zZ}v>DMy1wzA20LZL?oL&s$?T;V>!`t*+M{QI%*53KHa!w^PqY&M z*!V%^J@tE~5nQI9VlS}ds_{n_6;B@2o*oBzK^^n0(AGQI!vibjBC~)IQ{#<(I1+<9 zxfSufhmq?2v73;>Ejm8F93h>WuU*P+KOcov94U5wU4dH|s~k^C7F!%a0x~le!m{z| zG&06vIq_om_z$%2TBX<8kI8ZW^bUSes9kr#s9OBn57CMz9l~Gk=TJ(d_pD70FLD;p zUjJm8$nHC0GfF0xr$!SaiK3RlM_Fptx7`oycAZqqQeJt;5gjw`WK&T0hzh-2QmztF zX6-%xgq0%{yT6Z|e5szlj<7Auh4hJ6Sr#^ve`k)mbdh?nT-|MM#5?!=65L+Q*rboU;YGsJr80S|-je%r^RySP2CQ!3AiTW@ zIKw?g`GT9~sj7CsFvHaGq;ierMuNrr$8GGG+#dxUG)%}9fjw3}s^Gpb1 zgI?4ZVCT!jYGp^Kn@iGTtd9?iTo5X6W92F$!c>AIYweak#V;g}@S=zBCvyU^IgBEf)?QJ^s6b(z zZ=1%rkXtYAGF0+*z+?R3)zEm)qrDgI0oyhdvcUexd1_P9Ax(a~WewlWi<@sOti(2- z&JZ#(5UZ7JezvKS+c-Lm4(j{X@ZpF<|BVdCy-WFSS+}y&BkqeiYPXw^ zrAj@%IzRAQJ-iK%fFfk=1)_poj~-ub;Amr(&v>gZM!DQM^tsbd8SVd>s) z)%%K+ZA1Pk{&uw=0`{e!;NuxDc;GA?RUGoR2$V0IJs|Iy+4*Gr^Mj-bNhLYPo7)v_ zi!miLv+enBLzCQAbrMY244khKAd@2kC!>Cr%As+GGm8}1bz`y#zgAFmgBY^p69|7M zXxJTQ9#O8w;kQd0f}NE2dA(&tDA};+BC~ zezWv3iY3f_eYi6*0c`WuajScX9W0(qgIV~daEBn#;Lt}nHqNR%25`9DWsQCOYghl5W$P>T3?e7puDw+ zqubXW__voI-g(uR_xQ=}k}MgAdz8gOe!)HyqkbffX{$fOd22;=4U{O+sK^&yb_cQ8 zT3e`AYW~>WO^+%JZvEWPwK2q@~qu>~d>sy7IHW z{TX1f9>L&w?FhZlMZB-Nf4{u$+0-`o48P+ot@qXvyu|b>^U$AI2-mq7Q=KOq(9TD6 z-!@PIn-K%kr=Pu*)AJ8E?_)?|XzU~@wC27^zNj6s(iJlPqoGU0^5*2-%#UM4%-k@$XKw^w z_oUDa;;R+CT`A0q@SK+d5|gxB2DbxjASxNqQc2Xwc0J1Iky^!PT1q%r#NNwcG92a% zveP8d7l&_S^4{BM zVMy4{zqQ%^W^r2hWaB?l@Fm&|4@<=NfX6gf>WvpKxGaXT8GpqJOyFzFZ$T_ka}=S+ zI4nO#$)w)AIVfVfc4_^>2HA|0?){8uyGH_(6<18cs;<1toeR2^YG(R+HunJY7M<}0 z1b*YAiB^6oJj0yqrlh}v zj=Y(#;?!~L7TzImLM%Oiyu97Ryv_WflmNY8vYFPdrTm*Aeya-EL$>LG7d2BjBnyHN zC}Hs7TbtT-KbWGRkjlR6jgcH&S~ijp+DQm}oOp+D=_~2LjltBE52rh2kYZ@XF|o&W zE}i!nH-3aGr^=_G&^V85n8j$t|VU4uxGRI~0JOC?v2ke%p0#XX?;GbY-^KtdQ*t8yTiue z=1{}p7IL!2aq$x)8){zPnr{heF9^?UBcGLC2!RN6r&gfhA6w|oUbp(}A4;!r{L_=T zI=`h3-OzifL~}jsQUyZwa6`5=D-YVig0735+5w$OU?zrge5-z1=9bSKsj_+y9Kor> zPO<1uPlVpk&w0HvI>}9RetvqCM5rPpd<_+7EgF7LBU7+4WBbGNBV)b%+=h8t<+K@s zaks(=0+aC7r4#~fjbDO4Z>C=mK^}VNyBAe;g;)dIurSdNoPb>p1T}2Ng3l9oPF+=R zEQFa@iQA73eD1YsjS&Wdvi!sllxFO%hRS@oOcwy6s0e%+WEG4QA0*mF0z=! z2B~JyjZ@}xPbsIL-GU)L?@Bp4uhpxFhzA29(yjS@xicFdHB0Exv*dB3@?6s z$xaR^AmlNkJgU-Au}L!FN0dyCMC=;83{j~LdYuEDOW9lPP*uvVKUZp}^xBlfs_)xH zm~FOXAj4|*tNta+&fIGqL1Em>#(^_A&j?)Kt47A^W<5eD{-8JJFY#3ALGINev5k9B zk>hDKW@#M0-54ckYHUr=BJ7UX$zlW?<^ddQM}SUI52L*8zFQ<)zl|Nx@eA(9cRQ=^ zBH6cEttX8#28!RuQ0C1H24Vb0R{G=e71NnGHRx0kWEX}^*s^{deOZ+A5LTN)CUQzy zX~Vj`k@zg`x{a)|PMI20o%<5CV z`~mE}R8um_fD-GUFM|Oz`G@FF0*J-kA%00-yW?8jrx~?uyaWVxD$+}6KK3ooTBR{+ zsHo+<_%3tpaTIWqpm%5*S|8G4mwd0az5ZVNy>_~vRasd?qC@UXUqn_}!t?M!`sk(P z)Z-_|Ns@i99V4v2evR>OQf2PybxAZnbGqa{A$po|XI}5_mkjP{{hjt=zVWbPwVX6! zyQ$8;e|CUs^TjDQP2B|YHQ;d8<8{L2ztblA4pNO`9@BQ={3Z>Zz70jbdQ&io{Na zU4s3l(a!;GnV}Cj(&M{d!qnn3=sq~yCNuSQ|Ghi$FKb%3j~S76 zEi|w^dnRA2%J^$~`^#>Hw`yx$VN;*l(+p z#U+e6sSmHHPOF#gnJ8BsXfWC|Zt;>wFKUU5zEJ!slFP?8Vm4A#mAE9%*;l$sQrYpj zmNGq5?Tpx|FTFBMMA#?$<$8rY5j>syiWj>R*tYc9BTkNx|GE*`TUxCbOQKy_rK##H zUvT-Yo+ai5JF-phn6C=UYJI~DZB50SPZ{|*^`G)Sv#)Qq=E%*BD1IcCX3)XfO2a2# zZ0VPomD=p2zTx+J*Lp#TQ5KH+%Hp8#l`n+>!Wa8l%(q+U!|i2uxdj;2wO zQDmglcF0rVx7e}e509VB8Gc<|h@B<4uz2x;(O55XYisI}E6Ao{5DZH6@R{&s`p55T z{Vv1H8J^gxmDPb>(TSb zd?=xtuPrajji>d@?|)_r0F$uyB>r|@n71~+!E>kW&?nZh16c;jbtHoALmW8nY6$AZ zX;Fs~<+L)Ezm$V^qO1g9NsiE>GiZJYkmGz0=Yi_ zO(prudI-_m48|MTUvb>EEuPn{%3jCS8E$_`^!I!{1?${9&`Z2OnvNc-!=Yi4)vG;T zGj;?%Y;o6q^4`=AxEzr5N#TiVi>-(F<8G$Ja#D=%QV_lnlR$T-6QuvUrv+V1*b+ll z&{_hv%l?obRnyv!)HUGze@!7;G{F#yULBK;U;T1V{E@yK2OiYl%YgG3X!Y37+y?>R zCcGKeqb8jYHe}qv+WQ@v5S{9M@pmZye{lR{M(mTITcGwy+;0Ep`)DLmIOy0L@;Eo% zp5g9P&Yuhro|I+DA45DOr@#MZ9ryvG!IVPviUgj8(Nmg-{%AYMEr#7EvHv6M-*1Ny zLKtnoCx0pi>EZW(2oG^D%>1h#OuwH0%K^CAL*{?SAfxRe^lsdL-f!XsP4z~@)e$r+ z0w1RRTP48ZlrY57|AAB(E<67RQZYyTf5jj?H7$)PHZrn5Sl8gZ8UY-jz|2G};YqXq z<97T#qAh5cmn2{q%n04ThYGN*zg-h7;3Av+&3wQba-8#u^z*RPm zSWIu}z(#-CyAc}Xr)Ug%IFjRU^8XO6egRx&qbm|%{5SP~nq2mR*T~Dh`;sY6A9`Vd zzUChe|7ipFy2782LI0nBA<;yiSiVLAqI9ZlgE2`YJ0pYTKyJW(qwmEx0q3R=9FrRZoxx_|^;e{3MMr*b zz6;|y1rsAWM35wvxw-77cX1&v?JXv`O<#N?JEs;eI%4xDPf|Po{?PpgoB+OH-oP|z zN3}j0JU6!Fk@2Q|+;zo9U^F+kSk4O#9fAoZ_GeATpuEWjTz2%=0~p*39_U4=ga1kn_#623 z|D+uxAL|qI3BA8N6em|i-tTw?+?VwC6Jl5oeX^IONKwFVioc(eV3FIBl+d4fw-j25 zZ+xCVufS*u;C86LIR;LByAR`h^{!*Hc9sFS<_Yu%EDR7Z^@+bPm=X@A1Bwu}>kobw ziaF}bt$e#l^dIG*Auu3&CMDOLJPDVl7{DSC`@;ZT(%~C|D0v}CAo++pkX8TI51%oCBtk|*1Z^KL#>Iih zjRm@ZO!#*lLRK-^Ye+#uW+01>H5$D?#|$Qd3&Hz?$mD+@T!}w>oQ(^7A4by|g&T2qu3SkkK?*zy~bjV_+7{o^SZuHoN%yfZNhR zI_63Rx(ykg1J83L7GRq-Xx%B`mY0;_IMz~D_TY(xf&ePPawa^Z_YlA~`BKZPz*KAz zUXWFY(91LWlmcGNO?jCCgK1~_WFa! z=zkzwqxkGRhh9{oL)2h>Ex`YRP4AQoVEv#&+yOM$%CdZNhCHx<4AP~ioRKlZt44AA zT*DBX+i_2KG8*X!?t|10bPLSZtrQDcaJN5CK!#S4-~p&5;w}Ku`-;5GV3j-vRI=q| zA$8_uI+TE|d*+pJ@JI?nSy9j7yo}(N_fKB_ca()Bl8MwFgAF?w=P%eSf0=TIPjrYb zpeV;IbM`Y#v7Sg|M{ouPH~`qJ?&G-#X6iY44`PXAu;+rN zW?(7~0BruDA)!uir5_m4;8B1L>snk1JfotM@%?ulLh>bb#K=IiB3T9X7w1MBexrWNI@W)MeSNHjo33|QO? zu#CDV&cpeJzhM(Qx{VyHc9?Ad05VL^-<&}{F92kyh(}bxEi1+0IIE<>pTP!V00)rI z>svZlB}gU!Hk|?zAA=V_u4FHWHT;Rn8O$XGUjBEK0odgDV$Tk?A#C!$U=t_4_Y9vf z+c$tj0v2z;UI7w%A`$vn1Xv<|NkAfM-p^pzG{6L4lcY!P%&fErU~@iGzz?it1^_m9 zpbP0|Rxtr!ILKT0NekrLspaooR0~tjV=;JWWxKo zOJE{F0Brt2Wb{7}u2Fn*on^bEQ6VEmL4V$J-#Ij)MK!0?ia^0S;gQU^URE09$|Q;3ffHzTf~F zo+r%u2T90n5n*)XU^P&aD*k~%0Lsp*hWrnNU6ja;6Xy}4q-UgtmI5M{Wqmutr5C_C zdN@5Jn0hHLKq>B(6R|ANisPPfF9dD7z{UfW1r`Kr z`T){1&Iw;AI1j(VH2m{mZD2CfCwrZ1g!LaiiC}FAHN44XZ(mBnt4t0cJ>#5YL-O}kC~W($0&ksJ zR}ol?kk!S->-Lmw$N;Fbf)XaZ1)#^sZa| z8YPtaZtK|%u+PS7OzeJ7;}#0cp^|*wG3<{oS?KJ z68ZrEF?LJ%8FVb9%(T{0*4dJK$1_*e9{AxfxtLfBpT`60FoQgFZS z3S2?7bEgv9T49m^q)yCcip*E#BNaBLz(q{}$IQS%%iouU*Ic^qX1Y09wmm(L;{&S$ z#uW>9bkW}W<^>!##*tGm=(04Bw+x(hF!uSq*NBR<7|4tec39bvRU*&bMo09W-RWRc z;IuOFXFx5;vUi)46aUaynlhO+=hPW?BuLFJ+N!OqQ`q5EhK4=T0!#I0)Z)Rf94Jt% z4tS9K1Q!JBi2L}A_?4$$#gwm&*1>sf)IPw$scl%itF> zvBI$8Em0QN?}1T+D<59$^%X(ICt|_^nqlx8K<^Ic8v{<6j%NuNCQxPwBlHTbytc8W z1@sjukmk@Khfqd*e*KhXobgOBC;VzKP2_iEg0zJvSTjEvPHFBV_^yM;R{pm*8DYao z;E8+MH%+An>h+nRiwY1N%Xl?(rYQq1;QzefyK%Nx!2h{!a)yB*U}>bn9WOn{YZd-% zR_gW{{oDfzuAC2?|eu+vY(lBEK9U@*du-dGhv|PY!)ZD?}bApY!=N z817I!fKHtp9n}(Vr`CZ-3!Y4LqV18C+-DnSp}_8BbO}c*ak=k+#k2sL&tIvGZBqcV z6U26^>1Mf*A#m@C_^c=k+%x7utOM}vLa6iO0$%Vx+DCi>J{&KGTi}Df0Sp!ajbxcB z{sM{3E&;q<70_zfg#~U3s|0Lr^AZAenVc5HY#<3>x4+$>K=dL-FvH@%Z9qwdg#+~X zEptz7@-;Lxy2=OQBC3E$Iv5qDDj%PNWb(g$D(Sm)c^xocC!_Hld1ED_P!H7KJ3Lm@ zI}-_TOX5m8pabu?}B=PmI8B@pQiE|zcz@G->rd( zCdf2*W`(Xfoqv`uOCtZ#FFHi*cOU1wWK+8|5 z!=j+ki>?MVvUr*N-hY~_wPA6z{RePUC2&Jq^z{XRa2%0_3y3lJ2OB+=E;EY^921lwJB56iJ50Gz|8$MW1SH9fApy6< zv<5J_vfn~&RgaHwlMN&fCiKDy=)3toU5JPVO?Gt1%5RXO=~4$P^t81D%1=IE4?J2u zC-OU>h9}QhDYECZ59{+?|4Ty!0t{oH&d~QEQ$+g81OO?ee>~As;-kLB=U4@RU2D`0 zY=-s!$jlbqS@zk3c*cZ zoIp`92{ch;5(Ef^mrfR<)9-_tOT=Jw_kydQPFG4^$0-ol7?=ZMbn)7rx6zXoki%lJ z3FImwdrwAyaI{w*cL@Y`uxu{~hlL5aB^rVX=-0YTE3#(rb>lCvFYp(N>ZefuUt;d* zj5~*sr{H!T&i}2U0(m{BqBEF32?UKMmFZz%Q#oBroKl{gTOL?Zei!+!g3Yjt9I&4I zN)axJNdmQvpz#N?er&*q%(F%4Dp8#=(5MrPp{Z>5q5+3dPR)O`zh7;r->4ZJ6GKC6 z0tPl}{jzwt6$DiP6aQ~q&Sb9~rZc7ww>{xo!1lu}Rw0m9E;1y0Y0GBc0HG)%3-Ddi z6GhfRuIZ_X&NDLy3Q&Rp7lAr4#K)K~Ock9$fN<)o|dS5P~ z5~S9Lu_ucs!Fd}!HH^SmK|Ant;W?cX=iQTJufW*L;FfTdAJBnzp8D*n<1|+T*e&!r zMbRz|)|da6n0xATp2Nsfa61p@|JG3dt!Dx#Uzc^{-12}|newR=Fs}U5c)0sk|8k6JV(V)4QvNb< zk+Z`|#C_Gftsp8(N5B;fwCW%o7LiLGfMso2~d3ECo+4vgn?#0(fkB)X4Obco^UO}u2rqA>RfvWmy z_q$uxXBQ}{>u2>LEVG?K-^yqRG>FxG9g4Rn`CZ8~`CT)zOuVW^HK!S%I!3PbHrQ>& zB;HMeSOaB+{l0d3pid8C7_kh>6YnI>|NL>T;(c)X0UaWTK8WPytvwTcHUOSs$-n6V zk3kPmBV%cCmP;fM07ABsfKyMHu@Kssv2!^=AW_UBX$EG>45)lLPnYHo{R#dd6^X-P z`_$)55;Yz8GR~S522Usm@X>ajEGz0Uufo!|kLUkob~)6>>(`%zqVbt=t*`KZnCYfL_n%pLH;t zq&}O1wF_kg3S(I>i-Nzek#snaZhr4~a5BaHOoARAf__p%aK46t*Y-2((3xPupBnF!Ak8x*b{=s(KG=g27{1#td@C#RJ7|4calXD*qH|F?2Mm&fZ$}*z3r99#ZgiTctRBg-KbZuF3=CX= z4%*wRC_vxCTuK0X$nn^H1ZATBH|?-S#mQK}wT*9CfWm|G{r#aG5TeoR%8ULVj{(Tp z;{l1=cL8L#K@iYR_Tv&_c6Rg?NWkdKzX}iTeEH#fCNMP%Wc_cj461{oe8?uCoPlp0 z6AzT}L;Sg&1By8jJ_%ApAvG}Ho<6lo1KE(Q&Pn;fxpp*_vopieU?wYp;;SYyRyPp9 zzXgi4D&lptuYm+4qXcRYoFTrT#RK^im{M=UE!jYkO@k=_sRLLPcR{SMOTy95cc+My z6GD6h+lT=0>Ur*J6y^U-JGkCyPNyk~4lD_@Lmw#BI1(rq1&L=u57cLci)&$n#M`8_ zrEJ@q|Aq%vO#r-p=tQ6ocPQ0=V=LD5D2+c^xG(eoHRb82s*^=@O30l38kkwW9zG;ko{RA^h5;1+HJ& zBm*o|Up^0%Kt#ju3H~Et@u1At}g%WDgkRFgu_7DN8AhP z0+}a&ymfP{d(-3@`CkTNa0wVQt}YWgxPdt0@vD-@+n4Qd)Bi>t9boZ~2V5svz2yC2 zBQ-Czf@<#!QIr{j%K#j&?Ok+UqbamZWtt@*JHZ zVgD<6@zCc45$QWGJ}~frIDQzYoy*gjwJ59R_~vo6nPl1kc%&trCib7FmLLVgyL;W9 zcMmqA8sf*Q9oc}(!4Foyb#r1ugBW^#5phq88=NGWnl36LKXnB!K#BR4ldpG-yKQzZ zYc%YuZ3F)H&;P~LTZcvUe$k_f5+WhpARs-o!q5UALApyihL8>kK@jQg8ITg`kQ$Y4 zhL|A)lop1eaY#uS;CJ}`?!C|b*XI%OocHW^?X}k4t95l6bhL9O856u!6w_E2dQv?{ z*Le_yy#{i_E*h2}JOV!keiR3xzsz>=+mU~TbGbKZ8znthO+Z;AF|T(} z;IV1q@7yd`-K^K{v|nN9x`slJi`gImc2=m}S25eq;5hFllureM*R4^V$ECuM+YKzQ z0}6Fsev&5K@qMB`OJOfPSa!Wx?Ydm1^Y=tc4v`1Ygsz%zj0wY>u1LTmr%Ib!>#U7>5e|Zy&u-| z?`|L#N!GvfKJVoHys;BqM2rD1 zM|0Eiw+UhB-o{`ecP$)tfx-go5l78#n2it%CY?uF*oHyY1-h91r(L_i2Wa~FdFN%F z!}@63S3!#2k2-XLtOtBjE0`3;*bxum4(YcFY6+Ev3#I-o3n){0+~6x0@6(VXoJN zHGRRSmoDbGQTLP9FreRbP`Ex!x!Dw|AN z%k)S*yXjh^ZP%%z{hxK&&T@63GVY-fi-E7z{-(eI5N|JkIo;Ix&Dv%msOhHuaAPA# z|LPj>Y{^_MZpupz1#Ff;8M|293Q)HyJjfEQaOcjQn;Q;~=rRA}SkU9g>Hj@>`AE0tj3o9Go_w$P`*^8O@3%N?9>=bgbW>3eGth7m zWj|8XB#M6bSK!=w?5AOXNx*W8uhT}}ep^$kK%VqT-Ajg#E*59Pm3qaTgHQg~Vv z*$QEyJ^M(3I?y%n4vYy*82Z8t-Y%}Pn#is^&>`x=r?aRJ91t&ZuT<9EdhOzzo5flH**jzBs)xb(HEUX~#{!nok zP=*ke0l$rKK=C09n&UR!$%a79%1mv-@#pXBL|*`9#cvY@t%ktP!4r5C zE{0naUte9_h9QOmt?$gg>ZAI8N)74+P~*#r;B}o7k^SY1v4D8b(7(BeuA3`QDW}}E z9z{YH!C?cbRW6GV!Nu`=<|a$VA+%P%|8?G?z@E4l8au- z!Q71xJ~fIG~kpPG)BDdo#mAGB~L(|LvPUGgtRE3HaFhF5}36)N3DH| z-1l=J@%%UR#UW4@JI{g2ZP5<=E1>lWVf@;scmZDbneVFF5OAW27fHr&wQA*@-9rI6 zcuq20maE7IDHsW-u{_KR;kSB+K!FAO^%nqiNKB4Qlq$EhLb}$erSyN8m5nuy=Thw( zA6-8@s+9dcnbjiPd5%GB%Ad7-Fe4YHqHS0SlLu&%gwn|}K**a5uBex`HQ@NM-# z++6S9(BA%W^HGHuEdJ&C*tAZrXJ^pi_oj|7lJ{W5FndCs9c;e;eC0XH`Z}GeWK(s! z*DgWuJ1-EZ*d#*5BgNH(C(<`asqV;@n=as`Md5ps{GL-}>X8?|N7;H{;goq(riuA&SDKgGw$-Sf&YeQ#=lC}y}ds)2wbmSU`#A$ zZ(_`mB$*2;z5r6&`ELgS_%>M_?J!=~^6f-hOe(f^%Z4yHr;*NGfPwpR+Eb~G$A|n0 zgwN4aBbRTk&yu?Ovc5x-qtvwy;Uzj(QMo11NS__y#T#NxWDSciYr$?*xn{kb zvck>i4;X{Oe}=u^mWa&?{^o5`v*FN$eLDmKp3L(w-GSKiw*Q@}E9GurX978jVc12C zx|!bj4ad)w9?SfKS>b)ZNmG7Ah5wF2Q!^(Nv*OzlD!V2uxdt zU14&@LmUrS|32F1x7w4CC91fWH0*t3V*T#TIly~%34kT?tA%tiw6C0tFt?Xs&s|C3 zciS2XMkbcu(8v1aKKCQtvC5}n-c92TH*s%G@&LxsRkwS7pl@U$?B*L0UdS+9EH?LR(IcTP5P0Zg-oh9!lj5?e5V zYHF^r|NE>Bfhz1w7!sPRHDDlEB(&fE_=j=$AEyW=fj2FDrJP-3(toIB_S=28esWSh z3DuJEYB}^joY7fq9TH`*b-xC3r&c2-2WakP-y%e%nCvO_;b7_jvbF~5m?jVL6RCj? zV$O?irldzQb{l`bc)oL;C3k@gz1s-HS*p|(qf^OFkrM0)DB;k<1k5dS3`7V%Ajef* z$MuP#yIFM{BHcn7mKy`e0#`(+$;4dL`v>ErfNSepAOJvR9JxghD4J$!evi%ny_m2^ z2Mo>EXs~_DS0nTtO_nyp^126~T0-0gUyl1lTb(w-xXA0Arxagv1k^5zNxh7aOXY$s z8y=SX6yaX%W#&(E<~bm(%8o4dJvKOXqk`pOaVM1_o2*^HPQfN4hXb4FI0Ht#n=!ZB-u^>XchrTruMRcpt8Gk zEkEAhyWoAp|1GI}_e01nh-sQoDxVVYU@U4$gUy_ZoTk4HhJQz!+b2DX4`^RyQEti9 zKEjJ&3>>z~8e^Q5mN9RU7I*D_AGkXyhX3t|s4z44WKcX4Q(o_ptoppU5@)7qj~$FD zFwMQa(-1{5tn<>8wJaBPH~;F4-`sUkb&*+#r0RW;*jxEcr1-Ajci^me9#)xjR5gae zz31v@3%v&z5PGUCG!9>{eF|ab9xa%AZ0FBsZ;a1INviS6W%cGpwc0M3NbtO`E9B#L zd0u@yU&z@y&+Fp+L4CI{+%-P?k}cx7IlfT2k0C-U^7~P8->WeDNP!@=i_O;Xnf8rm zh}@;)GGmse^a@6^@=5ygZxnsEd5cu~xf#FNwM_ zCVYq!`q{@q!9)TFAijt3cf^fAFV_8(pr!t1m>Gf?@CZ;b>7Wl9^BPG)tY=(1!5Ll5RIGo#G+AYb z8?aK1LCH~0KuyX7%_6q7=FH{@4-+-hVdwwYGtT)suFwqj6XXRAdFowB)gaQV*yREH zLM}T0_~llC@h1^D^DaIaR9_)Wcqlts-0MooC;G^xy8D5UQS4i`5{ALi&I-x)6;j&= zG{E{fzB7YbL;N}dcAf&m^E|JsgQ@?gXaN#@SUA{=&XHH4&SjW_Gy~D_Sn^ssyrn$KtfP?ZKa2h%>svY zQgG#>g}I804?l--t$nZy`d8V_=jq-K8P~!=53`*wO$W|@4_I$R%iZ7OXKPqK|9!N3 zv=~*FwScqdVIXLs7LTbIT#+!x0COvTiL4&Nx^P^~{fdO~$zt)`+?RUU zT!DMOg$pu?_m)x}_F*HKh(zf-Jp;B=PrCRro{B8+eTb0*DanfVU~Ze_=4=K{aN^pp zy3jXZ_8-v{!Xq(kq0P@#^oYp?s^2&nuc+y~P5(eJ)oO3smwX6D!$ODC`eGQGJm38> zM*xZtqxRX8N+eIN8K&9c(%VAS_3SfmZJd9cBTHt?!GU zD>e}{O%KkSR^;{SSL=8_4}j=pY770bU+k^&YrwS0>uef=CIqcHXlU%g*9U>ou2~8!;Mvt9{XWMAc zVFo`L?Y#P2>k|~H`ibOj*H9Y?L({m@rzE^`1D#3{v-G}7XGr;73|&;XdRF`~Aa%X# zdEg18MM1V^4SLEMd9go-by{FtWL=AQU#Jp7l#@tKtI()kiElAH+sbD4%VRH!HFD>f z_mlE?^LQnJ86+QajbWjdOoEOk(X=$Vr%xRZP+Y@GeW>9=D5w_QbLGC7A7G_RkI_h# zvQ1Uy*8T1VK4+&2u(&#iQ6TYXXj{ty850z=EXTKf?-nmZ33s)h&koAdQuogao^>SX zr^YL9%Um5#^=(J;DM9XFf?-$E$j8+P%OE}4&dQF! z1YuZ^Z)Je_yko9=uOjzPc1%v+!!B%?a=0OQ7)sSSMy_EvSB-k-^{Aaj$8xs1ww2$) zM`x3o!y?}elM>h1&CVYZ91rIYQJ@AR$sHC*3ix0aR7!F^BO>=CXU&6Z5+%L>zbPyf9VnX z8Z$RTUy}Hkx2$o1EK5G?dxzp;A~Tf`>#}Tx!_d(^1l2#^zsy_|ThUt7PJT{zKZKz6 z;agUTrzM2UUeCSzNF~226>El9+pF03Z#_vm=Ym;KsvzlE`s80!RoFL)1q=OKvW;PR zOKQVhi;~GFrPkAqyadP{-9;aipqxKnkiLJ%ofP>Ya@3q@?{{G3Z%jgEPG!VTum1cz z)d(jheKb8yG_^1;sFqXug!dyy6wkitk^l9@rpX?QQuu=3lvXh3C?-O!SO9-)epB9; zaU0;h3JuZpNml?dK!UhSoncvFS!eb!LU*|r>diC-!ynI{4ZBRg2} z5RraAO}b=#wPT{pL)@j_)Qc!1O<0)J5VmapW4TYfuFEnA9{I0B{PnolOUH)X)XC<5 zJJm5cwcI{b(ES9lpWo$cGP1N+n3m56ZaWw93-+Kty(`I|Z<0Jiihq0}vi&mzU6}!x zKZN1L%Z1{riaOqMlBGj?N51Q5YBOXfzYqbti+PW50fT?DO>LbV zS2J>Kil6KSEcbWv9+TRPoY<7^^d}HXHXvr^tmrq2)?(J)=k*%to=~IZBR6a9uh@4f z&!<(1jVi+Z${A8(_3D>H<@YxUS>(&GJkPX~=KRb&N38%)A~AOBIGOI~Q|*t*Ndj^f z>%GfW+I!Np72sx6E#-zsuQINjtp82Ilr~3zqXN(T=W2cVN_S(pjhW;3&lhcpOPs15 zV7-1K1-KW8oO&AKJ)Eyt9Q1bsALtU~8WbEYw^BFs>F|@e{J#q5qtCCw)C7nmhPRVb zH-wANLWQXsJMJ33qz;RLB4mm5asAo)L}wb2Iy8h-x~2k*_a>2KvYqeFz2t?B0;UV(UGjb~3Moz~&wZ$ePG zfzy$yb|45tSYkQkuP7-Pces$*3fxOkcup`~u|F!RITL;hd{iFB@@tTmFHqfAk_Gno z+IxIfK5)k@ycmU}l!VL$R_&haOu4f~@x;WwI@0S%xF66yMwy98Hi6vghYpR3x6}o|DNw46+dgVL$yOov8_I!1 z?O+}jyuziKjJR#&rSr8g(A)ZdoFl~!S&vvK-Ms;*GuG29UJJ{MT^Qcr$j_#(tKIs< znb2U%gQPw&4aA5%U8ZY2sw`u(^%$v;4ZVO|>;!aO{;rozy|U09kqIR)V8l^07(!1y>s0to zTCkW}2Pu8@BaKp}#b=m}N08O;hhm3zHFn!s>~bKnA#m`5vkSt#qWfwa+aT%tqyL)M zF+p$Rac(ld*@5b-UAKnbG61ynlEW={^8NJpEj@ZZ_pzN2u_(SgpiLSvO8u%=u1@GtMo}l+r9qY^W)1G4RY=p+EBdHq`ju;x^wT9@A%zyl1qQG~ zqXw@FIYaj)V4Yc(VMZYzmEV;VvEvhguW7~RdDLapLu_TXp~a0ENUO zsCFiN8WG!3p-y|@@><;ymFv_Q1U1|fYaKBWZ*Bldd4DrPqrWhKp%-va{+y%(yiq+m zlf~nZByY0XYr3TN8c5e+*iqlD?o&9G*d^waytLw0#j5Tf2^*Ydk9_h~-ya$p%0922 zwCTHqb3VRr5l%(v@mc-f6W{u2QTi-4KBy!AE7y#^!N6yK|lrM<$UZ zLHK3J8e5KPbI8oW(6osnHOuqK)aOD|sM+S$`Mr+Va!0z0+UsSt#LbXYIo|Y_^3M2U z8v;i~fnvoDu;5o0m`(bd7qn(i7E537R0%XNlQEmwK_e`g*-#jHz(W^P`b{GLoYRvG zVC@HD-uHVSXscQT#C%H=M~DxSL82ahTVUl?B21tNmhON!OhtT-_0bMBOd|zi9%Nd~ z4Axz$zkDZ-0j-DhMXt2rCp2nTCvk>4)^8TGT{-t`CuvnA;KdyEKc~{D*}WbEhpw<+ zGBdA=5DR4F@Ds3{tE>?II@D^hSC#8QK7_t6%XAw4eDD?q5^HFR2x}aFhM+T;og}OO zO3o2VbjG|>)vcETm(7)Ejein=E!PY;kUr2c{l|m-Qq1CrAN7V#$F}aQtc=u}+jAtN zHR@eW9?rFI@EZ4-;iPaWT(nM?yi@J^~QtP z=BQ#~4IY{?_6`KQ3ZID?_&{3%zQri0--pLDb1Q9Xy2OndTDVh#bGe1^%9N9iCZhjG zgV@{L;mYh&2F*Qvb$On{6=gv?&iA1e&Ub2XQY&ls;F0(Uw%qo;5~Q9VB&KwPT6#$q z|3fok@i0P6i6@D|^0} zj|rno>Tt}KNTquit_8`N5Xdu^!loXa;q zC!;J|)ht`ecjJD@n*&w;-%>|<+~DD7Zy5Pk1WPg99hw7T!6@+)O>k!rwV@+Z%M^%5 z5NZMdf(V!FD7!HJOQ=1wn=EAf4KcIJTHD%df=tO%)3XF0uclBeJS+Sc{YZ(gE@NmO zb9fn1Gu{lf=$QgR_^>hh(SXDq?-#K^dq8X%OLmqlvj=vZvo(rPE&gw?&do9`AN0Mq zX`Hyc*}&t-z^O5W021G!rlsP)!0VNcAEc_H%Btt_EaKNw(u~q>HSPLxaam8lx(u!s z^R{ya1skow2UsbaGCscjxx^cUaHuFYtgkkidhFk-lJn^OfjwS!UMr9sB_hfKl^FqZSSOQpTtU5TM~||zfe4GWYd8{$JLQIrX~&{_$eSBO zpmSI;efrL4rym;=Wne_rbJC7FX6ndF*c+c$*Ot^^j3NPV=m42yY06o)TlVaiJ(f*Z0gMS1h9XKv9x>$t zKZ#leDHj7P@iMYdXWIAvholBaAsi0kq$#xLEo_`yh3>iEMVb?YQ)a0p^ms6FF?bd zRW+}|-fr}|K#7aIV(S*U=by+!KlsoS1nbdsjkKO04iZW6P(jl=W%fk>D?+v~p$5iz zWlDBWHf`z>>Pzka>usJ&N7Y z%*^mrluNu5Qd?FPxPp%^0HsV~U2xV+%1t(t&~c|Fk}-HV-7eFI&Kiee$v8#{$^I8M zEvyYWe06z?pH?E(v5}=o3h^B6{(5MAT+JeKb+!;^lY*zp5^c%QF!=Eb$ycRO*xP@7 zEM#yk!u8ODFW}zt#X?fXf*9S4dbjc`rF3%j683VWa9)coeD3jIoki9fF3FVr; zg;13c#8`IZs6mrFil(is|D}w$B!8{; zFx+f$QS@}^%Lw*!Hy@dUCZDShk4I_WysdS4w`i(TZrwpP)Pe197F)}oj*+h`G%97J z_E%=X1uZ}Fq@znqf%cpVxG(=76azfohWCbf%=}(}q7zAaXjogR!bw&hU^HNHFyf{Z zZzwf&cQsQ&%B5^6s;^I-M z##80+3|TSzpz5U<0M4nvax6>l!sFL;LUl>9f3v6LQU))@=C;50IU)^9PwUg*9S1F^ zvFvf6Qi4apy!c$75;0#7wS#^;WN0aE!o;BQ<%!l^yHc@{86*pj;3drHyN*VFa}ZdR zfsx)@-?+E28b7TM<4q#T{C=w?&^jH(X5Ibi`lesrqVrIqzlVz%({CkGp(cN75YFi_ z$((^Gi8IH}bS@m}{L2w^y0K<3yE$*U{`aTveWA8&VxQ44^Is0oGI@STCm)hT!!Ac} zBR3J1c%*7N*9?^BIO*8+&oaAT4VpJ~WNQk~TfX4I)Cdb|Ae~mn?XP1ha3%SWz78T>LZhhjNo}o8%OB)d)9O2q*f9d z?PX1`5ul6SlGSgRGKGUOv@tBjoY#v<{gk4m&pfDWVvRg*N$Xic#nlp(k?3#ZmNei) z*a%XXN%hxX2YxSOp}k+9sfu%0N>TqR-)>-R9Nm1#AJu~!0wU%7vU?l&g%;hefel5R zdqb(|=H9mY8{pV*gJWLb)J4H@^uZQezNX`O_8g?J5NECs5wcTWdx1iSe6ncy6T@oqlyp@5yLTZh8jIt|0)!yn=?XI`GH z=i*eOXDUn&t}`X6!L^&{=R)&qVA+uVTqh0nCe0)0+i1mSJgSfBfGz>`0(r$nK`((% z#%`2WSxVP5NfSJqQH^@0?Ew$JrB|>rZqMd z_lS90dh+}9!Msr!L_tEFE4mwF?_>$tLcC@(jAGPG@W~i5qtB(d3QrO)>v_HWes0P7 zzEol2u(TO-`Jl_PcTQK-ypRKH#TkKf7Tn-k#d36h|7}wjm!#fgc8J*x#G7#m)s*5S zvc4pG(gl;H%|ecs1S%?JN7{cheA($17tl5XpDp?-GfRc7Z32N>W>_Fg*Y*LI##cTK zqa%dJfeoLhxm8rS*@+)l6QStw9Ul6z6xUwEI5#Q(@~tiRKn z-%70J9Ey9&)vL=Eq0I1r3FkA8O=dZgkHch#~!vl}s$BDgT zMQZWFG-JEWcN5-^cbh%MwTR;NRdlBj@xOSPCB~TrlCjTRn2&*dR0wQ{jMbVrfR`X) z1QE&lSsai)#JC^S)Ob+STK01-7$ed?)v_U8<=7ZM%rLV%I0H4Z}SO5Kzsr0FtLd$sG zPn6iaG)HoVwlv>QM1%F^)w~nVZ0;NizRDU45$YjFWC@68lQ!N1K?6pFp%IXeKLv+$ zRo!Wtr8|weO4GXvCmFOh0U0app zskj!#aOnwsDk=KZA}if_LAEge`*yb=fu17FGqSs$-%EnRFq+pC8#S@Qp~Y_$SY$H+ zE~h386vdz>Nv8)l)3a=Mzs-=LDz~0y87=VzV~6fJ($7^pFzs7N9Slw~IMSn_zv4_x z@U=rk+}}pxbN=D2=hb^9=FoTBR@<7H@UsyV0kGM@ZY@`g3(<|t`KxIKchWD@;aQUf^$2U!)8{$shourwJF4ui5cX(XB&l@_vOjT;g}lM$ z7uySWYMuM(p)(045n>Y1kB$0wkXcclkvSA(xCRtMZpq!QkirAo2bM;Qev4*GIzja% zUrpP7iX-_V1U_cf#S73BJ&ds?Q!}d0zVt3;x+uo^woEZ-E{~8ZiAByZvo5 z^ms$je0i*5GfM+DiUhf=2t9EmpMR7k#X?D)m^~ZTja>p^mSVW70rM^fFTQd}u^i%1l} ztRe;5ywB1WHtykegY(!bk8;ypKJPwR{bgd!aw_&LPUl>#xwoLNvCouV)>eVDMC8q3 zeO*?@=B$00*NDh77811iCo6k2zJ39}!j`7Kq+&}W{&;big!Kc~IRVnY0OP3BpvC?VYQl4osj<+ZYz2?cGAd`WV)ias2YJm0eKpSp zhyNDuMO0z*^QI%oH6VJJW>+}rXugajHYLi0=EOX_IB}HK{RRri?Dg-^_`-pT>(5zt zBL!hL2pjw$ci5P5sp2_*%1ar-(@#U+xS${5?Q&L18WvLh>IC!mjn!Y)=6UTo{r@;$ zTN8AqE>yd5e66awHr?oZWqc+izH*&wWM?A0_-@P&qr!z==~z1HDchEu2*Z`ZJ*ET>c)bTh zGmRY@#v9xsjM1@$WMY>(ezEVpl*jn>rFAR77&+M1r%xi!-*}@{j}Asi2;eoK2^Zz` zocj2MBiK8)8SdK97+W@G!X_Jz!nL{t!Y&e_9}VVi4Tu4BWxe0tnE$}N6^3&P6U#!JP^*u&^cIlaulbQJ>B%}4UZ2s1 zwKF*MvLPUr1A>Oxci5r&jecMG*o8Hs`C|P21rX(h#LVLD=I-B&Oh0H{s&|^KaF5hj z3~7HHcA|D(s^%SInrEfvIXysrNsc*R)mcv#d&yv9{gz3|yO`8TS2$}-LRN0%_yu5h z(pqk3d5J8G#~Y;NV*FkPcla*$Kdu@|b+-l^)amT^R}4kxB3tQakAGi*?*k!=$ocfM zZ0|s(E=C!w=?BgiVq{cZgQWN4sWo2uHJW1!&xDBc)(4NW0b`sX_Okde;z^3;#iktL z)UYmkmT&<0@)g(9M`g5s+HZUX-F#UF{2s#C6c=Av33{>DqtEX_$U3$7vV;$u`>I_Q zEpeP|@KW>$i6hzE*L2m9n)(qiH&Te_CBS&*+wVlq7QRz0NJ~o-@hxjiky)lyx1>^P zP#jkKO{n^N8apbmA z|HUX~N&JVi*zE3Ry>HEPD_a+a3n&ll!XIVx6Ei1)#l5s>zz=&TRM}Xd0j4rgHh54D zfq{d7?_5?6$Ur*K@1lhNH6!TdzISu8;#3>P?QM5dFBN%tTZ0APGZe2>D}aXLjs_|{ z68GR1FI>2j!M}YHcDYiX@hFEY3uSURB7QQAry2RcK`CS;gj~GLWs`zo*^9#}7R;~$ zWu$oyD1Ytw!wOKcbSH*u>YpcS>L|OyNjfm392?=P&a37(Hp9~4$D}_mDuv8vFkH`H z{4f}=a1@TKFNsK{Cql09v`e)>`*bm53K0*nF0XyPsNmmf!1dzR#?yJ5wZzQuMQpb_Q!QVb2-Y@N`>y)ihp>i-2REirTAt{gIa1R63ORs}ZThJ$zm^(CAA2eatZXx+n{kqv7nJIMoAY za1l9vwkItT@u-W}+z;(em~xQ!A9BQsN{Nu@d1&7?e``fWX>hBAY{}lkNeo)^PW~?YuAk@q)4J!{82Z^A~%FbyRF82yKhM!K>DRwbH4ytRlGiF z%8b_2tuBB-uDPymj~_pmKn@NgTTfDaN>rc=GN@0y)(@>L)YD{dQSITk-lo!pnoa|( zmLWU(tlOw))#DqHCJlbF*6+k0>wd|Y|EfhD<5b#zCh2LDHGcA~78@!ughfh(F#Mk~lR? zLQLu(@-kY>bB4h|`+ISOz2voImN+!HssrAhBq!FQk?8)9w=R!fZP4JqYp+d{sVkKO zo4K#j&Pb=^4^Gnwa;~$AYiR{Eo^C#`o~)-(sR(-i<2Zb2`^^I~o*tD`cRR9>glb%0 zcoD9w=ctzJ_yL`3U=;%-AV`Dc^W4&f)O$J+sH;C zd17lvB-^3r>f*)$=#?{)%yQ7y7+b%k`bL)&;HqyFN$PEuU&Q_%++jN6eVr~hJ2 znDDh5IeGGp9ThQic!&FT+EBch5es%(*u-?HayHuYbZgs{*``}97`jH75j?Z?zOhj4 zblUT`IO=H&eIPfLy2z!?F3B?prR<+rPrTBBrHNRKc6kAn4MKISl(8*C-L zSY8*v(Y8G(vmf4ipT!{GS@1;t$4m0kr|8 z#IWeB+-uzE`&9ucbEyiMiS&FuTuqwNNV3$@e#pZhShy(LWUD_8!5M_w%bX&`c+Fn8 z(|}j{t~Uk0&vLZ1XRDU;pg=-9CHJe-SrG^7aL@R-&aj~*nKb(D+D{g9ccQ(cz40;peEUzBxF(K zCE1+4Kl^acBstVS&T|Bwgy$6Gg@h$PYdXCOEYQSHwlB^RMF%^pC*piG<=~`zi+ohr zhT@3X$Sx!mXAAG>$U#v$L?th=)Hy7|DnmR`FFm|~?XKuLbneP=};>mc2 zj#2RvpuHSK#Kt6ZYfNx|;5G&oSCGB9;UY5Z$BOh{7ZOsx;5~9u6B0I~vKkCN7Vp(6yxlSm4o=K%L z$3B-pSZ?;&?T?sq%go_sF605jV5;)S)1H`|1?k3h(k=_0-gL#xB_RMv+v_S5ThK8O zY5Xhcw*6ithOa&A9qv0t^$4{#H2Sykpg~SdiQm4V?cE?bF>}l(!~CJy7vZaZdSv)^ z2u0Y}dA|m{=%dN#%oz9HQyG%RdOAw{OP}8K z`(>b{7b!>2MfyXTbM*9NszyEy=^(O0H$EC!IY3BrM=@sf(i zupwk%EV)0+$#Ncb`bczgG*+5()4f8I%xJ?%7S(GU#pg>^7eOXnVUwcGa4X-E7irc2 z%QGNYnK_*@ycjeup~Y%<4XEVlEmh*k41PXf#q;U$j8(9^*Qz;OmX8xsaui`lw2>!Y zS#Pw0JlCQN-oYc_n;*&cHKEq%daRvTLKO_mVLbcbxVPA1+u}BdB?#)XLY9>$H7=(4 zbzo@fh~nAH?Zpy$uVvSRb3Qd!x9e(G`~l1Y9|BskqP{d1J^)CeaZL~pMF7{jvWdJ_ zU$yq*E-4oJsGqE}RDb_`?$#SD`gH8e_H^bRyMd)y%GAV(+{wEVtp3I8D>GaryhnA} z#)Lr*2LN#=beZQ8*%L@#S$8SF`l*~3#wcS=`3zEM&lfb38+sthH&J;xf(MJ+ML#E^Dnn=4>Y|(gO?Qa;g zux^GP>!Ae|I&hOU9Zd!F5CD>$@FbHY`so#E{lMjUlr%=g{W!!-TVBzBbesL)P_1 zb(7wJZBxu1lQHtSg6Da?j1wDkH2;+E{&fI!OQWE`oyu}rUJL9u5Q--%PD`Rroc_}o z!(NEBpZ`ap39cLP*T}2rk$=RHHQbnl`gSxozo`g zsa{_N(ZrycjzMpo$PeZ`5p6nJfFaW3^~S=FmvSKDJbs^tB>tc*j7>5ye>W~y-rS3o zlKuDC>ZobXF_-368ayhXmo{Tg_W5OGf^g$sM&zyzJEgF4E=TtlYt0(cQ#U6`%vS{T z_#;yUy!Z@R4RBH+ALgi}SJrf>J{t@yQ3(b-kqv+~+;8NgfNCA^;^loJuC$O`fA$*( z@6YPUc8`sq%%)LNl-|tqRbt%?jlsIl0Rs#IT>(c#>xEZttw$x=+6bMP?4v&U)?15> zt*)Aflx*|EhZfVoXhmmcR?esH2Q$E5k<8PtI^*W%@wgpovahYEAl6|}BRx->v3#)f zlj-!j!>~itjhOkKMc&#%T3fyT>jv>^ zxez$X9g)E2p>Vcjt`4aZ9|WbhC!?M{X5Q3P|v^v#ex^`E0xflOTfFd$#-L=9mh5l~F*SO$VX1cou{v+$LkE7)rz| zRSX=(8YwkaCcdo**(wao(=>~EJ+W^7Nmp9n$yp9ERY>gg!O2|eWXCDqU9IimzOMl7 z7X8b-{OxDtxZf#C61DzEtE(x?_*EsE(vF%-<*K?2OU#*2 zWq%*rCzK=bFhUOgD34?4U2=auQ*wPtQikp>WPP@&^!9Az3c*`Jqvc5x!-Z0i^bn)D zbdoC(Bf82EXx2VZC}xF`5`?F{>#37`8E^e>J(0^A+UK>Q`ay}H!!!Pi)`88Havr?U zw6o)pnefurz(i7&j|NvJ#VIfZ{uJbkA@YBw!Us%I7}aL;nliJE@mf}il~O>KsV><* zKCQr<^wM>T@x?tVv9Dnb2n%CYn;aU)xpaQ=_PQq|uL>Q6J{1tf?^2r!HE z`%Ek9=Q*8PLaMEoS07KUdy^6XBn1=6*pvh`&JgVeA$VW)<9->x#2@mYX60=l?}1$P z(p)kM^=$jTxLA294WHF41)D~d>A+ofx>E>sTNu`!?IGPIf8u260p!$Yus@}D&goD2 zu&-HOZFg2N@8U4w(J`=XOK;qlp+Js2MPB6Z00}uuJg|qX1q>`C>(jKt*6mqp`1-DX zS)J*(1oLWIEI|}D=Qqh0oxr-U*NCQVM>dX23cZo)p$)oAwC>Xv zqP2}p+{7|5x?VMJsXnhF#TtQO)M~YQ^)7M6@OyXG8Q=x4YIT;(n-0>?4H#C?#AMBJ zIyZ&|DC&oZ%D|d;Zahu=@I-5~Y~U!-Z=C}R08B=h64`;+K?1PQx>#>19F46iI zRk(!Tb~#tSDGnIG!uRqYZNc!$Au?6%kJOWh#~We!OWsrs*H^f|U*zQIz0LwM`h{^o~%AY4xlzqbq5&ry$|_e6D$3Wuyb z#HU;5Un+xCfo=u|CHxQW1SBXUZ|Y~g!#L@@CD|vV(|kJ+idOak9 z5m6%~Jtlj6;)oQ3z{WFZRy{Nj~C&wgg-;hFa6}8d6+{sm+ zAMValfb(ftfwuK*B~c+bg7s6NKJCGntaP)>LG=N*m4sJoVNNtCMSiNj+zWi(&h0U; zi|8WwW|)-%jb79IE1VVDK9)*f2;bB5a};hTU=_;iOt%jgF9`WAaF9& z{?BfrUSC3=sXi$yQuxS{$*Y>6p&0TQqB^G{HZ^4HE?P@Lg2!6tM-JahjeZ}RFzL15 zc^VV>60(`$iHMH33dty;G&UF7Ww%j%{Uqc_mY3rNULav6jJpjvp<_=XfX1QMq8;6$ zF{7pVvS}v+v+q~9tS$_Z@&2CU={g*}R@0Jf zDh(R42&!ML@Y6CV>wNzG`YtoJ5aF%2kEXr=9gB5u(JZDdvF7wq$TIt-o>O1ye87g} zO_*eZ!N)tga$YTKpTrjPC^gQ@Ma}j{CmP5GM@Wa|!A{>x$4jp4wvXYGB~X#a;3lTG z8oU~OWuv`1>?nu2FL6KOqJCzxxBbcT_auWvJdRT?Pl^u4czv8I@#@e53Et=g=GgW*Z5iGh-Y1i{!(T z%-W!`FW-cWa5J%C0u3%9<9L-Ork4TF?}1#|S7dE*dNWA3ZMpckAYpqtZKQblwA^Z3 z+?ruJI63&_#-B$+I*vcM^MQfTnQ^KowIaS%n%+l7wNuIMwxd19t7J0RV7Wvj3qQ-g8NGu&um@e5X# zS-B07tFIg+h&yHRhxB8PsLuHKj@=zQQ!U(We@V>E}nhVk7F;h?b2emzM_mCl@wmTYfUu$Z~V!hXuChR%|KK;**#*|o8d zlLphQcRZnXWCae$J0RDNWut_P=R7XU&3`HMeZYDdBy-8_^GswRv>xtijs3jmsx7%0Fl2lofUEi?=!k{-j8 zqG{#Tp*Gdb_SmMls%#7Q8PA~iwLQnf#+WP~$6^homht)2m}ud-hhSQ793Qz{zD$|q zxyVp8-_3gJ+VoBD^Xjg7I6dA74MFaH5dCP1*QUw)j^sNtvD6tH%HyW8rlKqp_vy48 zOI-wim-`@=U1yVj&}7?a-wixO_6^zKo@;Ru;#7VTp62k{16p!S*Fw}k@Vu#m5UF^DZ~X!Ty`!v3R{gf%ohJlWp~a@rF!tAn9reHY$972<-USc zk!U=7(`d7&4)sNWgsx$S9e0X(y424zBhwdHBy%{U!gNMB!~wK3Yq|A@1e5Ti(%s(N zKnc@tbwA%GQbF1diW$qVa6(TYzZWuT)@;s8SL)z?>%W#O1h8uUPdV;SS|1~#VphxWv&AMmsD7CbbI$x7P>)q@t zhbhZFO-tn>+#%v`-8b>R-p3@uv)!kjy(!fmaTsujbHa&cmy z5fOZAwNZ;KSoh4UR*9`&EbUnN6IRYc>}8k3g>RmOBVxOD&et+OQB{a8IqYfZ(%!}% zCSF3PSdoqq^6ROP6SKc6JR7M!)L(w4e_g+6>iM?O(;r_g&mUp4dTL{|Zj*okp87m=uU}kih-jWwKB4)C|$w_=F^826hxE^4oFAV`vjK})$aT&0^NFmkuivfM&b|Am&r598{(wMhyF=8sFdjdzi)35%M5KPLP#EW1<_BRv zXZJ#ShbO8xV9((}uML^nE@Mr@*>ZT@OZn|`9@tHmN#hfzUYq)zr)F~P49S|wzMS$) z=;rQY-n`+FM$h94)Ds-H&$u!)$Gy5&@6u#oiSe%tKc;;DArHzaf=^~yS(?*UbhDqr zR2GgBiccgL+Va`D9e_f~_LKZ=F0O;mIUqFsqthAfN2foQ6-cz&fnHZ)=e@0gb-*q; zeljb~N;2C&aQ!6XZ9MCVnwQW+^)Mw(R8*ghaH7Y-Pa8+70D5jG0gy%Oc*b0p_W^%H75IOkqkOfGbr8U{;I zq>GZSH~jjY5Vy`vPl=Y?PzeiA7#h-$C5@kYhl?1OfA;Sv*Raq?Do}=jOk-Lmg zWSvZ9IU=;c)hsFh$+aD_t7>G4tD$gL0dN0f&@NqJY@sD42<|-eUaF+cz*0eQ>Gi)o zkp<))FY`w`3A~vR5L4+-qOMjDjHUnp65H&xVnLF zZmN~i)NmBJwKc_A~N)m|T9gi~WW=@R;pEbZp$Wr2C)!xP%C&Sv3`h3ou(h1;ys z`VC`V{WSL`!t-+!Vw)BqbwJ!x>JrPjc;@~wYwH@CW2&3Kpa)4jzK-df={@vV z`lKQSK>2J&qqx3Av7UR0EX+-LM2pp+tS$1!oxm_hrN!@--fcp)aCJm-K6mF?+h{i( zyCkm&I*P>-QSQOYg^3+rOagsgMh#r5zfv!wrTZE4fgeUFd`?(eB)!yf{Ux0Uz?-ALP z&K!KNL8pA()a=;q!_ZBsMOv-G&%|FR*cJ(~9{`?|HkRemD+MYs8_-JdkwCpKF;=6` zth+tQlD1U;B~+k+mml1u|BOYz%_<>_+9kuAt(<7=%WAVBAtC0G54RP4ZpBXY8S!iCmDzVtU(|8aOCe^oqQLVXDoBCim1PPjcbh4wT zf(FhD=|2ymDA^z+jiH*bF*7E88(b}uA0Xdmlk$hlxHf=n0 zl~t>~5;o^Sl!u?!EiVx6wwjmDTajUUb4G^AVeidtId>(f{Lk03NYrD*nf!G!Ifm3G zbCy%y7~p(R`+-byX=4nI&T={*PN7xNqP6XmxmYX`u68*)o26`}d36++#D`DXzz8`; zruz(UG|#U_dkrtM>oE9vrzo`sk|GlIAKV+^)t3%viRAX2XXyUKOA+W=Ef>vY>uheu*qds&l-r_fsvL1J^K#Nooiw5vDryg%8H+B{vvZ*N}EtdPDXnFOW}s=`JS zn%@bogA`n0`uM+T1UgaoWp(qY&x-kHo>zTH&=mX8SQ|N%F!>1tSA~xy8V=j{EAw4& z_zgV=;}tzupM3@rS1E`P!&%x}2Fps17rqS6qm>y9iam&7-&#%ck!duyck21O-d?#= zPftamWaUX2ch4Yw)$j(IfvqQ<-d41nui!@?cq(~EqL>>Xyz8WUAR2W5(>jGEpb?T*aNiTdajyh}a#OT%Ujv1FM zd5B|}bS^kG8kXFOdo9KF&q(l5QT`RZa62BC3zw@0!A2$4JkTzoJ+Bo5`0vkB?xQ0n zqLzj~p`J!Z7*hO1`%3I)$qn?c-^^4>!~IgVY7Hfq^*L&HpX}@D ze>eu(#GPaQ+UH>n2d%NY!0RtLGDni=G%ON|~648FMp8 zx3T22uetuAhA{9Flwa@R6}Ng8E&#QBX{37sj}pzOtth{PvL&<#Klc40Qt9iix7}1S zt+={G$GX*eRBQQLtk}z?G0QdY&k_}9fY?=CdYmCzMjA__f8kabs4*Ie$gEO)hbIbl z?;b+p!FLgCve}?7Lmz`p;Ci+fN{A643r!#((}42Fz`t%kQpBwhWn4DW@WC-)Ukq_+ z+T{sU{ZzmR*3EOPEGq_=ow9<+q42|QrH7ZpUn2E~CLBuGSR_yOD(fVC--NHO*rHwf z{B%Hh%&ERgeNho;lF*=G=fjfXAYfDm68gUIGHml^=>c3(Df<}pb6v_Bq~ccsHkX_BVynDk79`#WecokKAu`iL&U0j5zUR9@0SccJ&b}Rn zrcWf2Qxcoq;aP9X@aw}6a+*h=V1mn`v-GZeCCHJjmZDW^ua)gqtOGe*!~?m? zvHZcxUaD;ogEl0@v$)z2>)w)>E^Fd<+xaY_7D<7Z@r=~%ZMn(anh#hi9gubM;J7|7WNDF^p(3J$#vk;txd>&N%$!33^3a#K?zpKfGtUz1n2j3TUUVSme=Ly3ksio+ z2(ex-+ztoL?*>S^-ii3YB#s8f*PnSyu6EnG*bHl+dsmId=Fji?Q=>-<=!sjb@2BZL zuPgPWCjA`qs`H^I9*N{gwhx0C_;PwUM!^y`4(g?=3QR-#LU=4v$1}wIo_UH*De7d= zihHaTC5P}88~ovwT@z40){;G6v*hgk$fHrCI@8jz&WEGYyOYb}Vv#elE?}9r=KEDw zB{~Otf`yf7L?GQO?r^X(p{lm)r9eKuNHvGkvRp4pn)&@W zJEJ?>_=i+O%jn8rX;9p+s)aU_d}r2dE*J8ygqDf9TK0?;V@ij7`h;AVPV=$@W$VXQ zy}f}uvt{p>KA$S)C$RSR5bs~!w>4cDW-NGFPF$q9mPTeDl>LIOkZ+{6$@vc<$;ptf zMD!u!zP}2MxhtJt_ayzE z9eW}Yi4&B?YiPen&o~r<(r2}|s#fJ;blP*LfC*QzvLyGZj%7&fO+CXkcQcgsnqT@P z`xIuC=(Uz^r7j!o~4`Jn;jYq|mp_zG% zT*XJ>Fbzf;t0bnO3jZHIw>|=4lR5Q~w96xFICn)env8gR;x-;G(ckxLh-Bp`sIL!9 zcRPFi?Y&JE1+D&KTzVxKZkm=zIc#Xab6}rHso-#dQ|c<6F*J)%(RVn6GvgD06t*mD z2_rf4>4@(<3*{17^kLXC(V|S4bX<((+kY0Yaw<8R`=@r*cwNh!)hxu$*g?$*?bKhw zON{3Cu5H+-TR5Z^$kpnq1jJjGMr>Z2@;!&TThUlb5g#qp=uxW=i%gpgx~$GrEpuba z$F7#XJkUBfo)_+oc2I|)zPhg6JZlJ|y(}{j@qd5Qpl&+VH(Qi00c{i{$^`ldKC%LR z+zTa-nAp<sHLxa``iJ*5`k7SSC;on2zjY{;${hugi7AT<+eb=hnY@^XI)K>VVUt z1HAvdJ^yj+7p>%ae?h=&a1^55NqWo3}rjgbm9m;5(>^(AIL`k!55P0#Uvd#1+! zKL-S@-2by%Q=xP6|2?3!J<#w>RX@AFJQoo`>+^mCnW}n1Z%@YmcvSz4wD1r>m^JSv z%@+@8U;<7(=XTluvjKrygBL9a$d>>2I09_cc}xc5zaL5VR{+XfAopj-^epn<47HRV z4-Ac_KSzK+^WVI^dKawLt1O-b|K<_KkYfhM=OE9@|9eE)3u1)`dK@Z#@K06 zQvcFmXe*kY!`fgS(#%4lwFj1^i*?|G*32>l|KiXlhE>vaekN3yES@}~exGSB%V%^?n^92o~?Cds8R?7l~%cA>Qcn9z;FA&0 zDL2o;?JdJ&?jqoarnZ{>?(xzRY{C+M_$_vty!d7arCiZdspobP2*XTDkNB|uz|LUj z`JiBd*aVuY1wV_Eog${p0wPw<(7Vr9aAkmdGlF$GV$F8H{Sflkc{$-{P~aB z5a%SxhJZJ0NthyK>=`F_7eD-^iHh}m)}GT_rZ{^9R%ef0y^viB6s={jr|(5C6$7&q z@beG`V`~KXd1F1AKJhsVmlol<3+FqP-nah5gL3aN`KOx)da>c}#Dms=SdC9h8a+@q z{bBLTX3BQSfY6)n<0&(0=jwW8llRbd#hSCuMYyD#inSzL&nY$OL0Ra=Q{)0u`1%5yUE$YA! zhj(7=zJFcvIro>(aQFO?rTyUb?gjYDb`%Y`cAy94Z5pKYJfHf3JrhHC{q2lkksxp0 z;tVW@Zh2Ji+)xK7bmwvhE+#OC`HCPC`03zEremL|wOXsQLW!wLIc&zi9 zlpINMjC}*X@^~naEFVkCG&eY;XKcGHS#B%>I4^(-NN3M84>=xzl#$U~r3Ttp3d~{e zRBn_FaeEx!8@x!v5?g@QiIyTrglKs;n7$vdg3{)}MzZ?GZ9;mCj?G0v?;Z(~JZk~) zimeET;?$kq-`3l*%M`kB!Oomrt>C@}U&nfXOqP>av~tB}_0Zv;BZTb(NLMw9(83TV zp#yzy#a8s^lXfwK)#v$gT5uyD_M?KOutaEY8ZVXW>`m&ng5p)e7+|6=-$>_pTa|9p zZz9EI3oR$2mLtcFDEtX{rFt_YL+j1bsMPs?roo_FN3Li_bnX+J&r<~FWX-=TXcRkULlfLr@B z;F&89SBSB*3WahHjGU!Ex_6#>a}7MTbuc)*EBEQzL6>&dm5szeRHH@{t+)*&-JG2f z9IPX#U7ZPB)B5sS7iPtwY~?b<4LR#)rUH`@=TnphC-& zSW5>;7VcOv2Ogg~#f5$P%RjP1UC1v?sBRLhV#Kryw4;5LW*-PdY(Y52=*p*0Est0aktCAR`H%X7R>hJHTgrY@h|6q32JT*x)L7BR^?+( zBqrF2-mTRJ{W`0o6vL7=!}u#euEFw2Wv&A7_+nAy{O%xmzXE0fm4^*cJdE^v(fXV2 zBkWm(`ARFp_g>`Mn&=OuV(B78454!}9iao3S0%O<*mH@+ruRwq-)5)o;<>63Yj^|!_m)0wr(P{5`4A7N zDc=ltb*2Q=;Rokoo94NKrTWX%Nz(2}5)*X3&0*L0V*<*tms1Tdchgjs?Vf@8*K)?3 zl~>VZnA-y;;C6@-q3D)-_PsE4P2zklT_JxG#wHEi6T6d4bH+2Mt8PKkUE|Jr9fuhG zcrj$`On47-ceA1et6ssDjOa0uUh})}_mGqow>DoV_sb3~8>UotpG}?XhF0>gOHGTp z?+BnO61tDGF6P}sD*Z>)>u_uZb>`|h^D94oK2#kM&!iA9D-5dW2#*%LL1Gi8dVx4q zl2}riWx2W=q-SDM{YKi%@?c{cwkw85g8DAIS`L2{aD%)n+(Gtt4q~$4q)}-3z)V?a zEJLm?MhD6@{3MSDZ|sz{@X*UL91xJH@?k zeT_u+Y)SmDk+Osu?ua5DewmQcSsQS9Nx;Oo2(SRrQcMBlzZ?T$NrDa~lL;RttD&;# z_C<-BXzYRVTa$t_#!z^AW!>;$4>kz}(31IyYaWq=o++dyL*eg>zM+e67TNvxZDv{a#qm z%FtE#wzOH-K@5$?*%m~DuW^!DP zkH6l>`1GKG*$r=o(gBtnF=T}p!RR|vOnr?}0($J2Cdu}s)&Y;o`X;xd(dsjA0PaT$ z4m1GoBZtuT%u$YUQjPWkOl{;QPd zxYj(tnBpYd7`wa%I9Y1UCXT>J;ehWe>E&=>&Y}Bar2y^0q}bT0){j2`5-bCG;KL8b z)&}^uz~#=y##T(cYRZT-FvoC8-ziY|)!Y&A2bP$~dwcU964y`Upvk>h+Y((if<=3{ zwvu~a{e~ZXbW+fHqj~}C9;mh@x7~J^ah8pv7}r;2_5)I@>2j99?J%PPB|P;KkEw=F zw$5V>6WUKz#VV}zyN3M^3ttiuLa@JH^@SZxgoI!x>-ORFq>vHNs7tYLh$~eCpC2W% z7!8*QE&;wK)5~}pz_y?e>m)|3wu+A_LleD(?3E-j9(X~Mwa*blfldk z;w_mijNhaUGJJP#?}Dud>4VuWhe_KdF1-NrP*f1L>}yxhB*N!A=fv3=BcHod z+ue0qgST9DT5j*=FBw_tkR5+0x{J?{U$vSl*Hy&Za!=9@W7ZTop^y_{;QK`Gcvz_f z&s^8&jCf1K>}{9z-v?FvZ*&-_!HiwRP||Z(AYVPx`&=6#f2E}I`X)UtuI2H20hUczFkp zi}{RSOYZ7uJk|--;$j{9;LDV5mdH$xSS%~vGH!8e7e*w7DIP4GhIg(tjKS06=?BDo zL2)lOQ+G+TJKDFDt2b-*(H~;Al1K<9gX~D2LxlL`^c>UpBRG0W$Z$O>h2gt!!oGYE zRfI;cHUV)nhn$Haycx?TBlC)DfbX?jr*Y0j&AcIn2c4YCQ5YIF< zgx%TM7IbCyy15JCV?{Peh|c{ zi||WjC5>#+C|)0Y9qt_6GTRvV2uZ<;8K=I*eC5HC{OXGdRZhxXl-L zo>Q^N?*!ux)=}9nBMnEL`@sSk!DnS_^&zVcpqju3iF^??`cK^Ea7bTCKym`H((^ZP zOUp4;+>^5Pjq*zC!~F{ZcATvCKlJhQ=5ya5v&zPvk9^JV^_yK5>Qf zTjIhZJxRa8N+RmE#9_2FAOKU{KQLr~cm(zP7=gCrWn;AUcFs$>_3W4Q?8IeCo?Mpa znU(&lewX_00sxR~;~OK-L;n{PmtLEePsDgduqu8}f-_|ao!1K6G8_cC%&;WwOk1yTp;@!OOP{EEq5iO1J*KM&4^Bu-6qF0^XcW1A7-emN z3!As^>Z?;@l4GipqSEK9fS7xaK%m3pr{hGLh+ZOnzW(>yi4G~Vis6w~S;Pj_J-sAJ zKQGZ&6X%s|8J@UL6+r}VMHBq(LUFCqzhV?4PRW6bWKy(Je1`L&tRy2xd(aO?a*AE^^R!XuLBv==6(n;bWG}B-2E=a`?Ah{j5I~ zzsS_qsP~#(-*)}en)4%C>RQoLk`MP#A4zlMp$NJ>bpEA3wi{hUmh51p7xEB$sGul2RBge87^VXs+kfL+bBBmT{hJF8 zY=sm>`n%ez;&2tO>$Ne*^1HO0GD(cZh*t@Pz{8Xm=s}y~8V?`ypO+1bI?09eg5O^Y z+C~*#e9Zo0XE0u_kG>lloU&-!lA)17ZC@7qW6j|)Y=v@~E z;_HDSLh~FfYT%#7$pk|cw+f{V1!`2DJ(Gj(i}D8cL!5VQlvSYsz)NgbuSf%FZVAbD zb!Zmy!~GodO+;PEbRz^*jyQH)ZSDh{`L6dU=p+>z?P$nLlQB!L$NP*NV_`&!9P_Ue zC{1k`TD;*E*qPp79D9CxV0&IN>>bLh&Qtk!nNx1LxYsHl%fVC?m#2b4eAk3uL+W#q zAMI?T2ns=_HYcP$mD*I%X+4;hBi2OyTJ;*)hm;wj&_?&!nF?U{gskfmNA#}_foQRy z1CkjKx9(c9DpHX+4 zNx{Aq(KJ-YcnRQWb$ERe#W$A&!$so|$Uq6;leD8{CgD4$WJq&~wJ}QZdtW{^0w*FZ zhzDkKt-#n9E*q4H>6nYuqYRC$+<*U^#N1q9D_>r4#pb-$P#m?UjWF8~gQk)V-JqzV zBbNMG*Qv>hZD)Ez<4S|8M*;CXG$*_};jQrs%+7=73XI#rj; zgqrfh*;tn!&FShmw!Hh@o;CqtN>JF(u4iuh64Sl$u=Y+YypFqHFCq2Cv`EKD|5rkD z(~kPilb-rb^o(sP5$cIPHZ51qnf>BPb4#-R(*44RroyU$@>T@VvH-VD-`|5?b*SlcwSi&2!x5O<{ee%AN?C?ux!wxVO7u{+zD7SJtZRfNK() z%&tA!6;{~yz3!xq(2Slrq+0HR*V1~Fa2`zK3srIY*K6IM@AJ}ENca}$nwlABpb<=P zcosr`5c@A^7xQ9bONXqvzKh3-?Qm7@$<&h6*$r3Nvh%%#=-di<1#&-GubX;{)M<>D zJ{Fyt%z!?2Xrg=6%V?WDBLv5c|PM|51z445IYxiOqCcdY>emy-`W`~ML9rkoDI7!pyPwjdW z3+zfVfSrXUZYfdIT0UUvq`~3F7PsC6hhVGf{ z4aqLhj_uu7sfUkb-t~T&KSKkyJDVGYxK@tcxyU82;fTD+T(~4o%1vF|faO$H6$u0B zgE0Tv1OmA;L-7SAd``bk6eGD*X6Pu$dkPTd2@`BT0L3Oy4*gtM;A5buvHV@RY10H< zL_#f)R}}ZUmr00QA^4#AZC$lpYX0RRZ=iE*Fh8l5^ok%*o%r{)CxkLE@8f5ARW&r& zI6cz!9cHuFc=*zFz5aT~zvYE7gZsmiL>7Gb`*BkqC}`r~BVAv<;vQvGmrkY(58;~!Wh*2MDbBTFO*8v^=l1y1 z{FBhDhsgDYFMKSM-#C0VLkX5#|96x)>S40B*Ot_jRC!ZFP=HqO=2Yss{z+a{&+I{I z=K3;&NnZjsPsuS@u^Zu~?cH=b5G{9>Gp`9}i zJ%PFBGfy0YDO=QqsLpu9gsIYD;tLpl*9vX#pa0eKw9OL19y+w^64Ua>!Moj7ENLE5 zq4M`x_e<^dvU$6wveNp~|M(T*(!1QvJ8)3le?9r}{I@lxj?laEgIiRVhAs=!*pNK6 zMs9lf3SOT}PN2K85-E06ztf-8zinY(HSqP;_S>G!`n}i=sC2bVD<5FY6|Z!m2kB7* zw6+4HAE3z3AHR!33-J}O`;LjKowTEMXJ!Tjk|q7->rRufp?VqplSpXcau$9nW0aLH zgVu?Jy*^G#Oye&m3cHGi-gn$`k|jnGJn6_KYbi6rkKt0JT)pdO3&4dfZ0Rq*OI zd%%s;bt6})xYh0HK-2TE?iaQaGJ)-F`pGhpI*hO= z&?Qfbha_BlO#d2d$dDEpii#D5-PE&})!!4n5;eax-_Sl0UiCn?BfL+3e!H`)(1bTO z!bl!bJGq9*7q6`pGD>ARGD&|FE%?&QQJVTW#%7F4Ma=sQms%38YQkK0Of82RQw(Xn z(pz#VgBGqn*pi7(pMR4LOAU@uNnuFfA?CT5X_VHtnNjHBB_<*b@s8L0wi~$05-Fdq znZBY`rs-w~21|ZOF*vI$iiiWi5&P`AXQ`z*j9ursCt#M>iLx zD?ZH$n=&hiF<+(dsDw8xibeAIl+N1D*e6D422VB)TxU`rB>ixauH0n6(UPVl!Ny{~ zm>KHp^7Kc_A{OW3Q=3pk&ixrO75>RdNm0EIaaH5HQw}B#!%^|rrbXl~xWjBQ z%X?#Jexgo}gXD5bB zF&+K)L!K!7GO9BPZy=#F3*f48%I(4uONolD>6z^q%dBOnSZd+&h$;yU*fCqAV;#?gVVz z{5bpw5`1E6$2z)Or5=ilZR{bZ$*$R4^>F6%Zq!sei-3$S?-EpRd(1_ zdyfhY@xCf4%TdpI;lO(R*{{pnJ3V*)e)YKbZumF5=0|_Q=CJ7NXu=6PMViMzw z-YAZL1daBdTTK$E=$X;B86%LqA|j2V``0Yv!8^O#%Y9t@HpSIKXPa2OzJ$dZb?;I4Z&u|CLGp!dLxWL;eongPH|D*< ztUdrzU6Jc=J@oPv&eL#P^Gqy`Cv6YPN$$#>59Ed)k?$6c^Ir%?1pm-MDXlM4=U_*QM0Ia@3Ss+=K9(SgO~|$SI|tU&1Z! z?N2sUk))KQE8ttAg7hF`AE5IiG75=u@gwP_1#Oi%horo=#h3Bcpm z2t^tW*aHSA=cF0rsM2JScNwMg>7aKczT`AS$L6?aAZoskJwL0|U3$(uK^Z!162L9y zJh-kL5TUU`Db7y?M8G^8y@p+m*sXkZRLu)7cXWs;Wj9p!Ab%ffr$R1yHRg(rp#)`z za_q*rvCSIc>OU|k(*+k$gh?-Y8+|#WJd`tCA10|quac{t?~q3FF4^{i=2xCk2=Bf^ zfTR8ruj@qUdZuyAhcfhy>6PQAs^Cp3xwWF^u&x-{m}V`Kho@yfVir|Elg9dE2DcxL zX{gu?sjZcyuP5K#nG3$O{c?4upWrdqxB-p${Q@$Qx1RObX0^#Ty2Wi~{d0X-Ns8q2 zk!(fiY|PDWqj2(k3JY{Zd^Zj{&MX(~)VA5Ovg4Hb`PG@F))VTaeYBWv4Dj4#oCgN7 z`%!)e{!)7AFiwW(SG4WFIoQ(U-gk>KMSFU$-(PZAG6LSQLX)?>oJsS0?-sGXw|tr`gCHvVj@f!0^g2!IQr+#3< zBwYI?2$?tsWnk@gkUwP`Y7mbDDwM+I#{9ZFs50`ymp-w~g+H}sFN}Y~Ka3uybc0>* zq+@ZmoqQlc<1_dSn}xNI1c*KgR%4zM;(tIpJURHqVSd}F1%F>cZ?m^7dDYVe_sG1U zH>}`FBndH#%l;%<4V|sNf1uNCXeo@JJu971jjnRAiz*Vud?Px+>;i4ia zEY_qT_-wnR=iXoA&TT^?haGj6jl`4O_+E@xj?36I?T$fU@zFi(KgLXVIDZ`l!1#S1 zow){iN@U4Ur6o|mRG@6l#zVR9QipUxZb0&ht!+G&OTUUGmo#OYP@cO8ts*n5$WdXja9#@W%-O{I| zZP3SeS8@~M#yb*2^%4tFvQOq6hebWDu+KIZS%zQ~Do%A#XH5K-3Vm z>=n1xx3l182KXy;RI`>mLO+4C7>lhfLSft<8uN_6)=ECUI0S2@mM3L~8Jg^1rn8WJ zzcim}0L~g*{YY4T=%OZAfP?(U3@<>2G9zMIX|+uPhB^j44~S&d{s4OL=y>z@#uaxb zllB$)0J{s8t*rSw##nEMC{JBp7>7dq)D^Z$gGg}DmXB3B)+od;w-y6LnsKx5FU35$ z(e+H{(hD!P;_gploXVrpd74v3&jHd;qTgM}Bg#D#CqK=qTSp?oCk=ynzUp`i&q){f=yJN#0oP3L8$Lq=6}bhMzU((JQGwH{}a921si);M{t z=XtU3Z+@w;C`tYfTrRR80z#iC_NyP~c_Fz4RT{eJj29y_nLf5=*6^L8)K_`4r>ZOpnYZa-Y5hTmpBsE~u&(s?&4x2XK++a?!REeEL{~ntD%x zLLBi)t+<(R1%`cYdcGV()=RhyaHTNU9`6VGd#OQdY`K_9Zu;+=M&(ll_=)t`L>c0A z!RWmHPi+le$nX~#`xK9|e&zZkoala`a6@Va*}$Qh%8SHQo>_U(1dLq4FpfjH-=iYA zfWZ=Qh?`2}?%BS}Q`yri!pMRxwSC(`Y&Y5RfZx<)w$$#ePekh9yErMWIwqw(2zb*X z`?`L|hm3gX2U~im{th0GQWT65H&z47!|7H!JK_DN_v={ZlQIGphg3!b%IP=bwt>%_rLf>Y1ie|@)&Yg-|`p5MTEiUZ>X@B}P z-#UpFe)iq+Q8Zx&M^rC4^LRqI>@mvf`tUWSHho2(iG=MY2BsB_w$PaDHnzkH!F5~z zU6g>$&ERlbJgyr1ee0|mSD!1TnRungVR}x#P2f@_(^1g@gZ%U6_=9GfyPX*l2H}w$ z9pkMc^tceWoZc^&BaHez2)aCi<)9drEYO!tA=9PH(e{u48gt-k-ES)0*SSpO?g+#Q zV;Xc$J66veoJq_qtM#D$q+*d0_9tG`BxaX+`Q9pXo--b&COQ~Rqv)+>^ zKLF1#n<_xFaL|sI`lhO<-pihrOS1yrlrq#=#BZlC&0IviZ=!;ndRvK=1DQP9l*wgA zul*;ahGL(pBBN$iQw0kIMT~7)(V!)IW^2uau7dm;19r;!w3T4)W1!lbl}nWC)o=}0 zh|MwnELqPN){A3vGiOFW`Q{!~47bOq?C)m$P zu<(XPqrdM=$zha{!?N5gi6~5QwP=6yI~K3my=3?& zYbAqQZXoc0@i1SIpL4Q(9oFOyhQ9o5D>{R+RU4foMRh ztM891PE`3NQlW9*JxB!$U#vf>eijuXn*}Oeh;n6^{(|bO7O@CA-0pE*2uf5m9VN7g zfgZEV!uk`H5BKhuuoQqYU+TUj-0;mxbJb7wED}AB@93oY3V({e41Gt^FEX~ATytiI z$K(SSGGsP~F+wnntVY7~mrdV?wxd(cMPfx$%(DgdbjPPSR#M5<(Bh7-Mfq2L*!mo; z&-xkxJ4=KbO?*nEP#~k5ko%UShD0K%+E6W=PY2xymsUW}wkS{xxJBE4 zzL)e7s8|my->b;D{ZeUK!%DEe5`emWRf;r@92n$jc|Nm|i1vn13z0X3DTx#qy}J* zIZL|X2{%1|Q$nHZjDO)k^fR8O^Y)K=?>3l5Do)iC2^S@xhYl^1h2 zzZOKwN1)FH^&Ky280he_t(0eU@BBKzA!OIzAj{i)Ghudhfm~;tu?F6-`dojI zW5)JpHmV1G;cLyd$&3c6EpPPxf<{k=o06%MP##KOmGjyABrg^lII)q4=^&=%t^Hpk zSfw3IEP{lv4(TZr@Z-Jzpc<&ml2s3Jx18e8yEys-L(-2uRpekL@y4EcB{yfUbES3# z`=Q!M6J6=e>|c|4!<#S7Mrj& zbzET}v{trRBcSx6f`%h6S%R5G1I5IG)dic*L#+-dV~aoQu4*S@4d5)nP?HCUMA>L2 z6CA9#Bgg%ERxYd`r3i~r1qV>a8o_HQ7=2X|r8r0<0rKu{8{kWSkXNr9q4_ zGT7ThJrhz0vx(X>$}a|TDNMg}>)d^?_GqjbsyC9|Et`ajh?HGY;-&^=81x;%Yst!k z6l>4aet}$%v)no`Sr%0nwnM*bd%roJ4B5F#4WuEs1Uond7Moo}X0(!>R6QxZv4yw= z?TWsaeOe$x($!(P&2#&Kz1%|}UN3`33VR+`H>CV1Ck?`u!xFmV_Va93BU}a&;!wOn znf`DRqo&?v5WXQ#3rIL|%NklTKe~Ce#%~1wT(3_pRQ}fM+D{&?gV^Mdh-!LWR7Y?x zcmw#V)NJPQrez_%BIrUimLg4&R1NnA3BWjEuT=rk;QZs}oj!JC~TC&j{%7k>16Gi{7_F|w$ zjDiTv;fF_xt>3=CpU~WK>ed$ph$aJ;k7oc%{32%0-j2fDJzHkbA?xpp;7N;7_FSg? zPOGy>{;p4XBoa(37PK^}o@tRV{cYez4sjQBOH##%Zy9;_p<*kh$tDqNYS zP#}fO`FMUYjU)J0l;p$Q?l8baT`#ev+6&#>TdQAU_x-XoMa03X3a*i zv?zVJ0h%g28@!oMolAkxqWobTYz@hm6ooe%6q$ApU34G|`@YN9SWK^cYe2aA511xK zBOQ~aC2gfpi}|etNz|GZ-bjc1ZWF2EBX@ZWa>W;Y>~5en;|JV~4*-9r^t0+idOSx_ z86(AXDP~+nf?@sOwO~Eyf(v~x-+k#^KGKLE!X8G!NdlF|uk{#4;jSVigOP&?!*3I} zZPwVRxsOdbiso9?aeGEA3HBa%N_`z3sv4OR5$HOR7WurqGeqGEc92=N*23tG3)6## zNHg*oqZfV(fw}ebys6mCcmrG1puzJZyWp|;-#qnAH}X8#D-8oS7synKQ^?BXvZSAM zp#JU`7O*FSe4i-9ImI}h^fH+YkB}Wj;qw`M9V=A5qV8>U=Sn$RF(L7&BjWk4S<=bT z;d=G6C!i_I9_PMu2MT~MG0+!$*K*i>ZR z_Oz(*QS{o*BUZXPN)U=x2%uDp(-3aY}?Wza@^<6n|5pf^x^ zUgK2c$!!1S1b@dqXg+*RkIgMsm|40BmkW2A@I@a= zQM^ZiraLz-!XSX@2sG;WnjB{18X>Cpdu@D}Jy~hA^Cd@YXp(`F&T`ie;iRzBKTUop zAd00yyNV}5CHYN>AsRdXXR zw^S3=44xb@wOgO_ZWJrtJvU6B$mkksiUkpBx}Hwlg?duRGf(TaYvVV0_3qk1dX7U? zH+D)K2gt+K3ST<)vpO||L&nyP)%?7SpzVk5`^#W7x1JlY{*)*8aWGqg>TmJK#R{d6 z*)fY;1#uZ5T_Dp8m$@Z|sSz;(xQ2V4%}?iqhZ-wR%3W#<3b7POVH&E>8>Dg?Bm>Di z-j@1(u|-euj1$XCo{|Jd4s zu;7#{IR+(PvyJR%23j_6#36y4N;>(v)1qYrVZZ8jcS1$?jUsZ!lZbz{rk0|YVi>Ab z8VG8I!uC=;cExsRB~IB|q2VtfpJO9e`&JyX!=l$3VPIi%u&|Hr?)z!oh)e5TTHg@H z;2Xq0LI$BfC_aG!49#5P)J}hp+|S5ADOypy0w|+j^Ll>3Il-9?v*X<#=a^%b<{F$m zFt$#0gWWNmvMsl?f=MFqM@!MuEl^233k^hhuO_TELQ=jwmDm8*-K*(tqD^khXPC6yulasK6|#3U<*Cy@EV}m7b-O<}vI~^=?$4+| zmIqa|>IeuKe5^21T6xty8pCPu3#M*Nlsy-&0pcYqx`{SEcOT>ZENv3-M-JJ@}#*4G?itP8Y6^q#X4a3E0PxgQ3ArMB(3?RA*Fw)M(W+r`Q!2X0f($iNgJK z7F3laCY2$k*ZElw|M^0a%HQy zGR8R}^nyvB#Mp=x=;`X}3WdLZ2WICY8zy8JMFw3~Uu`p8t;D&wvd^kOHJfBF+4dwk z1$O&qxnmaac2o28vzX}bY90}T3hS3W;)`-xosL`T)D{brE+mhMQNB_=%N|K_l$wP)jvi09Hvv!@YDpM>l& z<4&B*;mRamG>{|X@G1|U|KtdEri)Aa_BWsu-D{NdTnuPbnHX~Hr}y1mr~b3izQO(V zBovABWHI3X5tyv8(;i0r$tKs|6ZV$Em*6n(?T%QjvMifX(Ssze(n5x3{-E(f=vx$w zuO`yCeZ-o9m8kdgZ7HI!t5vFE{;o{YfI9J`96npGMxXATH(JZrufR1HIDY<7#j!yt zB@?F9w=6`@A$vHJ(ybtx=fdX*X{`Eh@-3d8BLz1P4Xr4JlZ^X5Y?J6+R)j@yYDS)Z zUiaDp3K3mnFo%oJFD1~^hWGe80GLKUCzz07DS2gt*7_i5f{(S9?FJP8<*hsvx%mMv zCxbxM6e25D8lT|5oj~p|-N1Cgc{P(xyAnfGckPLoj=j#GrDi9xNe;z+YEy6Zd1!Zk61T6&dEiUE0Y1uAWm%gA-iq>g) zy@dzNBCY5{dN!UvPB&6Kp33*1Yipb6pdm7@j2|&v7>(c>W=Wi9zI$+*mu zsk*%S4sb$n^fVq7K*gTiIJNANL)B{)c6kGd4-HticvMqedvD;eGQ>VwTK9YB^SjMgPq4mwyeo<=DT>eL7!t{98(_}tF;;8`+rLL~ObnBn zhz}nOp3D}X%`e}1%2OG1$qZp{c~A!ZlXr5n8`4r7FQnK|2_YCXA}D9VRC!CQ2SaPD z6nGfl00K|DWRSvs(;TfQ%oj zcSY^JEzLl^^l>d~N+Br4ew4dC;a4lGORCP%PpdiJ+My@q4I0+4yiIJ03n{go89Sei z)!2e5R}{UVTyzl0THwSg#3YYMSL!x)sy z@e~R{*I~YxD)?ENkdKN;o^pQ9SzC(QO606DGpce*33p{^3EwR^dkTx$!$laH-hP+6 z1gR{9bfy%yf~ZZ)_4|nrUG?Ckj)8gJ{IktTPB>uBiCIi3=u}-h#i=)1y*GADEbaZO z-BFl^Ih4&sNKBZf_Bd+d9#7QRYW?hMeV-nG?S~@l?de+=2Hv5W6hJc)Yu0yMEx?4g z!NyU!z&S$5KA5xMm_Fn5tIp#0(|8}HI#5OxUOn!W&VUTT->kn(B+-Ha&%)KN&_&Ra)GC@tBo5R*J>{_j%A;eu}m zL5ybf>*ob;>Dy@g>aDyEsd5V`J!WZya9iX3@}Au(=$?J5^6QVj20~8Q4Vl^e*$S%U z540G5G)b=^b?8Kh7aXIHZ*)k;#V^SRn`tdlb0P(?PNahxg+&-rMAsaKbiWcj3>Zz8 z&#&F6s zYD)R|r2Cmj<|Y?1$IVfk-mlLYL8VZ>Cb&MXgrHBXGWeEdbgtw%5J);BL6V9`QT(#~ zWUwsDPkE9hPU1rmx?9}^S;JY}oSfzEN;5NGuK{_Hcb<*;{gZ46cE1)P>*L2R@-z<2 zWYNv4z}w%vlv}S|&d<=t@%17pRaRuuHdPn=n6^R2T$shInCP={F&(%qMYM$U>iHLsb0qPkKO5^~%n=?qZQPP^#vi(vbswL`R_UVQX zX6qH$hBV4yIUTJkkt@uWr*9MK$vb2H z_#OGrxtFqj7JT;+hEvFLGERCLazKl%k(u^ab;ne>?3LXA@HpY&|5=AZbM%6N}0MuCIlF5DlfQHE<+<+sGL6v(}|531I*G zv8iEANAw%beJs6?K$)@`99-P@Y#bjgkg;`fcIBjF ze%wTy{VblZNT_plY6j?IGMSm9VZ31mH$4{0exYW+A$zoYbR>o2b*_=(w(I?(4z!V` z8{XTQ4y#R?!RWauDx(W$O<|M8TYy|(Mk$*ocl63ke(6CDp1T@-1}Qh@8^wUomCWo% zSwnW{hnvd5A1@&1J&Fi>!+Ouj4 zlxp``=IzbH7`cJ^Our15wrs^Agtqo9c25=*rWsv4MJdYZJ4@m+*RMHv{6}xK8BK@B zafi)Ol*GXypB@C3TLoL5Q(hd^e^}gnb@_SN&F33Z-Q)RIE|OAxjBB|Fc!7Bfg+&`) z1#M`Yg?ZFb_f+`*Y2A9Bc@2yX%Vp-smz;Av;=TW(n)d zgnH+$(i__R-nx`ODqhVRb;|+QVR5O!nMJ|bqhX`5^ZVxaM`ny-G4IGDhKOgbO0eL^ z4<^A8CG}hLfgY<%k0+>;#$X!VB=NED`04s%tdBl`6iq2vFkmvY0YvUUN@q`?3{N-e z`xL*awhQ>i7%`QYB@Y3No#+fa0SJlpP*4L=WU#xd1Aizz2anR+2O(w-oOBDROf-uA z;Nx$D7@{bgsyjpGH{#3VYsG`WT#J|1|KT31E4f3~bQ|-X5GMDJ0QU#PjvrzbZ{X1l z221AGeKgLrOYQ6L1&*oS-F!(?!gc98umDQO+PWX(*rXk?V{?vv2qa&DAPIf?xm84; z7`sdPd)K(k9)4|t8J8(L%RTl|h{^QizUUdDnmFG~$Lxp`x%OIm zo&{%cqPdPIS1cs^$SaD4TiRm2?0J0A1&(v@0T^b82VtqvhU#jMu)At@23q{eFFwoE zS?SrJ{p$WGA*@J3Q5N9OqJRjYqePYhXJ(U+bNM~pYy%a*o2A$DCo|skTkb1ccisksF)!WROfA3S)0Gn2#n! zB|Ip5l*7j8RT(a9Eu&$D{-?4MA^fxPl`8h3MR@umQIU> z3HnKAu*RV36@Im=Lp?ECd1S>?3zkXBUDHEc4T@0+H^bXN^8p$KtxG9CeV?F-hQkP-D@X}~l^U&U}(dOdxi(qz4VLu`mX~aXIw*e%;9PGwwr|C ziy9u+&9i*7S^*mM*X%C%-m@y-^dN2BSVU;vDCLE+rWEg0_w9vsD9S{*2qzO?N)&Cv!$2PfC z*Sx9Oh{lTn$m-rG@==uC=aE2J!f3c*6|=^PC8kx>I48zbflc4cjs=kSktp3`Tb!1# zs@iz^Qqc)Yt1EgZMm~1*AkHt@2{W`$jKgK2>#A6|tyJXi%?XP?gRNFZ^hwv?lL%?= zha1k_Cb12bV?Vqc+-7ml2F%2fUGKN4$f2`qWHTM}M|0al!<0tX9{Z=ZrIyFS8kY15 zr?|JsefkxsuA$r3?l6Ef_6Koy80t2)ps~nv3fmOH*{n(54bHHYWbygDcoE>L_pxOd zdZXP$>~y27i{cgFfM2p&JC zAC-H`Hq6eMV29W2O@xZ~H;?HhCs`U(w~+YgclT&lhKF%J+6XzkG_{(Y5k093<>2+l zf$i7t-}J2HvArY5zLusxPH>qox>>8fYdc0pe1MLF0{g4w@Taz|=La}MR}%wsQIsT_ zl)s&hD(JFE+X-mq*A5qC&VU1oxR`@N30e>2DS`ig+M=WaUYgHbh0;DNp(-N%(L$0b zYh&R@Q;$`w^B{jvHh;31gw%~-^)wm8+7(D5W~#GmUx^FFjNql9l0rJdCKO6X#Sb`K z*4u&{uNG9kU9vXK*D|)M*VXSu(1*OM`g>-eXq@lS!W>MuhT`_Pa zdMeW0(_+_b+ssqJ4Sb-!h-qE%Ub^mQKyxB~pkDT$BSa>0SMNJtk^A%!Bh!}dxz`IU z$uC!C1?~w8X`NoV@lV2-+?yYrb5ap>now?jSJTeH?q-hV=7sW(hW-^YqD>@q zqR*w=`~4Pg2l1f|#-^}ysw=t9vvw-O6Jr{kUOqWWJk9+1?OuqOtP30!TfnPn$f)Zr zG}S~9Bh(gM2XQ=+5eD`Xm165k_y;oI8EcJ*)Qs7k$);2B!YJCIBZslMMvh4|D@~6s zaa6rucppR<=rpMnVNGLW5;pN7%zw}SY5&t^Wv)*D4Wo084BpH}Eb5)Vsd_cpd(|+mg zkg2HL_pU_!OuqPniGbDEK}TATu^k!HJl?mOW_6J<-MAMh#wgQ%LjUEW0n(Npm5`4u zsmkm$O((Hb>OYZ`BjB^8bjO&0!_YFsK+^Fe58laP6(^LXSh|Y0bBMhvrZ&ekR8|vy zJ85$4fHFu!(a#!ZruqD|{z-M`YWa{BwTvbWw?}{si|%?T$6O00KED#HrF7G%-g$E6;+0UDm8 z`*|MwU=?9IC~aai3F0WALOFD)Olg{UB<4~fu^hDEVC-^2!|~_@KUqowT{wX7HK?E% zG6_#X9qq9_Yhz|ksW8;FzHQozla~yF?$i!(<9X5uX{DkkUV?y>RFpS_!t>^+Uv;!+ z_MO@1-&PH_j1QMvH+n0{mX6HP!ew)U+mC**yOesv!qQoo(#0$?p(p|USgY81%0RwY zQ(qv4;wScDjPqbqE{A{rX$0)KI+gbeiCQf4c&E8ig9*x9x?V$8c=Nkv zVr3^pYEiza!f=0Y-pC>ILM%K{kk?k~VVX>9nT|Y22WNLA?>R#ZYr$XYbj_tkblC#} z&L+0oLEh}907;Z3z>CXsce-eWTm#iA(6C?9>so31M)wX`HA`lP45l9rC}IsI^FU`0 zNAW3kdaR@`{6~HR{>Vtz=l28bmE0Y{eSp_-l)>iWiSi@uZ;CpihvgC;lvz<}0$_r5 zjzPydD{joEH~5As&u$lVx}RX3DRST??bY0q=-x~iAhgLwgv71;2?GTNG|PvzU`*lp4{(+u^JeTO5K`g@+}8B z2Cnj==5JI18NGa_=R!K=tH@1%$ zF)_XBcuH_YjLpT6Yea~edXieQbfadp#`FVP2^owSl;1dKmEc=LIJ%S=%e1AT2en!u zLkin62~=CGT*KQQw7q;KY`j~&gERCK4ZVo1ABq{TUZSiU${ z^bGwaqJZJ{O-ImAQ~o9?Z-UdZ52yHrZZCOvlOJW!jxYST z-bdM+T+b=K&xfagy6&OV`|| z>Y`d~pkm~SnArtL)Yh;sq(unbnM)kewD9Y7X&W;uz20?fs=Hb5lIGcp5Vb&!YdPe7 zHYPAmWPpNQ?Wz~pSk;Q*_un;LlUb`AlDE)l)`CZtu@v3y~lO>j$AY5x-(`}R` zuk|UydK1txj=m=Ld#)y$$hR(p_Uh4lSD`{X_5k5VP%15~2G=liAq}&&&#ZyN1uFKj z5aLV)cXcNZA+#R)<)D6boIj?V0W3y3N z_QiP>fn9Ix1iSH>@?8SM`hz``G93K&nPO>CI6=XU+J#&7C+?>{fZZ=9AHL4-3hR3` z+p}-DF%o305C8fDc}|Z+qxgw4|EkzK7f{HgL|dMzEx{OxF{3++wAU3Z`{M|h?Fzr#>_v!u7mDXO?+w4yg@V+|1mNfKFEC--FZGn&|4@ z6V(na5&Mau&Sn(WpOp%#s&CTo71J>;u1g%KPRFpMqgZox9{f|d1!~8hwUQ}btNarD=k{K(+X~$tn)SOT6ZN_KuUFPTG+`!!n0#2E>i#a_X4z@>78y0v zwrMAGS1uWnjAKwda`0WtqBVHLYfB5ud*7GQNjv|LN_X;Gt)2AR;L;oISzRi#;^ep& z1lg1|%L0@QL8}8$v5QL7i#Qv1d!#l2t~jEt*;Q~_D`?3XMD)CRK8-nq?pQn9a{18l z;v3FV0vR^q7b1f<;WK=i20E`EFeB812;1ZHcqrWbJ@$Q;dI+Rfezvf?)=DYBk=gH~ zF}Dok9kFCa@Up&Xo)NW8MQmRU^hr?v)N_-ZG};3 z@oqoIWa@eSUXLo3`tzdfP1&~f2~1}3FW0OhNG#wB6KUUWa``Kw9Wh+KvmBw1(AQ@f ze3a-(gzEU6Yb;_JZaOB6@5Wzgmk#7Xay~gcn zrff0Nm}tN%@V z#m5N5qGq3b1EiMh8>}%=$^eLi%uR}tF zjaA$@Akox(Y%kzs%R7ZSXgu*DrZ0#@-isDn_ogze{>al6E8h@eO>MY^o@Zq-WfCvY#-8=kQK2U44faT|DALf2MKmy? z27dE(T(_vw^w4s9Q1H>k1!qc5(n_hg=p#_yvWc3Z@FcPQD$jKi+<0@FJmsO`c+xqi zQ8Q>_jVtTK1VP}c7I&!*#jLH+sLdx|jb188_v?+P&{`6gG(<g^@bO5H+f#!Jw3(%V;F$lNtDGbOMa*z@JP z=dk`z-f@@D(Y=8dri|CFkafJxOleF0sotu0^jup^fr5E_8k&ZP>HVo+^q5LvI#FVo zt>vvj87Oz1+~9EeZC0s~AtD^ac8JR@4-=6=W7pV$pAjfGMF!YrOv07w&7XbVDprIu z@#Yd&zg?W0hjDdsblOH+d|^03hbku;?9$)=xt)6~Rh&3`Mv${^W%cFIi91b_Q-k-3 zw3&fk-^Ed57p&>(A2AWn7?x{!loQ9r!}s(vOyi8fh8YF;gH<7+zAYGrXztvo1o#z^ zMrkp_BG(}^iVaq5jZzBaU*IFnNA!IL1j`bpN=)s9fT#ff1?B^YOfrOu-?xYr<(?;5hsAtOhP zDX|Ux-gibU!LXR7nBVKLxfe}njdO0pmv3>(AK{FD{KBu7i_KfcI+UfA1~MJC>52L@W~|GmQHpFc^!+aUZP%;10f0Q?`^ zPZ92%pLKBKy8o{q%K#pwvdjwke{bPGU-;ke2R}Q50Dc*JTD0|V|39A~i2wU%@MS78 zRONLC@%kS(_0ONCkAP@8^FtTczkb-xglJS7{XbtDOaKHK5{3;InGjenXrF(%g-s1) zcsBQP)v)P*Zx`-hE8;_bmm!%|!hijJ5MuzM!3>_!lz*E4e|)_zGhmLUM)uJCYrFX= zz?XwF$NXF?|Mg=&hinIzAyKC^vX0s_*%~KHLBAwN-GdmuvL@bu=D+<@&VJN^@)q4`i1U+8w0$Ixg!ZuIq5*8%W%$muoGaA^Y}(CwM~0;!b0gwi#nn2fWN9&P&6|b?PsF z0fMCeiSyrc=cHvM(L8+FIp8Fd*QNXKyPqw_lzEP@mGBV|_g}cV%>C;!zSaz$#0t!Dl}al1)X}d}8TdEsT=s+qXOXkdCctkyaRYXEUiJ5Ceo1rz zxg?|03u{E5>N#+>ZEYI!-=ADKtMnp37shgulDBn}Dx!iQG_{zi zEW9XCJ{Kw5%hc>P*30Pk&;1`gk@PR9{9JzvkfB5*5Fi9$>5j_WDU2PNcD2`e4u#dw z(Q0p{FZj%K(@#6JolTE`jeflhYE1V zr#In$5_68wS!Rd27}uM5 zhmt~NQ>}e&uO`Lxg$G8_EW-ckq$dwC_rY=e9hnrc>g(AIHbiSfE)M79vpWQ)*gE*F z0{0%j6qrNOzTNLGw<78|4P|)og0NARARI`mu`nqbYde}BoZiO}FlPmqF&!c+3@(9# zIH~p8-`^c~_QmG;%BF5MAVBv9IMFv&D@bTyiSebu-?0V*`j)8KD(=EN-8W(b9FM@X zuPw7%7q2;(Ny^OToQ|Xce$r48VPbV!pvV5U?Dn<#v(>G_-VQ#e|Lju{qVAV0L;;5( znLu1v($q=dq^2-;guICdOh`*|fdjuS(agZVe*%g2f_FMTtF>umr}|c86m*N|LA7eR zq8)#}r)|GkM9zX&iYS=-NbSWMT3B)AuNX0>uh++o#T+i$)J|SFN~&lyoW|FFWGRzo zw@D~v4i3@g;cdTT<`v|&&Ko=Y-Dk`q1c9;lhNXQf(VX@p7O~N@muUFIlwXj9_>oAK z97^p?i(W_aTD9jo%NRtBZF`QHX|3x_Bgy~*G=Sp9N#N=TtOZIDo5X*eAQ`V zFK;fpi=^;x{2>ZbOkAM1CR4zQudLJVF7^D!_Ax2EU;Mmg6VxXXItzEQdJ7Em*^IQV zG8^wY(+3A63vsEJ2(a- z;AV|M*x7H5CKHK`q>7n+*6)bwI0Ebf{%#^dh@70 zUfI$2At!c$+a?_Us9XDWL7kF)X@am^{uV} z_;{`r&>HaK4+krv8#UJ!$%?B27pT@(K}HA()e>80B+8I^5RvWu&z9;Mv=JzD$tS>?;#kWz?J?g8m7^bqN!2b)=^{{xdvr*h~v zGP%7P^xzax7F`m$atyF2a^{*`$#>$uXEsjGVd}r*%djAR9P{h=7UVP9eNGD)=;;6M zOAopJln;7`{!ld{1&q>0iymj5r==f10Kr$%r=Ohx$8NiCkvqQMmNnLn*w73cEjaa zq%-HUD3W(irwB*qypwWQHN=1Pk)3c}O)vIYE!G%Fgr#J3DIaBY$9Joq82ow|r+0i2 z|MwzZ3Mh&7S2y~js2w9VN;&orZi-KS-a3P|R;uZJ->PH($Ukc_zvu8_JZgDYzK0WV z80cLOUw2)uHoCY#FZJtd;}Ce=umo2gOAZg(WULlHDR<$bYnnYg zCngyTy$PMSs$>S)3=3{Ya#hca(3Fop&Z9^uIbjKsaLG`3bcGqzzqM$Z>=~Y&e^-0CfxlQvc$X_k%-C_qO?>`lDqoY@{fAn z|6&1nw!yRx@8%Om-Z<5+4TB}3vDbkNG>58!KJ>?#&&8xoa54@3; z6UF6R`S|@Uuu31NKa>-33_X5UOcpo~G54k67E_b8F#blfvjx`QDVIJ<{(eQ;WzP0B z0YYemRh@-xR$akYOihV|+>QBdy~@8HbUamV8XGL6MPZj-W!dBplfGmeLkYuU z_~|!9=%_t~EQ!F>W8~5PfifD$&V4u)z|P5h+lSPWF&)75{&I_^#nOTNO@5Za0&upR zD%NXlKPNT%{?NZL0vd4_`Aj}zMfOsv_*8XDeh2NARAPtuHVw1)@#O%K$e^lI*K6^i z#ZS2C@pfLI-2YbpXR~%XtA^n!3t_xyZJwA*7M9P$5XZ(vuz$;RWHvyox!gVPK%PVc zPOM2sDRnyz!+0FPRv{PTot=RBs>mP8cxORUyF%E`U*K9`^#I4U zlKAjKYL4^VQ#mP>7}2rHfhUW9CYS>P%rLbErG|kCcpuH0+NjzyZh&i>=0hRa)|(w9 zNFp=vgh2No$<@qoMew?XeS zPOnjX4tnBYh!FL@FwnhwAvSqbU#)!zPv1fl2S+Ftn>o8jpYtv5t8_!V2}K0}SN$xJ zFzi(X)`O&3dZ#waJWsGcQ+kGR(-*`Ao%x)Pp7(tZue6U$Sn}p6B7X(R_I?rZtjz=Equ_NF3kgg%IL~47Qtfc8oYWkvKgncpRR(-aE{c{YU|) z&f6`1?c0FlMe+lzo-B(;+=D5YD|(GHDzwP0AVV@L7ENfdj^s)ORRqNnNY^gioSFQ6 zTUQOUOI{NtgN_h9LkZbN9>^FO-0H*ds?ef+k(qI&t}n)H%3XAJeB-_V7&7nor)4=i z+5daJ-#2Au0Ogg>0_p%Cg172y?d*`4U~4D(LiWC5e0;$>XOqZ&E`dx;1jd>Bs| zj!IGkoP0^btD=YtDwLoAxo-uHM!{Q_t}`NIy7%ndsXuqzX*8^H*0%`S@mc61*6@ zQHZ)ejWv^1?&ek zg9xJOB(>3Y>)9MIw_x{h198otrM`;cF39!t&22)= zi*6`P#vdSx&$XS>!BNsZ6I=W+c$#g-mM9(e)3;;jex<7wP zWHu(ncP;> zgDUm9zf8|QG!iiBT=t3;c7-Tn-xjhwXFEh4)eVXf2Uc4VS`3Q(n?qNAVd z93xTDWNbM^lBt40!>rx-mMg+6Tj}S>@weH_6L4f{&T`Ik8}PGbi43|0UFjwX$>_Mu z>?qZy_R`lxsGXu7Cp5pLIRXM)zFo+6lmvG!xe1>|&^K~{^#S&DM~g5XLx06cneS$` z^79+&M{ExARF;C#=Q&pc>^-_9%7+hwh=%ZNFTckJOaVt7lY6(A21^*^JR9WK^Yw1@ zCp>qnJTLU$%=e%>iq7NW;C(YXtzdgMJ;Lq+#E2}8_{sUwf3ZIluf|TAx)#DelCR_k zsmH&uX=VndyGY=a(u9I9(sCp4n2wVANL38_5d<+LV3uewf}dAA%riM4*jWrKcR!=GKFp>OBX55Lu+{jzK6KolEAe zy`0fnlHD~D*Cc~JhuoeUKVJqVR5`778_BphUx+8GbKmWhnuWdZY-Mlxa8Gq*J%{hL zz_!>-WlvNl7MUG}WpS6j@C70mF{vu?oYifohf`%VXO%*jo6q#V+}blzN*Dh04LVM& z`wa$iZhk#J55=Cnr}J8<@d3UJtqysb>;~Tx2TaX4G2?1Om2~$ev<-VLMj-yBVs#g_ zNw1#CSc`l_=V%p45VKS-PHz+YU0%l=^4V}^X7P9kvCpRJqX22dbdFbVJ@qxkA zC5_sn$XC1Mff~!OiA+AeWQJZ_<%y^lcVJOx%F2iYrI;e30ts|wc(^>qDXO8d8-uBg z+T*h?1TY{~?!e)xDG7ta1ypNJabXQ9S;Jc<*s-3V`~MNti)DVEbyBqW(zVvD{uB}B zIE<{rr~J0XtnIeKRWVcPQQeRz&&Ry4UMArRn`#{KJ$j^Z!KzUh<{AFOG_2F4^la3XeDB%5kn>7XQg@dbsIH!)-`BpgC#=kSL`m( zVYTUuH!raqh-6&R-NbtKkGzI$cB`B{X~uO5zPVP?sOe#r@PL9h-MV*6Sf49kp)^(S zr>I?n%>B<sYcfJhXABw(|`)-xRLv z5UVPvxLJ&QMjI?V!cSC7{&;;q=SoVmkck2ysSg?o=={S3N2*a%&hiEn(0gG z&k_$^Cu9kJMP>GY@C@W(RiC{&j#WPV;+|a5aoy6fR!2S49J#uT39wERp^0Pcj}>Ta zF5VbiE4?VX&}c6iq%~ms11#FAAIbWfZs2mwsU*_{2>O)3dUbBNyp))=W(KdoW012a&K^Fx-kXM_g6bMJdeYpp{@9yD!`BM0gES0S*I;YT z-|3`5M{3jZ6~V!4mg#o9S|^!numBy3vS)9@jgY5RN_52{L@_a7Rb2Z=P)D@LJy!&* zy|JI8^oGhKy^lp5sI;Cd^|Bb_>hZiN2wde9wF#L0gg4b^p@ZOz)zs&7PsH3~;0QtS z8BBHKj!q1uP%eY(8PcT9Z)u?2#lV5wkW5EYJV+%{<+dy zb=V~v*x5p#po|~74@Vq0w!R?hh;*BA`->=%Zc|;mymxlP8$6T6ubtBIZ$6S`qk3Kd zTeaGG-Wm5(^VUS?-cAS6G%2w?Th&YlJ-a0LD4}{*bZIh(w$Mi$pB_`11cx4H_J9TR zz;@K4m(2UqL@!fs)<0U)O;c2^5{8ohC5;Q_+$x1hekRWg8)iFTzm94QXFgSdtb|sF zyAlzmJT#gTkQ!|fse~|4H zqlGcBE;}5M7g|Ox18~+MexlqOhw)LAOPLWjy^DLE$6Ph+*Zf?5r|E4?yuZWA2U)R4 zS+Aw05w&yh>DN0f8zw7cJRWbb$#NGoihCn}-DB_??Q$L327v~?*Q@I$7VO3sHe^P& z54cuI;}%Y{*EGD1n3G-tr>H==F(AKy1uebgC;LMQjF+p9)6gRLRQ;{gV?B)%64P#Y z_i$;K@y};ph!99>8y!DcQpY4T9LRNxJyz%_lo!2ZQ=#eDt??s$btd!wP<7USQFURv zCj_Kbx>2O1yWv4ax};k=hK`|2KpLdGLFpWZ?k?#Va$rEDyWwo!_naTjKfrugd#|G+Zy}&iH%gjizpz%z3vq&dgNoiI`JG5wIf63j5hZ}$_P&T*EX?#kpBHS%AlB2P% z`)An}@7cMw>8WAgDH3)sERXia*gXcB&3iczy1_#GS_NvdhsFVxBK^|HM+-W)Lp7ry z{L7V_PxlRo*)kFjnMg)Qzqb?E!yeVI^99ma)p7;Rf=mzi6@MQ$*xQ|W0&x+|X2wfl z#8h{2Y>7A#LXkblR^E6;`1o9vW<(j?3HqvV?E_=T(`SL^_*OV}OSg@dq8@`E zDJ_-fR=i0|{xTda*O8WMtd}R2s-!KiwM(RUkJQBD)cxtrplNz1@$j>VSt^YsT1NC+ z{#Ps7k%)>Zt7+5SVJd;{ShW0%0zh#Tyq$IET2j3f*qs)M>Txp3Xn@5y9g2AOcKo&$ z1-<&V6A#@lUAyLb4v#~~kj-#78yX$bKK9jT~1n!=Jm3Iu!>nA zLkWEih}N3!`R7YgiEDYlaz!t~V3i<*s)b#zd^`f=|0SI#X_a?!iKimy8GgH7sjk1A z__zPudK_=L7_0kg@MZE#QxSLoS6_2ekV5{EbLj1rG4pjDt0UUq5fznnZM3bR^q(Vo z-+&%^-y0pVwRV(7uhY^5bv~63In%i_I2J^hsMiIt;=*=&2{0A)`*1vfHrOcWpOEhR zCYx^-`VHle*`GnGN>Uj{_~d!mV;>WA2~U;cNE{vy^q z^zs$sMcpaTa6G7-Eej><<{d|+VcuZFMiEdkFpw{bM{<9I84W2EclWM2`JGkF5{863 zIcf=?Y@RYHy0R$HxB$j~v>|io2u`NGJ&R1oyoR@3#880 z5U`UD6Q*fT+E`jBO4V8MRkD=3`qAk1DXjz64-8rbnpgh(I9Y-)k}!QnJh5>lu60Yt zcsT2JnhPrBIReRbNXlsBtbBh96~?>>59THs;dq4j;A*UYs1SG8i+M@nf0Y-a*2zK~ zTu8WZZo1=4Iqqz7gqn|9l^JH@DEwk!uIF<4S`#W>yDmzmXY97Q{K`+wB+24_!8sT{ zOq)xbJ7AouA+6b+gu$P!yHvD6$mp!prGm!(sg70oq)Maw+v3Uj%Y?6X0#Ob)2XMLp zZwdzxFIlx(|3P%j`VOrU_5nfT*5qZKo0g{xxQ~@brf$wxp}Fqsx)pw!Sw3askZ_7P z5Xf?2qqe><*;ypD|FWz7OCp*dvcUvcA4PAYjx602g9_}b4@8oa z`jQM7Oyt3AU4h8~r#dZYu_b2O7YLMh73qt-T_e0*!we+K;i47*yU{X+aca6aiU5#M zLlmoZ2?d8S1XyavVD>vHAIw+`xaCiwFEG5gvZK}g>ishl%;{so%_8Zt)huYx*zuGp z@Bbcgsnb5H`9YgdQW8e*TkZhg?2am97$gtse6nGEIdp|KxgLcYEMwv2g8QG*lEHOE z3wBkngpB+luZ119571Q;^K@;Dtn9|BDw85y)n?Fp={XV0Lvj4h&#V|uR@zx)H9S__ z5gn!``d3$YE`}!7*9E49vyKdq(#|C9*ftL`fTB)NQ^Y24#Iv4lbeL9Vq8ODDuh-== zQKr-q87EFh<&?XwPfD}{k}il7kfnn9k|JeVi-2HWd0BHeU{xE1Pk$%KYp77yi5@~X z8Lka*CtsY9W3y80zwE{Z2etDOR`wFE`EFL@rjTtY|Cy}96 z>{7a2_>dAO^iVc8$x(;VC4evDv>2n}q$du)mUpxxO+p2NC9sfohE%YcC3zZJyU_6i z5cDLg{S)S|aqP5Dst=p0q1drx-_R*qmA_(PVT(Ik^d)J0SgtT)ZX<66%+LaM60;Gm zxY2?*JX4t)n-TtmLWF8#3fL(?Kosj9b;}S3zx-(m=d{ZDhgdmz0NUPNcQFW0D((u6 zUkPn+zkzX^9T3kqv+8I3uEzP=gshz+P}r@#w4n3W@~&u=y+;vgC6CsNSr-oL57c8f z`d~QRt_C=SsFFJpJ0L1SVNserfCXK0aYy?L4u5oE*bzTc7=QQ*(K&OX&aJGyt9j!K zP|h%(>xYL_`*C~^_qUYZ`!!wl;05*PHE*jt*AoXkQ>>0Zd;jq~ygiytv6PLOJ$4ii zYJ>A3;g0{T@pWF(N|`?v;Khk1)xxJMSi%$OL(M`#RZnF7J4IH_mUvJO!nKSbwr}FR zDuCzxfFM=qI()~)top4rG$5+98t!r zPpN!wAZPi~kdkpiAUCSP;GSUTt=`6SAa&>GeXZdPM9-4?hVAB;$%qw;qRzgP;;BsM zx{Y#_Fz;QqL<3h4~uj3vVQ)`1?$2zvdt(pqaPH`f4Tnbw9Z6fnHMH!s>N%H3-L>@h}XJdE^aBy%J>Xoq+ zW}FFWvD6<7lp!xVkZLgF*trS<0BJI3P@koOK%bP5~&s%P3) z;VB+48-5-|RtE=p$z^g{@O$GCOGSUt2PU`%7#oRNm7g6 zj=xVSnkG9Ye=(AAjYvbAQh-UO?+$d*;lT?e-s9Ua&MblTn1N3dKl3ftc5cH9fAE)*Pl@Nr{9>e$M9?LUfd3MKUHFa$})5; zb%<^lgP_t$^m|_G{a+ag8}UYPFsDR28ZbZ6n}(|}00`U^40EoSklC1XY(8ZjV#9sWS&FaqyWrOhQr(klC2#5P2t#R?q8?g`1C1T{8}!Q)kfN`rSwLq% z2n9A-wUfO{bp2_NAQ@*Iqid+wdwnNNqqVt@mjPBovDk_#)z25|;lwglFJVXW-d@akS>TcK5rF0t z8Qd>8ESh7N?9@nvFqYAPhSIT==fFNTlVdq) z>7naTGl%a$PWH2o-m5l?*_?$Pl@Q$+=$0s#!MCG^pL00r%P4JLX?hn~*ivbY`tQmc zmHv!I;ZiYn3k@sgGnV4#^OWg0K9WrqtZ#z{^fUj^r~|m7 zlM^t<1UaXmLJ^UuWNT0lU`Nv=gHCnz?luX3yj?4%z)56b|7$|bhxU`iPt+!&+Yq&P z#EuUDnKTAW&3ujpWt1P=xCL|4XO&)Wqw_$p$FRQLyg7Qlym5jfN35e*v(1Nd9I&B! zudp12KFh3n%4m3ia%CVgT`Pq=EYOd@g z)&u?o3I!Hb0n=*kWE#+$Sj)N)Hostkdnm{{LChgRRjZkO#e{Pd7P{5*Du4t+I!#<1 zq=%(YoaJ*mGzK{E1w4@qoTElS%wtKK>mPCo1H;*eOVBsxXwv!|)Ztb2^2A#NJK#-A zl@AsCB5tV%!3uwR>(x)ffz%3QfhC9W_C-v|4P71*3_VENpKXQoBHNzg{XeEtA>mqy zk5jTSsra{e?jI4itbJl1fuucj#bvvWo?diQqTv@3*z4TPqwilL`c2%P0hpRvehtpv z2>4t>O5479Th6Ojs+tZ=7O`yO&6ZFKcT6n_2M@>WXcV_D|Qh?sE!}{SmHFLcKdhf zj9zzBO>*8{+742QM`CIQOY){`81OsFb&o0#vc&%0q(D@ z$?OOCa;!VOvv_(>?Uy>Nj&Nmbx(VwX9h2^l4EyA{`njWlj7TZ6Z-$1_ySqM4nxj=} z2733>QNIR4%#Kjy2pACYkLh$Tky;^v-B@8szU&WEFEW?!Quk*}MEe%<&=+L8deME| zC~#EQon43gA+9{X|MMQk7x4QxL742^;}oYIdg|fg_kU5GZ9z$W{mlP;5r_isQ2+p+@0*4S)u;HbptDFDsViIMUtv*;0DFw} zZSTNv#?;$Y7u0|S8u}Peh@DX+#}HF|AUyAEBhXV*f+!4^L*V#^i>%AE3uSWBBV|Yj zPZP%(#uSd9juf`9N@}Y`0@#;YUXie7)uEhlB!FvNE`u=+(|jSp`jJ}01>J*o*d#mn zWx1pI>X#~S;Iaf(D8s@0OV7?8r{buCpz>r0AgCZ2VQu7WcXcX3b(3R4$8E%l?kUpsRMLGPsj3Js!LYbIyDvnN_x22eSPeIf5smJ_pS2n z>X4t8!WeK>i>QGc5kf(b5IZv+aacve@vADqzLVZHE(tq2#J(GD^}jv>!KLif0Gr zI5q}ff~GPT`)D`)C}B?^n|v0YNHND+%CvOjoy3~kTGxOu5h({%Aj{7cICj^G2DLSQ zaH-;po){6-*(_qMHs(mk-?ijvqXIYtY}InLuTJhpZfH|o4!OKH=EJ>4@DgLU9T-s|D5G!q2dytxcD!#ywy6W2Y>}JvL!3AfDZX{o^==EXGIaL5K%|8 z8=zb3^3B&Gxr{VRikAF+0D9!?Yjk+I3JPB|k=|QUK_<~+a_Oc;hh?PY9}}m+?|Rnr zIDQ-fYFx)24cO`}7op&|LbX9cS5RlMv^}%BwZ(;EXA_Dh$E}?y{Ri$so*?4kz3J@B z`mNb%xZ+9P_f|MjRch-^No$;c_z*o2PNJHpZBNG*JqIQXZUbL;SJmVsjq01#d_^RuPn&V8hx5>eR zzRaSI3vxqb>@D4ZuBu5^sk~jMk2OT^U#Qw`Qk4&VE^9@RNtbls=C%|qQMSR`{X-~_ zYLl|%`7-WWelk}q-+!~Vf>iCA3vZ3ze*s|LnIy_Dkqq$>vF||M01@SAA|SQ-qm<#d zDb&k4Nwf3}Ah1veU{xd`_Baj9U_6M18tm3SmVcQ#+)PG|82)_d=@ z&htAEWdTz6?H7tnrouf}SDz<;%PCn2PfCAfebWhd*3V@Tf+HiNogm<40H9Gnt}`4hN^A(Hi$w~{klhak7sDkedM z#j)p!*)Qu735p52@GMDwrbQSOG)Oq6ipwpQGmk#EibSMJ*vu@nz)(#x-p ziS_V+Lp{M$U0)9jr?ij%7$2GU-j5=5=siSb&d>{$&7N>eEkZYL z|K-FX?yx6K^-cE+bXE@LMacy2U=$hZ8KlrTsb^Z!^Dc-F9wsI#ESb@FESPmC z8Hh4_3Hfz~;Q1W?@jZmIbptySXxmeeknNUJIkEcPQ_WRABfa<%8(W=vHsf2*)KPV< z^O5!CaXT%6;1A9pRq>bryeXhg3$(-DY*nU?6kGAV6|?Wa!MAg2of#QjL5LK99WD)` zQ5!TGY{MH5k8xFs1(o~CJ=O-cHK^q^X@IDU&qEqB<+Rq`*!6Oft_we<+vISSb{ABO zZK=b;FcM!0U(dMzdP7|jVtO{(FV*x75j29ffHyFWiF1vFi0?}&|1@#iu&7@DePWmb zaSBLyv&;WurQRqUedhf_AL53BxsXCq8y8&hDgierGHZ{Tl?}Mo$(bQ)_EMMj!;bGd zYZ3|5BTy){pQBxGWzuYrmCprD*^UsWTyR?JU<04%_1MR-@JIuX6}RwAP_xanNl!&R zN=nP`*;7(jyj1COANZt^4g0$2FTmc2o@oTXomd!`g~bQw0d(uN)KL=|rHCi}*2DJO zXSm6~i5^)jQf*vMj2NlANf{b3GQx_>exye-ApLr5)Dt8fRogqJ`y2WG<8=rzczqy* z#ZIdNtr9u`A_#mAHb5qb=v&a^*7gM7!Pcnlh4vHNGd#+FHH=wBR1R~~tbW|0g!L?r7gczg@*4VjrlO0p8r;ta zUPT8-61eM%;`3{Y1>%!~#%D3*z;u2U@5KJ8#$wggV9{g%f4;KFV!Qg_*iG@q7_nh? zW|%%~O|$6S*?x{}^tYBiEQtUzHHTD&Ro<-|Le@N(iY%BiWz2z`VF;P8)?o4|Fu`m~ z>Xb!@+zjI(jSo3_)3a9K%sF8s9va9Fw>NibbJG|dj`|f{NYJgnf zk8CYp33_hVTWbrK{m!;fO;9RSTCMq;7a&7wbPZ*4nuu5ei}jye3EAZ z2W%Cc1HJd;)bDwj+pGWTc=ZG8rnGHnYEdwX_|anS%^RG4pbU7*RLas&{Aww$obUcX zB$z$9u3zi>`K<#Z>g!ak&H5 zEx?&m884~@aP^sB{Quca=Smr)p?5my(qnrdfaITaLn~>u#2t}ed^*H!PW5VN{_ZOAwYhq zTb=C1Oyfjv56P~5Hy1|JZOvNI%@$4nfX43G%P(g(ZYQR9wLm>cq1H-oej~5mw4{Lu z=diyr+jbo+!T~uY-Ri7Xh~dT3iC@Z2n= z=ccL(ZS$)Ewe@B=^9fBe3!kzcldJ;(9F>^xbllduiPmFQfh_ztQ~@b%ZpE1hZN^XAuF*RHTs3uQ~R(c*LoFw&9`F7zGhgCW>go3xM+A{f$I>w^3} z)0hqBf&(cn6CD7*k@BxWpYenV=u5y}ThnQ~L+~fmK^p=RlNSS4Ty^tw z5e`6RZTxAu9!HTYnsbRo8T|FM1@I`a$LCW~Q~c`qGnO=4c@1Q^aHV~@<5C2+A70Td zbTdZJIXrxLFV3}WA}F*0KaVVo$lzqeMHGm&y?WarIQo26(PvJEwfEf81D;Ji)0?sN zM6$kify1}xZr@zx!l=Fe)(-r1!BwGoT^j$EozGdH+oVyW@BF)EPf&rwe&(8~ZFu5` zBD9WY&4PSo1jO&!19=C<^D`}2MQ_f1=8K9c8Ze zU+Qh&%_p&W)i)O8g7oH%4v(FdnNL1?pOha(r8^I*^-Va6ni;Z|2M3EVT1^+xD?1TI zJZxx6=KIe9l{=rT_iSlBrn86DXwu=~oOZz$KnmAl3xOjnIbVGJ4jG+`{1eKg)wwuP z2-7QM)fX2xW>LSaI0ZkV<&#RifBXFQP2aWEHckB5*{8!TUri6C zS1kuJuYTveUV!-Zd2rjVYGhArtoztLrMf3^1(wBLMME@l?gU?=jw8z}l2D^O;4Nd8 zxnvD)0vDb>!0I&m+iX{1s>x1GzwR?c^)}#wa)YSdWy8g9WJ)mN{u$P)gCR9@y~+1z z`Y8V0PH$;B+>h{+3_OgbLgCZsw&0s;_BL;z{ zp{e(GeCwpWkPnFU05|jUpwYhQHJYar8fC`c@eb;0tHxhsJ%o#;yhxm@LrJ#wzDt1} zx+lB^A>vE@LqDW7+Ra7P9(`z6M53ZpttW^+6{q|6dVqYaSpG}#s#TCol+YLrRdA0UP3&xL>^H-C3Rk7wDq_&B}wUyifs-F{5MoZF!W{B zeBavBe?-s(jU07r!?W~x1q}ZE5~~uWtaK%hjEteBBI$DLe|%^$T&4ibefF9!26-WZ z;?p&NJUQFN&y1kMeKTOK2}xRNZeX4j1*P%ybo~4Bpm-Bu={CcXIDG@j8{G0OmjTKh zY`6NTOWV$&$PJq!rX&5Y3MmMY9iwTXPBRJCSQn1d353v&3?7WBK_G0cTO!oGpwVvNOy za-hzv=*)vk&2sCx$kS3U%_Fbi-}^& z%DJ{;Um;X^^l@Fn(h*z8FXmBM1FT{aZJ?@9B7RE)3zb)EBb$bVs~j7MFQ5{V;&Rw& z;k`)F$Xt!N>nrq3k4Vz?_Bx^u?n!Bx{{p2_XRFL>CvF)1kKU=_m79U&t1Wx)>@zC7 zU2+^#H<=B5Lw){aObtkYXZDUsAC~X#g9$E3H)J!eWp*_eTLt86@cOr2#Uu}D_ZYxz zTI{ju{P>Kn1{GS!t_&LIg}CP3*ECqCPOVY#u+Cf;&@*LO(KAlZ;21zFe!`vK*<5yn z-}dJmeO-)^G*MzCB&pK4r<>OIfxT?QxCCM?Ox0poa|(MTLJcl9jfO5|X#~gQRB>I{ zIMAoD4UdCZLt96fqj_3o`JSv8rwF^wt zn{J}K_j!Cy6AWpV_>I0SO>_Hanz7FwZP0M5IYe#goZd}zy`%iG*MCUfkUM%&sd6R6 zUF@$-N~>m(j%I&)F)lRXvynrvB!wd^*DVUJrbMNFM4^zR>Bi)OS|*k7#zC{fz9chJ z?~JUfPnmo;$YGXiwH1}*iEE7EYSpvO*LgOOn#(E&h+b0){*3AlS`zkpCu9-sx?a@LQQ-?o%Nq)R=fMpy0p2DY70N@$KUVeW>kPyZff8H|9PM zb!kn$v5wT#)$%2D(^>jgHRhSqKe?So`)k8xzCnENLVwxZ5905owWnXz9$%FlSbN?h zao;n|^<=s-Hmdc=&n|S7-VQa&~x*enr=||8)2d8Xfw}dj!(QQ#Xb#FEN7hHw zarW0?yq*mvB+Wpwt6;^CX^L0Ns<-j~l#qLJuKU0E{tWME_VxYId_LDGtoYAo+tP1) zN)Tm=q5sP+>;9bfY{`r(9Y+E#Lqq*ES9!55u$w05VYGjaIzhp6T#>e&Gng^33r#l$ z=5NA_%Navcub(LjsjFx%qW1Kns)|}7;(Bj=?uOQ7rbxQ zv*@ZqIeCSZA9T9%AsaT)CtGYur{+a`yUreH4fqz@$yCVvJ2KU~z_tEF$uc~L) zl+r+qX$cYrU1fOvW%~;{nveYJLAoulcYlBykGRH^a1Cjfw!IxW;wSs8@hAPz<#LKa; z%#Wx_{+*7s-0j$1Gg8W$TLT(X=Zr2FiPc-b$6H}GrvevA)ibca9IdAi^}g>r%gFM4 z64v+ixXlr4mo1bKqMN8$Jk2TbQc=t*dkROQ==N3gz{pGV$&u3T7DafB_aj~Inafs_ zMpX|j&BUAz%p!%%kp~>b2csWIiJNz`h<7p&^<3Ezze*D?ZDqFyFX3&tAVtYpU&;?F zdU8$={u&z&CX;6MYxgzd{55Qy)PP5uG5Aix9HNM;VQ6~W!@2%5r)y}Syn=-*zwTY} zDw+K=$bmEVx77tr+eCrN3B4w;(j)bz#|&(-3H!{~%FC^n0?Mp1 zJ$<#&m(!X)6vsj`Myvb$Q*Nnm(r70+)DjgLZf7F>QkCfNKL-$LJ;Za5s~%WxcWd1| zpFq2eDie|Wi#fT`EjYKkkV-tBv5 z4Qe>2F6h7)Kmto-1*B<6oc!eQ{Lkfab^>fpVFQV0SjhycY)Y1cMog48ltxUs0nr%b zeeaGd?+NnG{&D-1Z->JL?hy?iuMhP;y@-;6DrQnei-JRV+d9A(i`@(DkuGk6Uxn~ zD~N+|>!+pQcdg}0B7rBgzmt^>;#VRn+@0H1k9nImrs+l!mqA;XlneiCu@i>SuOJlO z)Cv~Y>;(=QkJ}E9+vm(-iZDg9Unk7_5M|*&2s|4)3;N$OMU~9)-#BJ90|YOqUw9tR zZe#k1S^eSb7m&b6Wn?;fL$F3T0oQvRM7Q3^VA<3`}mB zLN9Kqph91jQgiSY{p|bYEt1uGYl5SnDl3&@rqajpXguRg4D9`Ft^OYiV4(5C#31Rs zLV8kyx;HDuhR#{WW+qE9lSOX8$B@^puQaaDHZ z`%-{j%#;a*V}t!go04gfVAvG8b4R4efa!SEDMLyPW>MDcvD-Z3WI%A*3Z29;szmjq z2yBm2m#BR-K;9s(Pb3o3(fqlAtpaY)^YgQW*_2j}*}H{3!rMZFHMcU)t@J!AElKzH zeg0{{yU1;}b3)H9mGB^;2}}b(q5;fhOYBfGqZ(Ush4qu026_|HTICHI#%_Z;jkL#%@5Nful}WJ+ z^!pL>l2@pjk;dVS=YmW01P>cuSVKPTCjQ) zfpud<&lHXGB9(>t06G*dD#_$()nfCD#!;Fa4U-|uaf77BBr&}QMQ#V+UI>c#IzaLI zFA?;0Jb|;3NUy7)W{%I%&`D>So9GXC=#w9~0v^vPgDN7vB(QcJ@+SLEsIgzm{b==? z{k3$-RAtt!Fg5JB!U=Td2o6J4hvWrwu9s5M_49pj?u(6N*$(G9m2EAQZG{^C=iiA+ z%{i7lej?urT0WM|P9$XYVGzRmX-9Q_6Y|U*Ab@Ro#CcNkRz1(Z5~RH29(owKyBRKO zWqtJWDgT;!m!_SkyOWKBI@x3{IdP#)`fXu$Ap_o1U$Q_j^zCc=ed^&0AuLr z`LVb1azN4uP=@LWy*v_dkP8gQWt?HN?P%HBki_pVLG_!PyYTkiT4Kp0u!;VJSFh?}D#nrG z-V)aXmybxW>15V}s8aV{ogQb<<-AH0dCToIZBNPl&3Q;<#Qo)raK*f7^KzAQkqqqI zjZb+#N?WpW}Y3=(<2iWG7^mfo3r zjutI4*eg1~wx|vr!**ZZOo9m<2-?F5v^?9Y_n})_fYd?##x{HBb}3-J#nR}?%}5~Y z{L3oHsso*JGky}ReH2>s!L((ht+iv@w%tOvZP;!bLi#>dqw;c{th!;Lv^;_NhU!K9 z+6MjN8=qIA_z7Xo0LKpKHn)HQkb5I|WzVqjXy@HUQ{=Lz=0H86IP8}%Ar-_*XE_}L zTnqct=4C*g)+903{=@3o++yCFNJ!=NX@rjHZ)R8ECs-d_(gDEc%dD> zXbfiJbFx)+3$>_s4Hf))73P;Or_r5G3cG7{{ zse>0%aMBKuFqwz;^A)p=i?h|SQWYZ$3?EIiwX-FQJ87k96_t^O@1)&~AKi}+RqXbI z`Rp?G6t&iW(zNxJ9sqgWt)SX8cntUyXAPRcNp+L@0t%2r+Wsfv(hm%h2F{>h&4G%S z=UDomHoqH{Bt(ojdINrSK`Q%v(-|(1{6>RpbIqn+${aB-hU7kXSwpyJ_~r`Zn%&|A zWU9t))Auw&MC-D!Mq`E%we=~P2;Bts#}8L*Z@iu10J`}0zB@-QxchGyg1+V5i#3J+7EO%Z z?ui?reY{dkbLNpS7x}A?BN9Q_-<2vZy z>^#X!;FIT(_x1eG>$wTLC z*>>K%+I^1E*rhOZyg?W}B2Y!POe;n2Ga&Fci?Q(Pa&N!i zX}y}A=9)lQ3>~xgVAvwFPW7a~Xv2YV62xFSOnJHK95aC(%l#h8!0l6h1LQwVpNpG; zdn=r@41mrVWmWtU8ti8{I7rF2(X23sPX#LYXW|Kj`F#Fq~9c0_lCu#f(R zYi%+px)D&XcC$=)834t$NbWE@QcG~{$T#*?20yNKh5V!cfQD$$($JS_R!7DH>PGgy z1szYC4ZzOY#fv?h3!8udq3H+j1zszWW3?Wc8#oWqPs<4G-Py+r_)L>IbbCh;7~bzS zq!eViBj}1(BMTI$(QX)`7d7;VeeYAdBTDUH!%iybnQ5Qa1_Q$hhECgG-h2GsX>!)K zHr@BxP4U|;e8pv`-f`Du%+BEl&fnr%*?$ny-az&ai@9GtdN6EtcYY>OavTB}r7V;0 zN49Mw*e0}sD^eP(rTo+wliv}Mt`CUgpZu%k$9u~zFH^klk&FnVA615O3=)l$+ zeLiSbWqEJZ7!AiqO&%-f=+Ne{pgG~eJ+yjLia%FQlN&P`N)+Ul0r-Px83*av9K+7i zg)H~FjX@MbAp8FD=;@IcU9fM-yT?;$09tk^Lpfj3sbN^)(@)R+FvamORqt)FOwYZ| zx2m1L$i@bdz+(m!7NSK^{J!)rz*gisTgoLKCYQ035Kk9e^q4t8l zLA{y+^BI5GK_o_c%jXy=hF-ffjM{vQ4NC8Nq(~hh@&_z3eIsXPXkFevTj~igL_94M zykFJ-MlRWRIi>!NTtb=X_z*?F5-oL`)^wkouxPxXa1)8&g)Ccb%=~Rx4_Oy4m1PDUKA7XC5J9c4?i0^(I$6y_!Z@+}esyEk*%gIsiM`0~x{M2* zk!AC~ucv>Af?PbGiRv_&(?4zR6)P)VW-qBj$drIQ2iy|b+ATU?zV$6uoLRwyfu9`- zW}R%zaI#fLRT51^mYVHI*+CM_N18{_CCk0#9}kM9S^E|`jRdzR?t50}`&VfLx0FY$ zdtCdb5|^eWD_rMA59HQc&P6M!;pJuqNjEClWcG$Siz~8vowVSN9 zv?w8-LBA;rN4J9#mk|ya?U*K+g2dydgr6>`4sHh1hhPs2Si6jgk$jA4<%qw30uZrg zEFEbwGc*86?^hph8X_R9LasxQj}x6zKOv^_PiHw#_txGW zml}5~OOX1abDn;phkg1Khk>e1g`^3roXxdHkn)Df&S0a@NTc2PhK2LphtbMjBn_D` zPb@^HUG>RmNRY<8@n1rt&3v{?2DwajIR|6ff?h>kze->zA#-@1M!BmMZ@B_B`}sR& zeo1~wK_3+AvwXjg6WFMsckrt{p`B&Tpj#nMB)F5b8GG@>7CSr6#vaARL~ug{oCV&B|hB{a)A4y z?V9E>3UR^WS7<;LZer|`xdy`zzg5R$NZxLnhEQ$T# zjuv&UqS|#?1I~Db&DhK03BJHz2D_H$jeZPR2h^N%g;X2C|JwHKrlX$tNiCf1r+MQo zQ(Aw@91lL+z{iL9z8RV;l6E|-t9r)FNAZHbx5L}yHWO=>CJIA_=nfc~BUWf#i7Ho+ zWInkpP-(1YO`LoJR&!I&BkbKxtrFj(@RD1WBJPCS6oJ=%Il+z!Rz2!8i}F^?=;j07 ze(d`pU~EK`L1;G4Vd5kZo&c3WXr?KMYG>6vFu1ivQ-T+Xy`Q74zhFFq%tT9})xW-; zC@lOHSd}+=VCeu=sZY3gI`pvaCRj+Eekwj*nvGVti~qDb6*ga4OKH|@aH5mMj*!>6 ziqv5{D)sRQ*P70pm~U9VXdZ4IHKH{6OS|{&8?`OIfDbWA0|aChs7CYs8?L-VHY z(>ly>rPK^!rkuWMcx9Ayh#D(TUCS;d0>C@W#MZB8CL$V{@e)wB>-CY6)&1smCOY)j zjrgwKdKGy5YcGznDCgahXBJP*+W6l8HvTZHR1&8=GKi+WdOE~wJ9_c7{{>n%s1NQG z>ih6g@VA?0qjTs`frmYny{3rG)QbaHV|4!!4e0U@(1j}v5$~Q$y*=b2!YJ1eDUBU; zfFe`9H{hbRG4->;Wn@VqWgQ`cV%R-<9^m>Gq$kn&M7X$}*-=(IRbky)npMVB-n(rR zYg>l`7zv94&Q?^!Q9t){iZ$s>IiO)^$a(22jFjO#QlZ(XL2071yOsR$q<$v|woE)93)g1G`SF zN8koel)gL6cduEb^ZUq|*5K1wWBrbobsUkxE0So;WoJvl&Xz30J=;;qZa5j;4jmzG z8}*6!P)OXUo!sho#NG)zrav4G^C0+32HK;kU*m)hkPcdF`c5?L|j6aF(}Dv4+UrxSR;=sOf26j>p73FUb@cFw$-Bf3PQY8XzUy zbWbYLMc1cC!lw(K$b5a--OPj@wAg06;hWY7b|oVB5A%f5kKY(M+uE_x`p-nEPi!W^ z6Us%SddlWykzUf-+Q`9>55ls1dCt^iDKj{9xu{}N7yXn+bZ%soyo2s7Pj|SCffOn@ zm4uZZaQ0WFCs=saHT{c*z^6xS!4Y40`?G}D$w9x|*|6TtL;0Ta)2yN03a5-AzO38R zUpx`9aFUxj*2Z~RBU;>hvp1;rCU7okl%*a*|S>z9J zt+U=hWJQ^*Nhwylz)g2C)x!m3vFp%kXob0Z0QH;^->ov25}OP`TpM>oA>2r5ra$+d zV_zI7fh=~;ID1B%+TS?>prN(jwa)!a9k1Ct%iPmx1kCBP7`w|G7{{lzwf5V$fCOpt zlS3aCG8xSp5EgrV@y}KMbFqB@esbGS7VMElrZfEk&5>z7%nc`E8j#Dt`jvBMo())J zN;a;9O{MAU1JV{fuSqxWNz_=8hFBRAnyArZ{a=p&sdW2X%)tUR>=xM?Dh)&dj-QUt zkw7!cnrC!JKjb*E+L&~~=FQC+GWH}x{m&cuqdg5}UaK6c;)y-m-~PvVVX0k0@}aef zd+8L|TYN3h>1UGHwyN!Wq)mZ6rZl?)28!OV^T@Pw9o-UOdS>YI5D8nyj4eHj*FOpW z$89-0w8YzWaDbKqV~-6^9;bk(>&<60P>%c=M&!nid>PS(HO~*f0G`EzU_Fih3^jI; z#x0oW9O={2zEGJ^_$U=_UVLl9)Mk`n=29|30GQJ<#N-R z10<>4;Wj?_e5G#55?2P&um(bZRo*MOE+T+ta#Ye zj#F|YPSPr5EF|M=3yM# z+_zc#_p{2~du8YKUkE?N$0X}i09=Fuz>NzO zped98G6VhZFGyzqV(j|up%en=yf_NnU+PN-u*>uAgj={qM#6 z=iW9T*y;5YniJJza#&z&Z8d8B$I|;Bv4o0~&uNJ7DXLO(s}d-h+te(y&(et$RUu`v z*^8g=!Zu9n!csl*m-Rp4Rvx9F@;Q{>)Aa1*r6vAa7WiK=qZR!Ei11OW`qg>={muW1 zCjQvXh{7H3FY3R8%s=z*|JCO}b9WYQ)t~;K_u_?JsHbC^iZlOv`v3dCD1>o=R0c_q z9lrQ~{H^CMFrokde_r8Rga4b)ISga1fcv@X|K>cP3Fh+o?=|`Fn_8E`B4XE*!ycTE zmv4ZEjACVGwoCtB{)FWIyB9=22y?xIYo)8Bmu=Fy7xvzJ{GQ$vb}a_!-&}BARj5?E zHl~^KVIX@P(Y)Ju^rx*TEINS72h5OB3flD}s1ZeOeXkK#Z*{j*vMQ#=QkNU7`E@wf z{y&@oXaW{@d$MlOh1~Eg!EjpkhIm5GV*K8AnBV$I^!49pa;!aIgFDbztsWaMB_tZ? zuZHQHYPaT402r4_tezZMsSjpZ7%AD;FD$mKus&n`gJlci*Gs=w=$)FpMZe&f}i ztwQeRS)ZNyn!*+2FB#+nia(wK<7BW0gyN9p>mvpdgA`HYgF?pgLKKO@Fujch05stC zS&{QGMT@l@h{e%lp&?nnY8S6|Yfj6FF3L6K#cbtn^Eq(A8a8hL18I9SwnIvI)>%qc zicAC?VU!^I`5hSgY7VNZ{^Iqu?cyH`~Bsi>dhgl?0U0|9NUkvu=uEsbhAf% zjW^u)F#3A98_)D`h<~vRY*byoH+whUoBONI z=q?KG>sj9m`*0imtq&Gm_R#^ajr5z~IBw=$lwIY6BEfb6Y|9q@5P$aZ$xL`GCFl8?YBD*DOqMn@1h@WtBUd>u>>OL^*+&! zgS9=@(3c$hAiYMy=T~iR!)1XW01qxEd3T%A0c*ak-$Z`1l64u^RpUKdqa3V^n=HI8)r9rLKGUwUFJ< zV_@?~_ug&)i}4nGdUP2L{LP>b*lZK_KN(>o+ddWp3CBk9I4`(_Az&;m!O79F0}`rj ztHN8ZT2Bo>L`OXIZqSs7>v6vt^*vXe%#%!MtF|wh#BL6fCGImh_|#(hf3R4fM*`8zM!7TzAN{(d zKzg724$K~`%D1(AT%7Eo_BZesTR3tX%=ZPPfG(dOn28#_)W6!)Hk<>D*3-0>PKR84 zLd)>nl&5RX*Sy&$6F#FZP1{n%-*zIevVpaErWSYbmw6!|5DxPaP!aKthJ&*k3{;-N8afseu zPS{^f1WMuUnhP~d`yYK@u&+S8)M*)xw5xK*@*1noj~r(00|Xv>08Z?lshx+rlUO|8 zs!-;9OynBYzJ|(DY#DPjrR-U4#H*plvm>MH^BoYvyc4=YC!3Sqq&AmP`**worccMK z6I>)M9@lG^^IVPoKg>ybd>QY|VYF0YFMKu_^wSc&0s7hT^HwJy=_AKBHYoT6@FAS$ zi~jwOpN`nSbf(=)*Xws5FL^dHj;E)d2nIWQa4vh&T(Xl(p-H5El~?2QBGXS(Fa=;T zRY2=4qx8kNOTg=Rc@V9sjVZ$Hutw)8H#PJCZVPBZmvwhrjsu!#Wtb8#(lx<;<+tBKCW%=Sl|utYs`rzr z{$%jl<|%{ex0+DCJ-^wPmRm?S-xD`gP$UiaLb(uZTK_2Yy(T91iYv%eR&Zsf^q9Ik<$J9gKi6)yv$ zy-s^nQ#;+79x!L+m0ZRqm3NXD9H_omrZ8xz7btTPXEYH&o&r?pi73F4$GMT<**(+7 zgzGWwoze%2tpN_qF(IC$T~jWoClQP9cd3R1W~#QAZra{8Tn(YW`I088W!9ZKiPJ31_$8OSONRfoIet#tc&6Kz#*FGO*z?< zar*&_M%B4t+U0Ri$KkK{TlO8BBDC@i6U{Sxf4fE9q#LfL9OiPUfQ2XTq6ujvzfU%< z351789)5qoN@!n!OK}$Kqv1CD2^C^3VetrHDi?g_M9zv^=K+E-tGPj28`P9i=<>)Z?k;53m@k)v5qxugioC+9Sp^y(h%9o z0^~G+u#47$9XA)}Bv({K zNi9Q$-rKZlW;#!vjuSdZXoyW}qPsseEJS03$A?1{Zx(MZeB*FT3&z)pT+f=-6MQx6 z7-i;uJ(H*Q+5P=d%t%(E32To40(u0c0fET+0dwx32$<_D`SY*Qr(dmBtLbzk5jES* ziFY&ifL37zB>Y`OrPzb`5Y?egy;-B&P2N(DQI}?+N{lBE>BP>&ibmy~;Ez}rdb!2h zx$Ppe#Meic>vKpd_8Yo|f94aTQ2kWOI~uX>Lv()l9p$u%yWt{H$#W z@Z($C*f9!CJJdii`=Z|3j(rcJZ6+OFV~BsVKTLNsbaN&(>S;ft3a(YwLds5~ zBeJ&QrF@PgCqoN~4z}Chd6`WFSLfzYxIvgzRyj&Nk5(b_-b)Yqm2PR_sd#ZX^uymG zSUpy#>^2dU+0EOxN9d};JBys`Q9=}~tHfIDCoziD<391z2kbOa=gH?KGo59P=k>(z zgMduE1|JZTgtuC@>iCcH>iFl@ZpB|uOI=uuy3HigitLHm-E2r*6&6*Fr|^SIeXq7u zLsH)RcjWrWX5;7cKYu8`A+P$O@i3n|1B5fn31r4Ct_rM;t`Vdmg%Uef8myaDh_Z|N zvNTZ*yh0-Xn|}m;`XXUDd$aS$@EVDX43%U?6C-IAd<_=bD!$9To2wQI^F#tV_?@c; z-;+HR4wb@`ZT)W{ysr`$uXh#=-deKhnhJbXOK(9wXf{H>HavVin$3RwK5Bn?PofPQ zvNE-}*(+5z4|ttdbX9J)e6Pynx$u}e-psvqU(ZwonZ3kWFDoZ%rL;E3eVhD^xG;7UQBL3O)Y^rQ!ZO9L~bbbi~jMM+LS5%q+M5CCvAzZ19wD ziqGfrcltj}`k^>)SUZWqCi0&o7uz+E^{l-Rg@~TpjDXSkE(`gXpo)AtRK@wO`+d*2 zDQfC|LklDWa9EUAlWe#im0q2_sXm6{`sYxzkMaX8Zo#r1DyQj+-B=^4a9}3htiQXP zx!(JoCSJ~)(nlo4Eo!LL=bUEM(K=63XTb+^9KqMTa&sSm9pVfz_XT&4UN;v)aymQi zs|iblKVI}du$!104C^e~)m=QFusSlBWk`}7QoZI)wYe0V-%u%J4Pi8y>+}SCKdVpk z4bSuMB&DA+nq6aiO0hRtG#x)iAxRKTCnY|}yFNzNHtkBUHir&J2`8MA!$n_@^mm-7 zC<}hx^VDuvoHZV3#&V{J?6TjKxr<+yVle#&QGhS8j?VcfqUC!YE|0Uk|1?WTfn_Eo z+wCHdIr}b9nu{Rd*tRikb}y(?O|{$XY%A$Bl2ob|r0aN!75StRwvG(O4?7QJIa-oU z6m`!e%nK9Nrs(=pAHYr!*XlwY{JvL{zTVbu=S)Y1EhQ#lUJ1kGrY2upUu7QZdvG1yH3dj_0o?y+(xZGq zxXz$-|0Qhy$UN}h+E1CFh*_Xw+QQ|WlvN=Bnk1@8JJWJ=a^s^;nJz0*6I6lE5ZM;R zn}6V{x^#)95!q8cGpu?&T~*!NNeX6%E*gi@BwdWMKX04Ri?Q>BveGiQXFuX&o0@ra zClu`ucK5lINdn)k-H$FN#Bq!@0a+QllsiYWAx%%WhpxBz;|t^2cYy_YoUcIrNkSPD9vo{NiLJy2P|Oawi(BT@4Nisi1I`H zRfb(e&3JyeJjr|!hrYDG*=fljO&$d&=}|s|*kSlugVo`P#fAhRE*tuSN}bW|CK>&2 zhD+mF6&CcoQ6>e`owvGTzpyPnO|wy`&8-aLRbk`b>J1F&yK@&uzUS7v!MDEyvOe?b zEWJ}xpjDtj1a0*eaIxKNelf0$7~rv)%?x6@Mxg@Q7X@Sn*{c^|VZ`4q0~;m;+25Mx z-P2?=nc-?St)f!;rJoNDRowVuPbmLYua6%CXsIN3Mhh(7O8o6vySIi#P$k*VmINrG z>3yOG3iUYfVhh$pJP3W;*WI@olxQ|sp;B`FC_b7N6i4$%^;Y)ZOuW(%vxJ|v31yPk zywM&5kSld%Ap`9JlHe1*>vNsp_V?x|q+Z_K%bs~pb9uTGei>k-lT=Z>Lu3-O)}`mXy! zwcQQa$Tm7<&liTnYCCUnd*3vDW}&P_8gt?$pM?g9qm8?UmtBV9%6acZ3ImgFctIKM z3ZNtF9Bt3Th~!(5-)W|gY9fZdeMX+30E{K#k|c}zyi@hE(@LCgBdwXoct;Qy_ORAc z)xY@}ftO|{q0Q~Jhwsf>)qY@6bJa@KcoAKO0etnRqoGR{Q|% zMSGO-BlnH;cv{!M!b=IVcq(#((!V~di#eZBKY=))h3>@;ZPPGP%iJCk)n(s~h2TZS zmMDP<#Mv`IoG|kgW-apBJvR2<2_pP2ZMm-J8pu`OTpTxSR)`L6(iCwj3Q6Sx=_$8t z&J;I8UU^Z@@?<+8i<;R`k0%$xVf-<5R6X%anL~HfxGlDi=g`#p;QjK|zem3#xm?c=qA(Vev9M_fRs4xiRx1Vp2<= z^m(Oy^}Q5^Q=*$CDJ91a7)J9hO9b0Cd(Hj3LqW%~vfflCy{~T3 zZN{Z*5mw7=eBwpbV8Rjcz?~r0mP2wW=am>@{sH*wKWr%61sG$JH1$ zmY_W0n1LTMJCa8~yxZS+RJ}giP;ADEMn8l0@2kWc?ST412IB1}%gbh)R*c(?G=em) zXF~2vT=v3#Bd86Xv`5yx0o3B!YC15KqiLR8%Tc^%Ch~lgMel&0JukzGWEZXFJJZd^ zt+PK)$F{vmU!)NxDmkKYDS?+saaqkY^#-={w@`evXehKV*cbC0ZJIzNbrdEw%_obb z)`5frnm9wBRL@I@!%Xo7(A1=jq&YLo`rG}BG1aTFKEF|w7|eUK=Q@QY2#sXPM+KRh z;(T0fq~uynz@@)=M(y+a{H5pDDU2QyY9pZEQNJl}S~}uf#Bh!ZZ{(?C&gqtFgZRu6 zCw6hV)6S2*ewK};R9M!_waw?Smd{ixpWeRd`MF$uUO-Z5)@N%K9}NZ9*5g{FeE?vlmykDXr63x9gB3o9 z55E*xZN5!f&2Y6#J*RTO_K7P@kP3)$Bl{RZX$#dn9~inE7)8KT^gY1l@wdY0y2dZ) z_xb*OyPpZN4=XSE1ft1k;4DDpeERFSq|{gQ$gk{#fc6%iMP&)8?CO&wpw#M`UDu@} ziQa4$S?E(6@ly9TF&-OVT@QUQ;!Awbtu!)WANUG8w+PhA5h~qd=*eUBp^Mj@slqes zQRb=Uv>r7WV#o3T`I8Wdj~A8!e?oh?^t0p)61Ze7@aH%qW?yzBiWE{?UjDKG`t}W5 z4``{e=RKKZWexZvzJM79iy_7rV3M*pBNr~D!L?8=WIXZs`XBG|fJ)cb#NYEQi8j9t zY|85YklPuAi^IesBzDyG!phfSk22#Au;O+N?^b`~VxQj%8nG*7KEJ=s8pz`$snF^` z(Z!mNhOD{r6~zW8I1#KtUvmneR#{*oL}4h{)NJ0B&m~&jaP#Gb**3o|r8#LO02Y7N z(0!=tsV+5><=V~@5bCZKIO?VxadNG$jd0r>E3!&>B!!@YpaU{oOLmptqfN5ko}=T) z*Y@Abv4^{J&&@hYtG(0anJlnvGGD2uNOF`$!-G_=No7rsUZsre?H?%dRDG)gQ^MZ9 zX<9^rgoLlezv+5(%?2W&>S3_PnS{^M=kGyK=AmDbxcLJ!(FrQ6T1kkajF|8jMbV=y zY?zrZ?g-8%O~N?)X|4AMPCFv-D{6xklP4*{I}vtynY`#hLaMmbUVO#G^BHF#N4cxyl85kxOO(zkZG< z{JHrkbfi~EmRG!Dp6WVNX1RD>`QmjpquE?>m$GjU8l!i76tTnL4dPZ#zk-L#=_lFC}!lp)Hb z?02X6zxxyE9A0>=*#_mGd>cA7uU0p-Y$T?4-JGd~rVDXdy0OHS405NL{=gi$Fx>*^ z<s~PGvYl;o{?4K10ec~&f60q_A^q6C zm_GmZ*0Lma9;h(NGJPnQ`prfGH-Bv42hLYqV+Q`e_f@Iv^!?*ngcm%FAIA0jCHu?L zIpb+z)`ESHoRwWUGC<0Xt|FbC3^p8@IME*?tbGtN9`HMFeA>ZPKHodnKi_oSQmONU z!7a_*({%_8;>E(4Yzgw>-FKq+0@}qqe%FO|0MQ{*W1A8JzXkar6S}p)u+t=k$ZAVf zXP+aA8IE2unt)g(#rt=rh+ABrR(hp3qm{FEK^DyGi^IGayIN`CU9 z0%Y_q$C(Vw+t^!XM3<8>`hB+pz1Wq$4)a*V-`5aCSCc@s8rcHdWmvRqD`N{w7H6t0 z9G+Z`#jNYJ7~hfhB~iFq@fjpoXpbN51m!;(Ja6Q_sNfdM-O;4u2`UUF^bWtqHr(xj zknjjJZ+-qM-;5_0d=)Dyz@9DjDh;rVTX=8+<~u5Ub`Bj%MZcu}IaPZ+YM925_rzv4 zX?rK^k6`t1%*R&V;CunJS$NrTshylUXlLP-yp}UWcOh4?VKGldu6g&!7cQJb^D(yB z38RP6CJ;99yMB}AN0t)LxS^RCnVhB#bC63u)=zo{#p^63!r>KKD-z-v)kxz&%C zrSN`J8t1F)N53Nw78i%Hm_lkI_`Gq&gU;?~d)dlN^xQiswP#VVrW;{vv4~L%jkq6y zih1OAxOai2FX{=lANT`k*ns65;Z;SsAU0*urwE3iep~UJ&J8aPD26cobe7V=9GO*K zgB!v&16HVXwbYjrp>hCmgEBq|T=j-{VXEfkDb4;!>sTq}Iwxhd4cuC#b0w_?d+BX_ zY&APh&%r$a|76-*X&8`N%GD(hHa_CVHJO{Ee!hiI!<<~vsw~p`;xUR5Pbk3uSER}g zyBhc^P|mIqT3CS_l7y2u0+C_3WMx^69Y`_cj%GJG2dAnguZeFH*p9pLF$PQ<^XWpr=kdm`p_nDL#j1WMtN)0|eH@T= z5`%ov#v3kP_(a>Qq+G(tK6sYjFjB&i&EB0)eZ_36TISu;JC#+`aj$10;MrHn%qLLZ zp<9`~2mai-^mPk|x57RcYM`2=cA}T$K^%+`A~5>|^|e}o0T%=@q-P&3i9S$DnKNGL z=tU^}X65S%idpZyjgxXj0#2o*F)_$w<_I3)|D!AneY)NYTj=*B!Q*mL4YP583~Lr34h8LBkeEOk4WW7R(sp0*VhSVig0Xw|8Wc!z-yo!XT!m6 zl7Z@Qs5#$FT`Fiv)*Z*sLjIurD_5oAjlarU_$zGdY=656XzZRI`@zGd_H}-*M2H+F z6b98*UgNWa;7>=1VfvaHWfzvTSCbnORrI>QIGNuW&1MBV_F*}~C~+!Q4*CMsTi0-BzS?yj`D-hZx-v&+S|P_; zO-bk*1Fihdl6O7!70ITQ%LC|>^bf22cCn6we*Em#>V2CD!YqC}Pwtt`{W!~SWJ$B_ z%5R`-Y1%T!EkLLf2zy6|QgNgwWHnk-on&&5d_fqE4=zDj?)H2_1wW1M3@@&u5b}|q z1hhCHy&8Y-$K|0oa%!WG*Ds9Wq*Fd0ZSLfYu)d3;eMfuC_HKF_JJV$;heHGnzi9+r z)lVieNh*iUgYs zC*O@k*NATrtdnV!4yPqEFChj%nx;0AJTAyD9?L^o$2JX?;Qwo>@;xWwLq^W4w$bDA z5A^Qr5AYW^%=ftWe)C2&X}`YT#~?`|weeHYe3rLbqdVqAj14_arL%1JS$Pn+ti2~b za~ICX_|RyuGw~x6G}lr6l^eq zDBw^ZDaq9b*GAkytk6C+0iAJhnKZMvxJe$7>>hnr@p``dBwd$?*U`THjYPe{Ys5#z z%sB0%JuM%|?dhxXr#ltply5K-LRO<``!HR$NTCG+amz149f;ac+ZU56wM_X}ZuY`$i^s%`gD_9t(u5WSfsH1bo`044spiM zU-!&QWid7t!T}QUCe2;39Vl06Z~ zXkRb60!R<^WcI$=sge-&HS}YvarFkdf-E5(Atyhwptb*|S4m#r;Rodx3uZ;!yWu9( z5efGc;+^w`wtV+aeC)&QJ;`5xqUBzS=Yslu*;rV@Nl9?CcTLa9_*_V;>pjjg zF2T$Jl5&i-n0snb3JHieTR98#4}Hu*a+>n~t%3O3>Ann%CxtOy3Ob3;XQBZ zyFym;Bnw_^{opIF+%NM#?_#;|g>NV?1O`hd8z>!E-d7xr3mOF1l#H+&&OOz*%=2tr z*lgsz`&-%W9i9peh{jf^hysd0z?)Z4O`Kn}?l!GQ3d&2pe&&1ExHaXH53Z#kR_s$6 zpm7wP^*oc>CGoJEF}UTz43z$S^B&8aD>Ln{pJ2U%_$CYKI7y%2ZMu&q_8vC~C>e0& z#>>^-r}Iv9nmX#JrCCg(B@l+qxiGR{q9(kQ>thM5WHw(+A61*uWL2k52xMB)s%Ye0 zH)LbQZV&3uPYh4ZKy$s*+chfu{2HRH{JI90HAGEMRpdS2fznmPGt4oW&O!pnb`IKd z$cMcJbm1KJz{|_daB5#Jsmg7TNtj3@n;v{qlS&)Om-~L1rt_$tGoGEhPDaOHBk2c~ zgR>d=UHZafUOl!{pf&}DBlq1Q$0ACi2A9vSjrQ!Wg@?OaFM?AFK^_$NE6}>JFZVKt zl_JH(tv4ir*2gD85Rp&6{0BjU*JkAqf2nyH1Qh@DY0N+4xV;wtA1?rYB%>tWVyG)d z8t#)J>SA5Lu*PlH(}Q5co3G~VgA?%&GVYYpi!~AB~v!Vp_GRMCRYa#mCLbs zbrxVsn{Tu<@PVSV_&5#&w(CnJkWN>HdNkXG7UC&zMm=K4Q!B_zh_0WM@}O-!u#0__ z@jy{m=~8))(g9^H#PW5bWHU@x8yP=o+Wv-JuB)(nc=5wH=5m@DkH7mpv$sLHo_VVW z;Z~c*jJo$EjnveuC`1dDL%Z_xw#r!1>U_ad(MzUA)Wk6Zr?1b7wzi%NxTd)DPS&s= z3~2D+J}7q`Lu7cB6FR$pFh@;9`Kj>uT<_>-))L0X`nD@pu;==sWHepYNCQs=w{o16 zXwQKG_R4%4_R&CW@d~K$nhKnZpI-GndPu_EHjDqLON!Pj(y(kDER0X8V39f4be_Ul zxbh&b5ULGh%V-uhr-C@d+lLi%eu!cytDv%FZ;BAFyw-{XFT_}B8q5Zk@B{O%w%-@n zJS$sN1o5i)bYfmCY@QU2Y3T)eDGEosFL=X1dXZ8F za$Fm4Pp$UiRfFd!3%k=Em7GH{7N$lgaJZQ9_2IYu$PO-X%Wk|tS^5OKt;oCU zT~hv9IC9ZH)4ZgFM<^6dl%gn_ol8YA2F3D^U;T>4(O%Zp(Krs&@M_ZNHq?F2{*Iu( z69x#%_53yDw4^Iimk*f1LzKrcZYef=y-$m-si#rNZe(%h&yikiUhj%+^jT;p#mYSj z5vJcXP2vQsMg?|RCUbFWc7V={-G0&$ZP&-x73opdKkgQA&08+Tw=t^GwtT--}Kc02LhpZS=J>r z%1`^ErDj$1Kq7QOqlstdb=Qu|=O~RI$@aE7U|b}+)3SP8N!+8`uiuDRyZ-Y|=F5ve zA(EeF$YqHIVDcU>`e0NJaLaTUS*`q!C41nBBg=AazYl1Y4g2x;%P#?ROD4}!HXUYA zjwgbHd-6NDs%>byWO-3_2cp^VaDfyAD%IF%G%*gIseG~V+)q0?yr~Plh|qM&&mS4?AP0~>_&Us$?HC!;#4!r zAIhCoTBke@O}nVQRKp0qFx_&|f35hzv5I#w_)BG|>aouRpgN5TbP(u)*T%d~2Oy3`N*}X;S zu$hKqfy>F^1zVvyTk!#oqmr-%|9}@OP9;~KQO16hWM_#COgi+Mqd!852cB}vSljl) z1sAOL=F8rKYged!?N)a(dFy~ffu479$!uOZEx$WBHhs3f~+DnYLz_oeN zx})7g{AE(3J*P^q&yx@DXRdy8%V^rO(JU<@o+1Ts(^=A@D4}q_!CtUdZzB90;(yvR zj@DJflzxl5sW?yA-=w3!D@BMKY)zFsN*R9b@?eQ_(i`-p)_!WX%$}zbS5C+I)rIBZ z%;v|2@4$}K<;O2P5w{KY(qcpg%f5c>-krg?a}{~AbxG2U$ak1|Y1%;d+VAB@j$-?= zE{1AM!st*t2cH>Bq)F&nnwUeP_=TjlVT&1$kyY+Y?%QH)*@B zo8(ifq_tq{SZV!5i#=!Sl+|lcImM`yNW*Y5ELIh?w)fJuS&se0fF6%nr=;r9T8c`ODvsjyQ{OCuU(mQ1D^xpqKQ^{;ZhXhQJ~OkHXiq zKCOXki(7+yS9QvEO3N7$mM3~J?IE%cNpQd(PL0wbMp@rdN-H|1Bn(bMm6cJ9ZxTmI zrn{Fs6BgOc8IO8A6raKPST^$)w>x04^1%x@Y+Asykbx=pes?D0757qK_a%v8RHy## z(E$|d(L$b2uc`C=%ap@$T95lMz+GyG$k6)>A61Qnp;gjd$6G21MP;gzST!+b>-4Q+ zZ4piqVHD=gSvGhK`mDM#ycL*`W>%#E6CyK+qxL2l&VAlnw5#}fEBb4qo9|PGD`eQa zF?YEudq_XX`f=)$I_RoBC5-=7A2dRqc}4TFqL?NPP&jQ6eZIq0+uNZ~>Yw@OBiU~T zgQD(|>$@KM2R|kSfE_rJs+?9hhGGvoTU_{rB@(I>|MapkWOcc9>G$jE>-jR#&R4<} zUzB3_APh}-Qnp7_Rs&2YsK~Pq-bVKrxwmE??Yu!N#CRV%)BE(vh!lfUtJf?Nn=)gQ zPZK7&CN&FIXcxdt!HGMn=L~t?9)t;;=u_Q{Ki7YH`O$$IGh;B-CzcPi+$i6G4>g}7 zSV}b|DT`EPgDsG#Cbykf!&PlF6n7L5`D4%futaiU&A~*~3jY$zZ#8NMjM8+UDaDs{ zT9Nc_K}0cC!JLUsVXvnz*n-vNr}p#0ZEZY4Dcz4i7gt0J!h)kl9vqUF{HCIV;qKWh zIQufe4Zy_(pNkqC(F&8$!{Ebrb%O(WgC2Lj*I3UqS*mW-Jfw73`GqM^HSP_{8(pJi zh;NQk^Xy|zdV*Lf5I2$R7KMHuf6Q{uBkOU_$0}y=XgNYjYcAp}jH(4nP|Hj0^%fx< zd{8JR@~!uF*?J6p?(m9Az6*d3G&h%HRqyRT_wcw&RC*H=KfMF+Vo?TK(MeT{*XZoa zC$w#W;}^qzCdsdKe%_hx_T%Td@Bz=5Jz&lkLk!gq-OCe?#|xk_>1HU>OF@?c3HtE@ z!*VpP<+rMmK6rw{xSyDz7E;~SEZ9TKYNABCKo6`P;I37SoyHI(RIs6(p*XhQmV@} zm6?NL^-FdF)ceq1T@HD@{O3dSY2V>yV70Y)3vmY{u6aJG*~-n6j6=?Nm)rCenyCk{ zr3QmSuJmvH`-%4O1!z0JQ*g8=G=+Ef-K(LN@lV~OPh$zAzj^8kl>D*2(Ym{Bntk}& zSZ%dcM$EX%gG>3|Y8(?P(qqG>(I#+DtqD&Ek>;ekT5(0^!8(lpFxNclDbY|mQIf^W zPQ)V_amUzZDu>Ip1%Ji4O+I{ROwH3U+n`aEG5eC5RP%Wku<*vo0R$(`-Fevz)3dno z$F-AzLmK?mtTqf!Xco5;*W%fT%1<0tx-XUTnrH9ZDx5y_Tpp&;M_je}F1h0Wy{N=3 zEQ!{A5E;S(?TfBxU#~~0ETEg$bUV5f8_J)8!o^Ltw2&*hMVON7WdRwr3lDU-q4=E? zy`qqo{RpLM8m6q~79L{k1Smei<2VwM7`{+-+0BK4|QZd=@Q0-8D1XW5?43wROGHb)JB6j^Rj4u665cuASD}9H~)N(fR2WHE$3fVXtcailPOtxj|!% zbyG3@R5T7N{nd9##T!Anm>#QMmcL$MxE?hJDoHJ3$->SXvtrQ_IwfQ>O^6Ll+ z`Cy3+Ph9|+{?aPnY4_d+`>^D-?f1N?sdi?2PzQz25=H6Ck4C^UVP%yz4mb!ph)FLO z`kogS;t>KU_pVj|=DLrsZQ!%QGTxR}Tk)4xWyzudGb@;sNvpzR$bf6dM?D>7{UTLU zT?6>2dLykl?^;pwZ)pv}m;@??LibQ=ox*#bzB=E(`f4E`Nuh07a~)<1Ue%R=3N(+;3DaGj9^Rg`Ze0aj^dP5?t*Y+BtiEm&ChF9Ty!L?|vIrIr zdS(g7JthGvkv%L)B0whhKYq1xOYlt?s)lb(*O17F?r5aZX@|1}>t1dQ@$2;YnVe4j zQva1~B1GjNGG+xhh*TM7u}gzJPTiAiAsfz-{fLN!-JM;p0?~;pR{AkBp=l566LJ`aAcb6 zD--by+XWlZK@d$g`znaBl<+FH=>&)EzDl&luEH(^6eTM32J*Z_Pc4GIj!7jKr$=}| z%pqaVrwoP@k_1r=b6d%xwgoEX;*vB@)=0S(zCb?UC;O-Iy+K!~ldkHYKU|J%Gxp0L zOJUAWP8(nR^ap(1oNu--zy#Gq$R~oJ-O6l^^RvyeDNi_j7xA7uM_7x4G@4V`BAiUk z!rRsQpAd9(U3@gpfxM2u2biT3_B6gUboI|XJ4)Vok{#wS)r8kxAmKY5l`8iO-e}`R z8KY>KplM!O@ZXG+JH<^3*}I~x_?KnDW&`u#-yKCp>hBF%1=4nYPOWZ zV-~T-q)z2oq!wU)TZ+PeFqFj^gE<_K{QH9Fr%qOL>8e9)*16GF^(ppx$pGXub)T~_ zv#xH<=fWsx&ymj8s)N)5yYEj(XiA=J6&`TuCA{`j2My^j9E?apMle*riakmi=m>;& zp70Ii695?BY+?;G21sZg&_iQ}Z*kYwmd<{*Ns$PjDIaI_j&vo(i=tMbT4F(@lNS#j zRkMJBMxo-N{nh7I{rRV0wkv`#oTS=IJ$@fsIU$H&3z>#@i+q9js6eDBKYB^zPw-o~ zK|4^2HQ}fD0kdVYT|aD}=62x(zDdRYgWJwN^grd=962-PoH+vHIt3anwAI<%@Nm#sFbk5=%FoGh94|K z-m}?jdc3KVCCB8yGoP4~?)u8_Y{!$EJd1eTV>|42RCSL%6vt}qfoCu{1Gl|t@>ceZO8yY zFPKvyDS_58zxt;lIxI&DlXUVXw8P7Do(eOK(2t}pXp`38eS?2;NY~y;9j)mY zdA(~azQwQJnH$lTI6|LWi8(gNn06QnhC?q3M%9F#{_QZ}b$!#2>{8FKw>#||@xRF!0p zI~TeyZKW-A&Up1Cpw~2{cBZN1=S)-c>$AKXGBMa0>id2q<@C#x(+iOxrvaIZf@G$v z?D5ENm*OqUVX$*^ah|bixgqLw3HwY|Z#E`8u5(q6$nuz)=2mi>IQ$sqGe-a>H_$U7 zYR(ipvkd5_nhjO9v{apTDr(Ybt}fDNcT!thjRu4oJ7GcR<3r(D&w(VjQ1xYZI3PTa z;ASbu5R%JuJc+kx&r7sO`M%Pm2+Lv-5WgE?a#bqH6{pqhJ!JXS79PMiX1q%0yLaFE zhDVd@QX;Nf&bw+aXPW)n`g4%psS{e=9D0u9Icq;&XK~*blrG9|S1(kwsx!XUTTB=u z*o~Zsdh1?KM^M`cCo(BYa1Wu{s65*U7kAEFEs!-L z!P*nt&X1}j#Zib$QO+YVX&oQUwk`xV`;2V=CmG02+dccam-55Z%U@wK=I<$QeZv9X zLqrCWQ?FP95^xs{ra%43|GKdcpuFHDcmkp@3bklPnf@u9)p@#aq=MKuXY?t-@eBnx%@87Ov3jFohR zh11Vfn{>Z|>jMRMWF)YVcyWBY%%=Dv%#grp0`c;6&R7tmP|%DRH_IC%bzX(JP5eo% zYAE7}Ms1rd3H)w{jda0rS(Pi8A=iA`^sWKnhc9u0db}|U-q6|2A=7(7qKh9Cee@9G zkh-G6-XMD0tCy#|JnYtK$71rj^DD-DU%vN$V-~tGdlC_I-x-GM9DnHWgTn#btTZ@~ zKRcm%@&D0w-{EY&f5Z4Ig4laiY$b@@R_wiZwMH9ih3XQkW@(I?wQJNKr9M=xwzOI? zLyWZOph}ETswJ`a@A5hB`~E)1@!Zd!zkda}u3Tr%@jl<@>)qm_Q0G{ikTZlIneKgd zxm?FR<6Z83?yetSub{kP6^nM`*Qi-+j*IAd&7<$JUV3teQ2M}qY?x;%c^0Ydc|dlZ zp{O)fS&d}Mr5BXd0ab-yc`vavcRE~Dp56VkZP~^uEpX!N*zol88&gh>Hw)G48T|~c ze`a7|Xsd3-g{*RpXF6uvU3iZxqZ{J2uTiRYd8Ot;XYm;=hH2x&T z=jVwe1CQms3bpm@TYBjl?XET?$!uoY?Rg^= znQ~$0b0oq{yyt@~fvYg#;5iLY?0#MbV%< z5Jyh}B=eisU0^NGa(@0pOfn!>PM?R5Sl$rC%3h>s-KB0=@^Q!sFrxB=8$Iw}+r8<7 zbtd_vaq7yRcdjYXPESkcbV>XfFpuRAH-E`LI^gi5;!D{XJl(S6Ai}itI`a1-hjzbD zhb?TxR-i*V*Auz|Tl03mXIFu=6B2vBVTD_^iSfwNHsUwSBrulf3$^0NWPBPHqD)~ z?iOCkar+TDCt=fRi_eOU^cj( zr|es^;r;6tXYk=`glCuuP}AYoT@}|`;|JN9Znr&{qaOw{36aHy@(BZ#GbZxB^)h!V zf!raFoVG8I7V?6=JZcelA2-wNk4s{f9X)V4{$}bB0-WM3d{DKn+Eqn}*AaTdc;Gr~ ziuW{Pu0Eh41l_Adw^&W#3tkfTRt~opZr!K3KWw1UxP3)UlRB*Wj^@LHK~#Sschg#l zSz&GPHD*M%qcbqtg*wiNv+iY>bUwFHG!_YykpGsfh`dL4`SL{|xBm=P_)+%7pP;X6 zVipFOJYlPp6m*&Hot$_bFS|ZiG-WUL(rJQ4F>*M-u0+{$rEeYe!-UC}R?tvd1^exf z^qkuA6(MP6ekjwl(z&I1$IhUsqa4hfG0zP-7@fl+lNT+c$~(MUSu2gFpj{3#7Z=OQ z%UiZitB+dKaF^$3C7QD}>R86If9$-wK1+Lh``0mdZ<|l=OYx4U(s;(c@pGv;cNzpC zvGJJMwR`9b)bVNhx8iBvFf9%bIE0a%Op;2~FQjM=pOd|l!}Z5dh>}J&p37EcC{^lQ zCGb5Gq{&vUVOEaetC&i7koI;b`(E7M;y?alCzW(P80|e2LzV`JI_q zP_%>IXlL7vUaEOUL&)?rV&?oyii_~U-x=vzgqoJS;<(|)ZBWxk|(>9nO+)hKcl*K zFMV^m&i=URVEk>w=&`1Pcsh9ovH9r3%TV7shpg@ATx8AYsb=+&mhy+8CH%s4dbM;7 zJ1>z_T(Q+zNjbMOBvbXE23-twm)}Zv^=$gx&3UD{P2D)o8p>kHv-185-5VAGx>i;H z*Gm2}UzBUb5fOj+OdB0;mRx$sWMKT$cjzGM`0du4KyQHuBrVsv=xqL}xTK4_s}@3d zHyVdxrTM*;7IJ#(Q(-9o=hbPIyJ9At@k{fB{TdeW^f!h=`K#19W`~#?mn84}C{kVn zW`+N{@8JBM8DY@t?7DAU>)=Q(Zw45ubSI(Uv=FmPL}mc zz8J#!Y$4r|i(?KSv&^TuI}L+fvN=gCic-SI@EXBSC>sWI8b6Uy>({3VBZgXdo2+?9(WcP$Ym=44G1Ml?8IvOF z`x^H6O)KTo&V&LDG`g)K=Q&=RW^E5xwvV_ZbRiuI2RJpeT%TQcn8UAzL9XpP>|aQ| zF-}~sAvixqJ-NAG|2|iq(0U?82*R^LO->e$^9k?J@0pjMvayacPi4Ea@SazZFQunUs*jl1yKgVemkf&8{<;E1enh(I!YjCgJT z2DTld@Gah_QF>BXVq$^lj0H^T~H^fuZJcZ7gEs|Mfxpuc(SCs9*N z`HohcCzq_5gpoQsRmi?1c+k9&{kPM1U-gM2`TRK4`$zr1Wj7Erem%co z^Y>HADP>lrwO05}v!WhsOu!B1S3Lusotkf7mIm+3)pepye(wo7?CA|*}P+Fo+U3gP)owZIZEtV?e6Y3Sg1l zav}^t zXBSI5mZy7@QUfEG#^g4EUCg`X$UYtS(7&puGLCqMd zrh=XS!N25f!Nx|LFWeBkz!q)bcd+MO&ECZq_?i8GftyBY0FF5W=KBGo9AX_0s7NPN_@Be{jaA2xg-pDi5`(YZEVftM z-BteQfBnb40*EBwQ@Mryi~P^e{)ff-t_nI9U4Llso#}sh5pn*^IsbqECGhiu|I4QiJQ6@H zqFo++{_j&gdyW+;)vb9h4<<)7)!oI>+TvwTLJnu5nS*aOMKcu|h@+uwzwBY@26C@c zfp=)+z&M;ZbdO`s8ZAZ?%a^7Ug5my<@&kfoJ0rsMt_Jcpvm@FehGuHgExUy_p?qG-#nI|G}9CLvtO0748z+g{f;8S*w!`AV*(SfM(YpPBNXcJ*mln6f%nfo z4q~@)nT#8E($?q7rpx`p096EV2x*+4pSj<@eT5p67b>>+f42vx0(Xh9KEsXt|9P4F z8n~^?`Xc7T#+igl)89D_Id_~p;z~`7rryF{TW*KXrn2UD?Zbai@xGoER02)$JX7iK zf8e}N{)(Lg%# z%$Y_aff5OYPa-%pRqadxgpkjvs4kMV5^gfcdEfL#)Zf6;_n{=&o9%6*!3`~K03_D= zFJV;4Md}#&eP%RybpZK9?B}D-*c4vC7>a&#rU1Ta1FA1^PMl$GMY`YvE;~`k)Ht+KpWa&z*5`oTaNm>EQxOlI)hT-LVzV}ZCtAy zbteDJzXQOVDy-3@RoBe^Xo!5yK5#VW+x)6y=fV7q&g~n#{|ZGwN1%;fV^ut}!xH+= zK;ypBla*5W8Q_Sz+!@j1Ewf`1*=quC0DwU`Ko!#VCYK8zl&8qv+{a@)15|xAd?bDq z2BtlFaB{S)6HWe((|$nSjXvE?sY8-vQUJ&Pe#%)bjg~(rMU0WXAo!i}6;|Tzzk-vL z){0rpg~O!My`&X2HGqvdYn~OrSxLW)j$z%&2?!DfndoYCO(zkE1GDEQgZ3b)+nI-L z*FgAVPM|7YUkgCe4F0%#{4YLr?|xw6N|d~nRrE(!6(Zo~nZW<$jX22vp4p%twVEn# z7M0CVB5EI0>Vzv3wGV--2+eOk) z%e&w7Vl%p|$Ky`>*!f*e-s$GcA2uP|1%ZCEKYmRAJ^2z@O=w@fs&#Fq;>q#s>BC-79%tKthNB_| z>t2fm@q$?xr|;Iivik@>)z9n%IgT} zKavcCFm;cTCT+E%)*T`Au)M7#9xoZ_g16|16@$6&fcZSb<~)D-*#}-6+vX7l)C;-wSxjT~MdjU*XP1&DvK4Z#%mfU{ zJy>|6dOjJNrd%`XhUr^n+VmfZ$nYv?tY=rUVm^0I)@7_=@RaX zbVyO(-L1QMjMoOF9I01QMd+B~pfR&AF)QtC`7MwEkg89L1HY_+h%neg*YnY0N!L2S z&*@J2#d0qI-B1Vz`^o%uNk@WYIu@1ZlAC*6_Neh9%h4pGeUP0ixoGwX*Zk~#Mdy)= z%B)Q;wkeK7m3y0;e-0b?k4qK%E*!M`12gQXPDh!jBD=KjIQ^!!>j>KB6_+7SIbWK3On};)oh5MUFCYI19v8dv6 zNFvrsx`@Mp74%wtsd+=`mZLxizMHG`i+Jof;kzo9NzojgiRDI(F0S*H`6!PTB+9;G zbaEB>w7}kG>L_%%BDC9`_;*->}|EC(I5D1F3Z=?)RctZR!^mUo;_}ObNe61 zKVBH=e(KCaKvi%9q`Q#uu^YLc&-89np2UiqQ8w3HVA<4|%2OwOe^-*KcH<+=#i*c6fA^WEgqIWd^l_syOj&pKY)!+R}J+HtH64(GEI zWTKP(Egf8+-jX~*jK!X#@OAzk@l%SadUgo&F)R~BPZ~en=gDjGAbuZQu z=`5JGCuaKD&xz=F-}5X85>72U2%9CdHW&YDri-#V_XP|bUpfyY z*Hcds0mU!hz}Ml6l&Y4pBGd z{uYGJz*q82+wXrr@DSgJc<#HA!5G*73;Pw35_eBPH|51k{~9p#+E z+U6gYe9Yi>^jbREKL!*#ofS4}I3K(m&e2wJs?4t``_7~7NOd<%UHtAz$JE2Um%Hc5 z^E&gxsDz?g5i}~m;N&W@=DIdG)sv7pRHCY#fEB$=>{UU!Ipjv|*!b@;)18l#tyWsx z_?TONdk){d7^U!WZ~khu86yt@f;2I~nIhSv3yMqw$>-hsEdt|)#yJVqzn|f_cm3~O z9Mwcl<1Xc0i|qG9vX5`@Iv#PY4|S94b5r&bWGQ#_Km7NXmA;~=8UixlE3C|@i zjB2b~`lAWHp3wQOm4Yz78FnGw*$E(hfs)v4!Dme#S{PWj$I3)!j3oI-Rx;L6?=OC$ zx1L?#YEM+n<0S-SR>dE5sisC9EeO}3g7$^lAj0lRZ`mE0@=mLxW`e)D)D~eAD5A%* zjt!Rk^hfjN9be{aq5_k}q}avsn#-maB2cJ9J2AhosOoGiDNJg#d2h3oYdsK}ye_#} z_~CA=4pfSj;tOVJF1x>YUuHpSJx7fvWL2rRuBJxnsg}RJ>o#J{@ECPEV-yuGxh(=g z&fva?*F7sW9;&sp7DtuhOlD05=FAVv?rjKaA5c7Q!20cS(?WToq!-$jU3vw-ZQSf| zsAJq}&vYFdSgCK-!;7WYz+TPFii#672o((hHs^2Qkd-#I*J?7j5uA^M7D|J@U5{6E zeP(8%RJ_0L5qdPvv$rGm2cr!iv)lUdYu)2IzI%KLgger5_pd6Z*FH$uB=< z)Sqe|lpIQ}i3HF)o7v~?Zr!94+q9A0?fFAi1;;F2Z?HZ?;R#D?%7wa4Zcg`xjWV2{lqPgpR z2JcC-7+6r$Gv`BcXkZP?z7WM zoQIj|krJ7bImN)OY9-|?g(V(pvY>UTh`;`H6m3|9t1(gc5jT2Rh3&3xZiJo3?n>$G zo5}1#XE$Q6=xQxjT^!?EN!soEeU+^(!_1lNzj%hL(|fK8mtHSR?GIec+kju2kFy;c zNy?`a4Eod-#%J@O!$gv-JM&`vNPDfZCyOSn@>7aD-c6G!WiGk1HZT(L>_cFy3Wfh3 ze`nFbe!Y*@Pzg|JTC!fOxFe;_uk(1v@FM+<5hKKuWX%=rKfX3~OToi|6tnM;Q$SU< z0j9IZaCajC;^JrWfau970GNtrCT{=!_TvYzc=#uR`X&HhS6z6~JA{w*OxL<>rB60X zI9o278JA#9H0RlCAL{H6+LUm04WI%*7gjzjq-k8~?4?^vsu{MEQVUAn`UnuNe3R6D zVCbA+Z7Im5R{Z(_5gs2DSvk{n_H^vXWnNro`g%1qJ zZ13u%rUTOFw=0N&8-F(r0bpaf){4ysu}Id4<{4rj_aM5WJZ2VDLoyhx(H#`L?07`~ z>l#gxwDgDN;t*GvbqFW&L`D2=&}usl?;u4VB=$@dT8vX8MpOO64Ym%XkCcGED%@t zQr1(t`EK#?IbH6`a#^q# zK|nZM@!-&z{8&ue48ak5+#;rYYo1eOU>Gi>>cux=?0a#3=yXp4|HVu_HJ))R=&($d zjW(Y^v)KIxO~y&2=wqqU$N;fd?K*!&W#CT@3RoO@q?GL*sfm^J$OSk`pnXchyr-zI ztFXj3>3M!Xzzn%+~f@*eORCoVLt{_*k=B z&iZgbgl3?Z)V$BEeYP6plulY-?+a{b^T@}KQ##c!m4B3+b)&CJ#wMvrHlk~a0?eO5 z%LSE1?MLjQGPHos*zD9$(6>T(v1ehRytI;VOv&pkDp`Jb-k+GDII(=TG&M`A5mcI^ z9*yJ>51G>`DPE;JQY^>r($uvhzQ^vevGu1Zn+UTER@}tu5jRc;ZKB2~^lD>;8j{z2 z870o5(&rAz%q)XhEVxMm;4}obCKby~>RoTPc_ost zL-67van*d|cpNg3?$NHb)0A!{oFgTdBY2X${n%$KJ2L&EB)6EL|47fv&5wDpj@ZZH zX|niK^g9O3bx3Pyyr2w=?rYGmVzw8L&lR%??DIoJE(V1j{&`#a*p>px&D zJ^1siHcuw&(9(*Rq)@l{4F5Skufafgf$rx71Tp=&R;wz6N+oi5`mw%cRF9|*9F6oZ zYQUw6wqy|T%}lg{x$krx>|p)_VZbq#4DS^+zBmeY%$RTfIa18BD#0gi?#G=k^|5S1 zT(c>WOB{8aRmslQ@DwfO1s!%$q6z!p|??+6Q(I_^Dw)RzfkJKCSNaARjR1DfCu-fEf;0i zXCBegafxn-&rSrxsVuoN9HILjJVF;BI-;^R>t6IoH!kJc(+NR*+yhg7l?ChR*U_zO^2JY5 zw$XMFf6Z5P?>BhCX^Kyrh$86LK{5o&$%xV7nX-^?myoVp#GDjpC%4sFOo&sgKXxT3 zgM<%;O#Sd))cd{B*2G)uXY~}G!F}2-|N6uBU_*!j&fu(Yb77N$7**29l?PM4sh9Sm zCx={fB~dYP8})W3>iJxi#|yu3wNjQ1?9pz<=U@ETqDrN5Gu6?*(f!V5U)S1Hb-}1g zgEcmCgOyP}-{j|DlQahcj-F%XpW|hOI)wGpuBrq`+xII#v^i6WHm6qVFx~@ws3*&I z_^BP<4z&%oZTDiB*!J~+A!g%h0Q3(ei<8y47_c3LFSd`#iN^Ow_F^IAiLL8@u?iFi{4Jqq!g%7Y+ z(TR2AJnS6!%lJh^b(!j{R&cj5bZl9+G@ADkWs%zfZW#Q4{AziIau1oyokp@@tL zoyL&qvqBH8i%Fqfm@dvc@(he&=@-i-%COBrshGTrZsm`#*(^}fK7iUw&oN$xr_XDd z!&iER38G+_@WeJB(XLulwvRq$;M-MB#A5SBhR8wjV9Yxz+M~3~JY*a<#q8M7*W|N% z7R_(@6MEi;>wBR$3Ecd|n|I0tKWbC-5bRMuxsnXdIMNhYh}{ABCJw7 zJ5QT(SW{e9h?5CS=fLiO8K1b3L;sK)k618)KlS8SsfroQ9R!-N9`P3M7I$jc7R}bN z8?AOKdxos!evE`ccy3@-`&Z=ao!m6#>UM!)CLIG^I;oJS z!SsM|Dq}H`lEDzVsEHc~3R9q5nf|sHzxUJ**IGaj_)R27PoktM-yxP`h{j4&2jsYm#VG()7a4XF$W9dq-KySEk5G$yN}_mWXRQY#k|%s9sc9~#O#?&_Bbfm`VsgmM;ZQxAGZ%+ZWA6I_xtFldh@BYSZt>IC-Iplxuc(Q`%Dz+XIciRJJ}-t^ zWw~6uhYM067qnJyzYNV}o~zcB*2p zuSo_b;-~%J&0Od`EDrRAP8Q>IwSXX}Bda-OoDDSWs`P#!RYjhw-h+;Yy==T+86)i7 z=ETCua{Af55>_@%t~VwA6CBk}!}9!T+M6~ev3a-4AM8L0l>T>-*47ftRi&{qc;sU2 zp2&5k2BjP66yXR@N@Ip_jy?tBnGx?c7tp7q#dnfTpp98Mvp=OeLaol@yN&o}4EA8z ze2+qT_(WqTZ{*N#EQVb&K@9M%;FR1d>J5uwjC7f(F!6vukmHhS2@S?z(%UxGz;a&8 zaZ#xd4_9V@sElSzI6cTd99g%MG}XZ)yz1^MgR-803YKLR4IHA<^^-{;+(&gd4{FG# zIvLBZDvy_zqRQ#>#|h@m@Sd`zDSPY3(=%{gsejo{(+qnL^Q`C;9d&xpn0uw#vOaF8 zsaGsfEal6E`p=ow8>Khxt~)=#Nr3mue>U8Bd%u^F?`eF^J$t$rs!o>etj|k^zt#M= z1#m}VV}tqLGyVr&U&PRT=bh^JblQ{ZB`)jx9@q$yhnFd_^>oyzEaVHowd(7U4V!Pj0q(rhk zekVNSP%HceqUi9~>7ky+tswdf;Iuak7{;UImF{PQ|Ii}ITzDWPn;kX49h_?hOXROJ z=?`T4Cen@aWiWMA)E zcraId)^Qq4DU;x#-8k=I*AsX)ySfqI!{PR zQ?7ccOx4{?^7z1f$|h?nu%b1}9VL0WExoPhCK)eeH(*~Re?CEc(VaTB2-{==VMOxl zDfHVB)(a%iuxa=WIrYZm4occA5kF^+Sf%G#Q4Yw|Ox>(u2hqLJlXQAa+a&$wx#oxI zzybON$TkE8_2^x+D5>$!%6CneF2cG8Cuz6lrglJAsPnfx^{EQlnp+iFXvlFLdPVrv zeM1P8tlY$(OKQGIqyr6uZ^LhRG4;n>Tl&YDc&lzp3nf2G4a|Q1WgF!m*BTQ8pqq`B zqy7Kz=C+UR(#{c%NkGifOLk~vP={oAT5y9_G!AMWo7N>E(gM`Y^+cV&dH;q_mT7$2zI*8o;Qb@)C6R?RMHTp9Xl3$(yb-eF-4un+Kk(ayttZSmZnxp6j@FoEakac&b>ozMT1EiW_X2dA+epYLC#ZjOgEKf~ zcI~$(!J)u_M;qF-WQd28Yfk?~vru`@lrL+*V(_*zPh} zqoGyqzzI*S0~@rgvh1~r!?H^)(B{5$y2R$c?7JjX$963Gm1Cz~k0_b-HKULd;gIG= zlN#cGLC&ABt@4riQ4gXmJzG|k)(95?-A*xh;o+>b&C`qz_)~Ew4r^EA$qLQBTd(+n zgk?(M&5l4wTD-_c$-~jDKxmp|2t))TOD^dXP3b(vBr?^z7X`o0=VOPOj31Cy4WAO0 zh{;lR3whexK#eDhxnJL!^l?;@VW%13U+HZ5`rs|mb!l**b~1xe_4gI-=ve01b1kKx zYnAHyh+Ku6Qs%@&S+6A&8{Wu?m@ml4=Cc=(gD59_PdE(?XMO&0;e~>mb~czLCJi+B@jO(DZfvRBNT`;M z%}Nqx8<1a)>$V+^h%5Z{I?x2#C){6On1$v%$Z07CO9mc-(G@$Mh7unYE23>jAe}sl zM98`->0QyOcD5(+W2EP6gbqJ2o1*&Ntem>n^sAXE;{h9(NV$p4*jvw+MZ~|wG8_$(hRx7d52j=WU3?7A;=t!WA*G8Y*J9pq*N1B!!sIrucz^~ z-Wb`xH2&siPzuth;n+e2+`@(o#~SeVdTOciWll}yZF_hJ)CHQ)s!2jR8`Y(`u5Rl=wj-z4{U4^ z^Wl8oMWc`H4S^sWm4XTilhT@P!=-w;(ZJG4xsOB1TD2ZW)1c4@?=> z|6xbWkkZ;JKUxDLcovoH`2_(oiKG|4C+I8vF=dxMO}U3bn9xp1Q_8+TF)~s6yu;_` z6f>%)6gK&^&oQTbR=?~#s2O|Bz?dLl{Ae`s`Ng|OsNB*t74`nx-Sb-C!XeNAiWWL- zkB@1iClK<zRijhQaxn0qcl|m zcR&1l5?it?i%U7OYse7E9WBeD8I*r4-9x8y_UQ_Vpq$jzLO}tK`{Jy25i)xPw-yb3MD0E}E*MaliM9J` zDQS5D1JoY4M*Z834N;FTn#jxZB&y5=i-B1R)_h0kk8rAISHQ1njE`&Hg7&U`hfmUFS&o3t0e4}|W3~u=U(Qr! zqXZpE#ikP_4DRb=r1j^{C`Jq!$Y8mD7ALq>mA=Jiq-HDBG$%{^8y=e1} z*6aaUic^evXQ43DQ(R?)s4Xk-)%X&dbuV>>WBh(vAvbo}6CTz?GC8sep+1 zsxO8vLTCM**z{HTa;Ad54%^cv(=j1*z4;>%n}26HtenwoZMU7WA0SoO5o25l`4cU1 zSz73c_DNmhJR2v3c|oV<=atKLEICHgCK}JILAYLtnqL%Y_FM)1qI}(yHZwwKL;lR3 z;9P)nhv!%#x3JTE8;5G0(D!xWh!JOpLG8mxGt|KNHONHlBRG1yOhV@xd)b1%zloau zq$fX};CKIzmgnlOe5_Jb*XrIV9ewEv$`kGyW#T(bXgm^;TIAuR2i7FI{4bYPKtMi> z2NHfE)j+xgD0EQsoEx?t77nprYV0WAP|`?T2=&O_CY{7$`zRei8?DOT6G6in2X}#F zG5luNnAuL65-i(9+eUHbgnehujt>3%>$M&1$RY=xtLbzOtW<9fSGW+h6WJ@ugVEa~ zUEhI66SNY(p}#Yx1;h^P&D?1hLGS5d&TT3`5Bvv?4%=ts9ZUP|kP!{Vmy!^hbK;%Wc-Vnl-#3 zC#NRdAbz4;;4>@E=_-#gAx>8gY)HIaUKz3=##YR4E+qjT)5G;DvvSq)ZS|;gcCuSa z8T$~1Ve2;9`->Cpl!ovA{kZBdTp5;0Lqa?xjBm{7`Y(|rA2D!R!GY$7FywTLB}f@N z27&Vr8*a+wW5GIM&jOsC^!8HEsRYBw@N5iUe9D%=lq4{bOtX(xGd*9NDbE@S7u zd1<$FwzBP!{lsi&Lh~racE&wv@z<@tJx}L=fwMk1<45!4Zmk%)>cZGnOI8N9A)PQ5 z9{A~VO=*Ssgzt8)@XQgx69ey)qKFdS1?hvqXx?K3c)?vgOdXGjkoI5tSPG6x4uQ`@ z1-B0+NgvMbJ+SZ1tPw9U(%uuaD4iD!SkOKqrvl-C9xHB)MfVZwekJpKPk&sNQ$;M=W|sqII<3c8*V*$HADvslm_c`$pjlVUw43vxkf>cQ(-~KXCJ} zT2HXd68d+y!H_5!^Q?OTb;eKXuFt1ylDEXCn5Zkuu@P~K2#XkwmXRcyyN zzkyJi`sxcM-}J^z>xMN058E{RI!ZcrUIz;1dajr&<*zfd_TaUFrT+brlSCg)kjeM6 z?CX_Y{cc5AHjpA2U*E>TYGKTm*gmUp$b#gTj4Q+wAdCKGre#p%B5riS_EFQPMRTLS zr4i7TC5dZ_Mxun52@`c9Oc_+#4L2U&ZOL?jSN2xKjC77HoWale zLSvXWJR!cVX*hw>jj=1*!mn$>J9{#DXW~;1$&J|P0SRWOs-`0{Q;JB$Regtn(O2xb zK3i%NxJHo{;j~z1F->3hn+#F;itcI(56vP6RP%-&$_xA!a$gz$QLAiLW!wD5pMBIh=F$CZG{qdTyudly76GdmR!hHZu14_SeuxHyepG?X2g^VLJVr15&$)ddQaN+RB_@@Qb$e zxAQF@J5`K`wiTjXmcKsdSxx96R}Kd?W-)a;{1{}EHL<@1OEcq+F|bx)L##?9gncT( zL%ouE(r*PiC9PQeTK{D+z$w3asgoS?w|%)9m1lYJGw#Z%h~*cg^=)UWE}?@JRWsFENSu-sW=;7$?5%xrH=}f zKx+7vk=|`qlNPOh+W10=jaRVvl10HDLD_^W-$_5|luuI(+DW!=#ga`QFt!M{`zZ=29bX+F zCCK#G=}z54iIP^)l!tK{Do_Sy2VIE8XRBPSyPO28QOBO(b{xX_U1~*N;7*(_@m5N! z^D6b%nT+fNBi}BH{{Glk+c8@=yF?HD3+Xlaokywxwb5%ANUgTr<>!14nx4cuHHv-e$nGi=yu>Y4aoA>_kkI{ z$a)5^>o zN1g~G8l{+6^aVY6NLCNwftJvv2%@A1rqb_)F)_bBX4vGts2qG>u0crjXAVtveXGDK z$1#0y!+8v2^cQ$G{j&#AGXJ|;3o1I0t4*@2H#3yG*4 zz$Lfv2f_X9l2?CetidUx>;gc5Yk>8$Anv{ame8iHc>EqN)MRLQdlQ*c$1y@K7mZHHZhs21#b zZ>)YS4NH8&Br3;pZ1fZz)KH&k;x7INrd}l)GThkrF04d60ljufPl-t^*(f%a*0##- zmMJe@GL|bA#K7k7+0+wYKkdik&qEIdd%d$R2NycUIB3RaZP`{c9l-v~Sz%!T^na|^BklC92gw+9W40z{S1*qNOr#rd<$IUtk4gI-1) zo$1h^cXiMwM`y^f$*XKY$<))TEXpG(nc`KQGx@_r=isyWylsqA7BxH0&XJ!e3SHz* z5QZa$Cn~{Z8;#|{aJ$?2BhR%zYg0&?t?X0md|A<4%+_yv?Y;%-kDf>-(l}1>DTmnz zdUHJgy8BmT3VxUzkiPSXDd*jEa=a!qYQttSs}nsu(BhL8Ad`D%uQr$l2phVKGIq9J zm=eVcqiiC?qjHpvvewZ#;#K*IFgGI;=!B9aZ$@loaje3jdZx|KN=x55w(FFb`m>tt zgE4(V-zumDj{HFi5BdKTDih1NX2`*f8q z=f{~k2Ul3K&xubVKY-KdpGOk7w>j%B?dwa|us*_;M=s>byF5duFMKf*X0bf)uVO~z zqZ2_J#ax&DV3)g?a@u+a4|P;Ho0jwX0!bx_m$qwvRc~sbC!}`P^@`A`2B{`rkRN>n zbu7CTMPq}DFB{&dY8c~L$y*7$<+ru4)yLM>tcAAQ-TV+Yu&9$3AS&Pg|55hVaZ!EU z!ziV63y8ExNeW2A5CS4dDqV_{bT>Fs(jcXDh=?#WLzjRwNH;@wHw-iLp7HyO_dd^k z?&ovozcc6Tz1Lo~*IIk6y$ka4k(KvoN2y{@l*45&@fbe#YNW^uEh|VwP+qHDr~Ov$zbH zw^!ljZ};E$JnoY?34XL;+s@z0vNS%n>c35o{6(H3#~6AyFFfNp_w}aqvI`kE$&k5b zw_(p`y4w}az;-T`p-Qx)rZcenu_CxE z(TL*ufumr>gmrID{$=JUf0_!l3L?;|NjuRBhELxUHshq1#%=~nguUjyBAr})m>?IX z>o$oG^3j#|BVSzs2VF=DZR@B0!0u|G30xs40(*BqS*|x`f21#OG>Anl_}-+5kjLQL z(Ad;Uq&FFd<%deO?CwqqT}eFpZ|PUqQBtMzSjr5ne7}@TU0biE5n>)h6a&wc$9-;- zx)Q^A7eyt(+~4(ZN+rPg$nw08&8Ayebw5Z)U?yf=U}IUFNiL|4z6_bXtN|59Dv{TBIS4C`4&%kciw zbjB;DSup|%2l~CXC~R6y*T@$-Aw`~wGRqxuXBCf_({KNfy^A4H%n@0LVo1v#8@`oRgq_l=a6@cRAS@kXD)t$8@@P-+B1suF+&Lf@|^XYFF3P%ei?qu`{+S+OT@f5J7128a73o%>yv^HQg|;>>4_11{1NY(ODtXENEeW2jsU zI%|`*<)l4~D)~W}z&MI=9qLbWiuER!k&FbSug|r6On;>*szv`p!JOz=jyyEvv&`M2 zAN*R@k>{ZTAsoa#tiY9rqgb@R($q4Q`2>$Nnq_lY)ORTRNewP&NP?E0`Q>D-^4~kx z-wB3Ey-dOm)S8S4_DaI`fD9aGHN{)qVC5G=UTFSQYaSN-i1j6eu?_-{m ztZ@FuLdJ)QzF()zb{_Q`JEPNA zi2(HprJ7W?%o1ehTge4kuY9woAoWpe z3Gs+`HQbDJ=``b&xpBYI+2P-RP-0U^=@Ct-hOzX6<1AoRd`BpNBUYe#H}`w(pHeg3YT;bQq!#Ms|>a>Dlye!!(%N)LP3&+w=UkSq}zvIsCu?y;5IBlr6C^QR1Hf@gRA3*S5I+rw-n<7 zA^0H>fTkiJIcy;Bk<7kj#Jv5U_zgRXBoZ7s6zz3hmpAbCK5*|-h`)s4n#QpvuTt zvGy3Rwd4j9UPM=UO`!74ad6Woj=u2A+qi~Fn+z7vJ4#ZYPk|wqYlYJqic(E+e!s%{ zvrif4oh<`d2i}#L%Qv_r98~(I7eWj(EOGd5Qo2NP8rvv;-442->qek1Xw`7vrzv~K?n%qaVdd4%u?{s~P>MwYsLaER7+xvxjl2MC z$J-q({f+k`!j)O=>3Y+mu*Mx3pEOpORMhP=`h@Rw8_Vpj+5IfB^c|n7)EvJ(8P(ee zw?4lqrf$jF^kH0S(Va~&h-y2QS?f%;c9qZhgmI27YAX53c{$G6XW?-l7c%z9CFb&0 ziG81X!CbE%$ZBEFQVjHZ-Ei-49#|Hw8N$B!#8YBXDl$tHH@Q9b)U^zJ*pdhHUhMJ6 z6FhNWzl`ZLDT76PuQ0tn5tYG;Ns((tMj;;{UiPu78K2G{5$Qo8CsS!wY zhJH0i+~q{<(k27nFPg*tz*BoczBoH6amCgy*lOr7Y>E<^mi>O%?RtJ{x6H5(FWc-` zbz#Y1-i;Tj&aaA0BCnIO4`gchp?29g7hK$xs3re&GVErctFaQ$wCdG-{+%Z_UT@cs z*Z3Rws{gsEK^-3DHeZw|DGjo?CgON8wRcL0MKcUg+Lk}IX1)PjUrnZ4y!!Z*Y5DtU zTDK8*z}VNjy^b))>en_!BxmM-gpC-Aq^R}6tGeObgU4&A1YFP^$Q z;PC_PxUl3iw#MAZiSX%tc;BVxuXk(WbZdD`0X6jjXdx;+aZ5G!6-5&D#yqvPm_2S& zZV8VDcRhp$fM(gCGnlFVI#kvmlk;KxRKig<{Hq$G*D`#d()u{o?i<*wW0f+CYOXhQ*jgLzt9L&A(e<)0=X5^H<038Ozqj)#J*ub@BR0HBL+Rpx?P~4<=%-JC zqS#pDs>s7Wgwx=M;86h(85ua8XLqpu|d)GuNw* zd7CZz^^CiO%*GSvjG@kopQXU5k9?X6yFbZV9xGHf7|*%-DO1{dx|4tSC#T{4O<2+j z{L@4W>7@C+6B$)B4*YHs53fqy-@G1Tx;(wX| zP$jVfc_07^ALIOMk2VrOS-^iBOE~jRX+c3(SXfw}PVxWC^n9Xa#|)O9Ep50syqXOC zZxa01$Uh=v$H?o_iY8S5jS_8ANReG(f_V2G$SpJO8%}I8SAYA|LCBS6!K!Wbn{CfU4{(sHr9}Yu5D528; za0nLupS*{DlSYS`DL?a{TG`OvzkmM(#Y*bV`Y+Q%BX1CG_6{2Gy-5Byo-pSC64@O& zo}c|IzyB2m0M3l{yjTAYrzaYl|EblMaf(q{WN_^0tP z_rY`c6w?2TrvGj)%zZ&3KQ)hG1Ww^gAHD#`~_ny1mL1EoRUreGJ!@iyndr^hN_&{_$Hxk z?#!BTcldbR$H-gX{e|0#A3*KkVx>+W&@qrI=!!+tU%w&|I`TXTAOt=*vbphwvCbwT z?S)n-ITirse@E5P5Ub*R;~VOKtM@&f8ndS7JMRNFH9-HG#D2h==i|p>Ln~t|S=pVp zLP;M-nQ^dyZ)D~50NjPhl4FwBJ$!h>3*dlW8KX;Jep>PKvDMz#QE@RatWdaYwbI*H zQ5oX%REfZI6(;ccjOL3M`M`tDrw>*ag=A_G|EuM!?gJtx-tmE30_fcHDR2@%V*}2; zR^a1*_(i}4KrMT0raT%U+~~C>x$FBg0IdKhXtBcwrz|cm=BA|hL+a!I&T_yKXtCkC z{n+WB9sqhvpb>RWp^F5XZ~|$xdKk|@|D*B1256jD{U}d*1$6oy3xKysR!i`2@8}-D zCcz)nbLXGdaqFT%q(y^BY7f9EU@({k1+tZ+_zTt-20YoNUoVf~+Qgr1 z+Uy>^&_l0_J#&g#Gx*RRIoLh>?OPSxX4wT>&=H{}j zhQQ)e-(8cIO4;>>Sl6)SDZL7xH0XLmuN zeFNau<^|5@1M$3g5{?S0I}^#hZ+4CJ>EtVj6y1asI7^N_&x#I0+KlCM3c7ad(^n|C ziiP7l>+Ux1_$9iWBpd4VxmJHwI$_#>!COQ=zNQCIX(swZ3$|#ws)j8MfSDI$_g^!0 zM=G%Jc$K<-mwm(Gob9b1LK5oUGmDED`2cd~^}u^s17kW0gRjx{k_!#5g|yAf<&4Tm zfglb=Ce_t`CQf!W)YkUckVW>e;=p*(Pjvg=0ncYg@fmNC>9;ivV95FpfV3EMDy{=| z4OoTc!$~(v>%791skNJ+?8;FkecIf%)Vra3^4WM;=v9?NYvY&*>cDZ%_mIhc4ngP8 z{XN{?d{=~SYxh(j*_n!W5_^+w<+svzGkNn#=J=l#Lba2Vx_0|}<*^5jyM~nm)TM@w zQJzMY3x1G_i{?qghi(E=9B#&8w-R6OGx5f%kk9JZufFtYETz;8iXvwny;eLAV_GYR!fR(okt{}HV&)9`GxJ>(74F#& zUC)Ilf#59{W#u~F1^NZTK;Cm{&^>?hiBXVdcI%7=n4YN5&f5Fl5% zcCltgHeEF3(T|TW_hO=;hDnmOWUn0mihB+DA8VZVtNFEPaiGJ|AG)K(+Cg>ldcb#- zBY<}8H(j6usfkOoL-UC*UDK($k-#5N6G7$Mrf6EOgU_sl_2#? z@}Li>^I*7sZfDfgc7xcXoPEScF4kHQTELMUmbSPZhZYO-7Qm8$!9c=d`lTfUq5?@~ zfSTFh$I6diHs6T0YMOg!(^dVY4-1fQ<` zwo6-_25Xf?mU|fl`Ax%8DD7;N(Nj}qY^i!NH>JyfdbBHXW^QLPZi{V_ti#jsF!fhN zTMTZ+A{y#&bnOWVO=%@NK#>4EfkLyd%iRQ`559Nx8bl?E_ROBcn%hK7e82KucOalW zm(Uv0)2Fw3?kePUT5IkcIPY1>21};juXr6+T0-}xE$k;$hRZLWa^Ef`iqM^PXx(Ks z?;;VUR|)yaP`LPa?b;v!)R?H=3+-z(27cjvQ#9C94UT3@msMo3pIfw^D_b<53fL~5 zyqPnC^wV&=OBfaF&p#d^=HE(lo+seM+2F>iuBp7hR<_8V7Xe{dj>!1Ur0J+bOY=!9 zbj@_dr`u~OjdZvnOG-vm;9~RKRy0Xz&>D`P4dM^L5KneLv#o5NjZKi@vEc1*{0GWk zi55Mw7hIPWJx{%Y%!{E8waG2UpGA{H&5~8u%@fHZ#S@ z&zL#ycc&?|g%LZ+M8xs7!ER1^{DLke8!wv7Ut6< zRZi8Oj5g&57LWV5n4cK2D4>g5~Q2o z`ba=UqcGhx%lG+6+T-Y|J5(8!-&ErN>V7V=KjBU3dH0j>fRU|;F!e5&O}6}7Zu$;Q z)=%w@-#t=ZgST=19ki2(ErpVT{#M$lgKsgv_e$9emPQ?J@}c69p$F(zlISDJy!y1o zfkhLjDh;jobvY^4i|d>!Pt&`tja`u2^XtcqWONw=VNLTyFeb}E|6xM(V?8$9Mf zQ#n*NG{xlz6Bf98DeYub*3w>jz2^hn60M!71cM*3ktp4_^DO4Z@&W82^Pl9OX6~&? z2myRW;C@hFxPM$pV{mCfQl$%{6#XM3F-Gyo@n<57576&l+l;!-it|nZdg-xMHh*V8 zO)aX25iZs|WWCE&w`mF=L?NPiTX%fzJWeJ>-g?dXAZ0wq*TT8g{C-iP4fUZJr8$f0 zR$UlsGVqAip;pJtDiim>;kRpFNHRS1h$=;gKnWlfun5Zm&U3x?=e}^D)l>A6pRaSx zn_fE;78f)G`hyTM+Q&^f`hFr}8-ye*a2XGJrfKl4=JeFN3~dkU#L313hlh2RH#aX_ zoQ-kOWCs4MfoxT@tH;vkIVjQnp3)b6ai?2mivRCm_UOT8w6$Lp0&NqOn6>!KL?Qq` z)+-!wGY6}M%UnJ+S_CbHr@Y!YFbc4xZi3|TM7F(r;EoRr6(UOuR&Xz?-3HEO8TM6| z88J-tn$s+10tx>bRdQ6)t~gCh&};a|NF+d8?21pg5&(3nQG@-}vkDRc-JXfqf`ROD zrRxT%#eDj$&pGH)f1x#`8=mam-C0Td{oUd6tU@N8>z>PU%+i8T{I3L-lrHJ@f?8-7 zRgE7Iud%4IZ$Ohj_waC}i|HMXmYOf;&QZrIc8wQzjn*e?J#9T-YQ1<7LiR-fOMSY5 zMCy;HIEfQ^L?C;VK|e2eB|MjWMmCkM$JARN=! z=G%H?2EE(}xAaM8Y-4+kHz0=9Y?2AR*yhk5j>@uA;HHrP7iS3XGSN6w6dI(_@{=iY z0_3b_0m{f6{=6s$x*r6JiHLJg_#5Ra9%bCHh1|`dTRF9 zn3?5*GSfS3-o+Ngw-@Af^;#``p+Nh5ysdkET0FoC0Qdq*7*9)K5GSvUO9#KBCMUzV z#9H;2eZ$KXdXs>|RehQ~EZOU8dSq{BGP+-=4ZTk6!x{4LRPdn&c;E3M0F-F|>v}*C zaz0>$N5O)I13bHCn4s7qw}z@5gjZXIWM2??0<2?iO_1P2sxqG#4~B|t;v3u+qxrK^ zwxp_7_hfX`NQvBLdw-uH&n=PiuTlFNXKU3Ees}NUl)sv8NP3uLwqc>_!G`F0kXy}s za@lo+Y<3XAyW!1D`zX^Jd%B%%ce0GOkwx2`k-be0;l3JRmTov`k$x`sm<}z{N;w`z zttJ<-LXiEGIfu|}De<4Z5p5Gn>Q13;d$J$ux5SFS+3lM`yHUp%Ep`2O=VtBWy^#C? z*c4Ip1_Z-ZtbQ*F(3CYt_o|fh2W=X=(SmVHn-(1j^q8M! zJJe@Myywy(@CxPWKY69^0_X%m;~`K`KLq<+sEFU-^1il^^Ig z)l-Nab}mI;XJAtKqKWK&lk5ePCCm_>0ROI__O>-BUYfyPkXjOfR(2Q6 zfcLz|#a-|U7yzFcL#q+>xqojo&cE*>$hnyJ0X=+Q)L@An{fp1i~^GJgAfQ`6ce)lRiw~|7~sbJ4F0(VQ~(&VwOchL zC$nWz(HhY-IH~=*A++rZulh#0DHU|8VZTjhdJz7lx*VHNSHJH>M#ley1u%gq(IGcV zn%K{PJ=E4o{^8q`F_|r>aURCbMtOAM3gil4dCtGbAO-RA($rBPzCTaMli9PJIX zC4|o*ty=~SC1xEy#L2Of&cbIi3JTHD9Zj@yIDg0%1aQ&73!H;iRAA$3GgCE{=zSWM|emdsp&}GZn|KA9F5RomP=!2H-l1q@;}k{%2bq zUdWw;6eGt9zhUGLNd5khOGi&Inx6>4Na@Mx#WIPBhFITk#Ju*ZcAScf8^D>IqVnc4 zXklYgH31~=6c4;x+B_r@utYz1d3iaQZ_HgRZ;pJ}M)86~aG4M@xLf*QW4+q)7QEzmPlmD8+xa9X0mZ;CB zcdS8EzUqN##Jq=477j1lc5TQ@EbielA_{bv6yQ&FAgF+P~n))8_RNn`f1#R;Hh#eFMMIjkMjVu z9pJyd#WB2r!^7_qGC>_y&K}zWR7E>kSM7Ib^ihQ^Z^LDpnsc3n)@eP2l9nQhKZgvk z4Zhl;8oqtTyfZgFU$_cKjOc$9o*Z^ZJgy?q&8nI13&ip1m%<)@#m+Q(asr@6F+eQq$n0ev{i$+ zeHz9axQivq4lh+b!F1iy-#x1Axxu5??&D>(SlbOJ`|=2DygSe=ZTislE+VKA<+zFx zU`qRT#YIf=)ClQ~H=oT;IDdaRUX-3Az2~pdX+@3>zvTVW)&`6z8zRi-^VcxR)*@bK zs-Iz0rCqO=n9Y-cLewtfd`FVvtWdoP*gdII$)!;Y3|S17XL7H00M##mg>5?6pjY-} z*T6>7uzAsO=B?3TTc~wp~3S1ohr*|{_9X-~))6L*>hND8aH4T&7W>u9#U^&3q zd}lJ);20C#GsuPWOTA`ccg-~D!gW^)@T9iwt6FxQs_j~k#6}IaZa)(TQ?{uzoCz}y z0W~Vq`R-9bLhi{-Jh{_928S>mApL{74_}~tKAlL}hd}zg-K2urXNv9df#e>{;cF7T zSX_xl`%C4L+B@MgeY2OQcDzwEhN`J!P;emKEOg@Luxaj~Wm(S?6-GSS?2zsux!Q3u zB2myYK^;aFcDC}VwmBln{L?|sDjs?1bnxSTxD^GHv+X!>9hZ%{_YBX(Ltd3LyQ65O z^_K-GDPki-BL_s|;`@al_oN!Wt@4+k*7?Aj1ULJ^X42`;VD_JQ9T*{Z965kGNeq<~ z0BU*jyX1foZ%t;e2n3MZ23Y^>;W)ZK`DQdXJ695b2!swtnVFk}GrZ+x*dL1Zmoqe6 zU4LAiNI~~N&2MdhYMr5W!LjvfMGtbGW;R>d5@@6;rX`l-`071UF9k|PW$#aw9h0KN z$C~vydXRwu+BK%yb4T*Vp*NNx(NKb>=!1U@U%T5j63bQchDTegUg_qFs(#CD;AU2` zq&6nNP+@Xe-{btSJPS*Psy(0L_iu({G9jF~F~#5EV?sAjR~nb@)8n#aGIGgQXm#ye z%1~@l97%2I#aZPe7Xk9M$kvLAqiBxx?IE4`@TmKzmtF9q#BjRvU`ua=B+P0dj*i{A zwQdxDzR-S9`cm{MxN5>8RWo+uxz}IGp9w_=5sRCW3;`y4@GR#V-&he7wpi73;d{GU zvZV2%?eTc@=q}TuRc+9|(M2O+;5%T8 zRJdeM@7~dq_hO(I=f^+!Ki@tP4686}@GtO?S>2vQeyZVf>k&ci3Hohy)A-FV`%PP5 zr#|n}7t~e}2=Zcgrh2P*&qqIynAhNaqcj4?&a5`hK)KkVIWX9vZV49(by6O@_j+Y! zMs@A+Qq&c265p}o<{wK9rGU*!8U~jTUf+$ek}mwwB?Y5>FSDyiV#isVO!bvtF!j+} zMc@vqfP30{uSeDMlo^Qp>; z?im16d#*TX*=_ZPdnqNahowe*P0x(&U;zUHy9XH%liOIzu}7ixu>*WWw@BlO0DlVN~?FmM(sJr`I-_@piwE>4)WJ0sC{%;~hH) zA~zh;4{@@kDzK2+5`{!j&o!{dRx9%RWO?j0hS!K;?jg>3FHSWw>`YpldOZ)B?rTB0 zzqKbj$8}%7RGje=SGm?`RU&kJ_caGZfSNJN`kvjdTUHb5BrZ)ZwlH`sc{G6CC`ppxErW>A{I0laCC~!}TsEiY#Sv z_oOz4ZR$GDxwEKZ#U-V-vA@A+^BZ)`>*k3r5t=FGandr|i1|$I{cg8a?Uy5h>>Z*c z9pDP-`(YXZBR7F(pq8?dptYpl$gaE0;mNKXSlroedAz>cT$2s%xk8O{jcar;C}8FH zUwA|rbIx&f3b^2{Gjz!?q^y*L2R}D7y!9r%y$VS0-#&s@!=l`wvAiEXZ(hn zA)7H}HKq9^M;bQ7Gra0cj8dCX$w!RPF;p!JYY~Da_u}a%oM+L8Q5Dk(iDKfPaO68r z26W9{Z2j(il#VUq+U;@?a1h>&DE6vV$Y}c;Z`^-hYsB9&9=JhWrw|6(P@m=--V{jf z(|>t~RDkv@&Zki8b;qAkbsV2h{fT=kecD%ML%Dy9q3GD4n<1Jo`+TRQz_)e z&(}WNtED5N51Cx>QFPJ9tLd-<+P!cY3#M0;A+P*{Kwx~{kD{5mIN+Q6EyvY~nY+DT zbtk=c`XOjWkUmnfbPf`D$!qkM)B`&E0Cjh|rOZ3mgRw47m9f$cwe+xY*AAvifW#sp zsz1G)+~=@@T22;3ChY_zD5$g0Hxo8MhA*$rJw4`PJvp>V_0r5+IO>|VD`4P2IL$l~LZ~q_^ zsykN!C)nNHaiy4gpGhZb*jVVJ)o9WDF2P~{z+HR%{X)9v+)rH5x$m$0_gRMd>-Epq zEcO%l16qXGINk(4LKPgMew;6y;uQn)7@xU2G<7bVv_kH}5g4 z7K^Z7nA|rf zVZ)s8GkG`=e4gR|v4#(9FV=mux@y!=LFh9rLt<3)&C3Q((s(@RR0YKq^T!U;%y#2~ zF5nvtW5VYi!(dZDgl`fGe{5&)=T2<}3rA`&sg(JgQ%jd)tsip@m zoy(H}oo|rWVNWNa?h*Y*IxNz$?SrIqZPJ(1Or&p(q-4KpHOjvT?W|`qE>1q>rtkR^95J! zPnRO;b}r8xFNK6N>)x6yT#T7bYk)3P=7x{ED0E$t-D}H?ZMjK7J zvKR(0n1w??b3W$nP*H?Y<*dWR8|CSbi5k_V9i;AEb2OLjlG^tIJEU)#jPyhnUBVZ9 z4n*zeP^NGC%aL{2uQ{4~d`(Z(?93{dxz2ix6~0vWj5v)ND!1D2S8vYmYyIi%75&AcMSrK{lVq}wU;!(veH@cs&E-~h>~ zWsWV^n!xdnVQn_=WkK~qH{-gcjud;47$OVB(AqjI;(sXbcV)CW=jbT+O`WJa$?>kq zVr6opQ7Y57s-wDYgE_&}^-jKZ$%4ES>pv0m4vyOk4kOyTGgB%*6V)^2zhZtf`b%RX zG>x&Dxe3rTWUAA%baFud^Dk|1xQc3Ek+b@lR~U;^Uer@tw;i=ez? zVk^E83tO-QiNO)jVJAmb>U2xHi%PlL7Y?4P%aK&v{=m2^z@8VME#iA*PF6%v(>*9;TDV6@nZUzf((`$m=X*b2b%N(Of-?GIe-7>hgKuKt3 zIQ?GdFZ^$(k?p{?W!P}Q#KCPlsw!aN@kG6qh8@g$xH_pks7rfpbGsX!E8thyv>32| zxAFQ{l*4d1oZ@k2z;Hhx7ii3 zGa6s@2?*iub=MAiJ)G)sfw<9yPl7TWa8b*-35P&>ylBJ3!O>+)Kji)Hyi+={RCU*} zdvO83D*ee}!|_Zw3rE*nkbjW_vTq8q|KS|k1sYcu=k?!PhIR|ZXsSJ4?;&%HCLt&ts5bg9%Z18hB&Dn-g5QbrdvO!TZoZ{^n$vuQEFNF zka7c?+r;QIMqKIPDfkTVY0*;E;cyc)Or3G`sCybjfB4R=4P^Pp zYYZZ?q^fRo+vw}ySK?VrkGo&DKGAC*#s9=I;wPT*V+zDS0sQ-bKP_~(<{>(osK@+g z0LQV&XxMl0faw{MRj-X9qcPAuV&T+@$rWp}eOSeuIYZ^o6=K+H_~rxeQNsL z8d(hA)_^@+JtCl{FI{xw-}M=@gTO~{#jWpG&b8by_+9B_Un(d)*Iv&d{QP^FMo#|P zgcn3Ai7$4AKy7fmFI6dgaDliWXG9q);m34>k5Y0(<_UQ}?217*$E2 zjK&q2^Kl9cXYd(j2d#Caiu*nqVsdDU_zkvh`tJHEg8#H>K_mCJp8ut^yIYr_$^&uZ z5S-(Y!vJJotF7n2a$rN@p@v)k@-WCN%b{s4$f16-aZY9NgHR@~V~oVk+UCsXP0-wI ziX_Wv`IP_h?j)+dj7`;4aX#K?DP{JJwK&+Q)u~c_*{Lnn*YWn6%5(pkW_H8KsaAx; zxzXpX-gV_`yhl+qa*nw{z&&)LnQ1*bsOI#&G%sW@@xr+u$DgM2;5SzwqK8acW~dF( zhV^|L4&w!p^5Zv+eXVp}o22}e1z87oVhvg;;gb`MGYMsv*w&2O@JBRPi%>tNa#Ucq z-yT_Q&zt&ApNiQPi`a^FC;ysFhlIpRk=@39KKOP};E?Y^A0C&+v8Tsupoag){fpbg z3>)}~E{wF7;x&04LF~=nM8q##Kz{nV8Vkf5aH6K!@Pt{x3U53SvnhN=Z=#SF43h!l zf!mk7Fa%ioD%b7vozjWq!#*t8x?knr_whF1kl)xznv(Obl~cv0Z={FC79l_d*{WA- zZIp~}tcRILFhs2%^|6 z6<3l|V5SFf{-{@Nz_k$+k-;BL_VG*rjxCKZnwIGO7P|K#*nS3t%Bj z&aL!gyUUK3lTF7&yW-1VlCJirZuyRg<|rtYyRrq@Oqbe|A}(|R0m)pu9r-LhIXimUw17YSp6)$E zwUMz)>n+WLGxRT78bk%OAa>?Y_sl`&Y{ob7qBsW? zRD|;kNS4DEjevF){Dzjou)?M)q%0Iw=6 zs`G?brIc@7c9>2Akx}SUUH<1T*I<5w=F?!5t>2=D(@ls%{Me^Ax!LNyru|vgOowab zU6&%Jc65tyCumzQ+qZJ-xTjD!%rA{}TDr?^U$oVZ4s_jhCf&}bVI!l;3g8wOu|UH{O9FNN1m3&ff$=(vkZe(4(QoqlEd$ZbSud z;Fzr=ufepJZ`bBEB`0wDffjl;k=QlwTb?c)X~2Bl5YThK{n$4h=}|Cq8nuY74$x#jF0JD0GCC7o+2^=lSKSjH1LPgTuS&D{KYrNqSM2+ zeZL0&V<`z9=hWGC$0Fd6WN|JEhO9SlRwUo^bayJZ^_Pj%Y96?pR5^6np~mx1oEjEt zXG#OF?fUUEjF!akPg2TIwF^g~WwT%-zs!3i{oLRP<;d!W2$6c8c`0oKlGi+5cOedX@Zm||jGIQaH1al7 z{pyyIxOU!F6gdWWXwyjEJNXISJno*$(`%kbqAm`whbkMIP*-k+mor>O(=F~?+@BtP zyvOxc?qd=e4r^Wn8+*m0g!_p$4^;fSKqL2wBb5-!6jV>HRkbt)sN+|Djd~eC`TMD- zTimQ2uYC4W`65UH_TI0%pVL)#i*JUHFoBK89Y7TZ0} zON>&*uW?}ogu#Cz4;QTbgo$Mvl^CL1^-h=iI_eElP2cghp3^nFxxjpqm%hXKek>iS zP0BQFam^GkJ3CntL%roSWmK~u8PxH?O0k7)iEA-#)5W`aJKQ! zBCX(rExhHmdz~KD27~lZYsZ1zWWT*-ZkVJ$Mj=r~-b*8$du=|a-3g4ySnH*YpfhQS z6hY_oWH9{7?5lLG%H|%+dK;9%`Y~tg4Z$5_hLr8szfW4=Jn*%u$=o7}CgWV0fPgz* zBdnH#4+hrah1BsejW@1o_FV2%!=Ez9C+^tx`jtYzpAHky{*fLosW`k{_wf9BI4a;O3IhvIEfj;cu1Is^J|45CAlQ{?N&Z8A z`pU%xiQV-WNY|{gBY5~`?hp!@3hJGezT%n}?tV$pI4n8!V9_0_gfZR|#PT8Pd2v$A z&#zBe-}wo?rv`3NMgFpqYJ|cX;i52G-qb9+37Okg#%oi{nKMf1ThIBRTk}xtuwS-C zH?h}v!Rew7mEow1?EO!LddlFhx^#F;v9HR_p~yKD|2vZAvNX`I&gqe{JeZa+`kGbz)Z>`DB-G}}jNpl*Sn^fX5+;V0hNVFzYq;ys=v#+I)iysXg8Hx_xE zQ_LO9N1(i$SwJ+88+FrW+u4na>JoCsrc9!Vd;mRaH&A;iwAr#uWG4nEx})?UM`2Tj z6XV<}+Hf${kKxL~9@AKO$70$!#LT0wobSq+<%14WUAGkWWrp?AU0mmdzV9{0MO>7# zX-_}=kmS?iCW2*qyYF)(qyYktt;EF?=;VENECPMBnY zLBm~L`<@R18XY{f?G96v3_Q+(=)xWi`x6Dcb07!S~G_DR_X}*dHTpnrF*O2-#5;R;)I+-7Y@-aHO>MQ@u@0cy! z8V^3j;Cqd?)S_i0|1}azY~l9ukk6i0wEJ{H2_9SZ1}PEZB_vS-Ptt)L)Rc__`3oft zc41ic@i&oz)&%x`uYiN+;Wf?9huA5;HwJcN?`DG;C2Y2^FTs~2!nsZGO@gH+(s`N8 z6!y9U{x4~2?^h+BE@${mP)&L_RL08WHn86g*)Qfrba?4IriLN(gkEMFwndrvUC9#< z27SqTpVaN}UfyRNoUTdoZb^x1UptS}7u_ASuB9{DUcJ?dA2XmFdkzdn@r<`)^a`?f!Ej+0BT#>N;HTiWkPo`%c%XIWZAoY6FsE@ifma|p zO)hyEwwK{VhdX<0>i=x0qjaJtv+$XL;oT>+OY5{)c+3J+SVi_C#ay;`0~|!Dy4L|Y z`p}kym*j>qH9DV1P6aC-L8%j8PB#xbR)-5Gcr{k4o_AfsK1Vubh4Vm5tA?wfpjQ}E z#&!XHYP_f)N{U3ZVrD{?LP4sS^K1l5!a=hs5F`83Oi-0NaXfjbUW*`dYJVClYluZMS_lXp%bufeZ7K8NZ`dqFGT3PE0+7F^H2_aRP%)dmJbZjlZbP3(19 zh3#VgKQT#h0#E@}R&x)XXEX#lC@ZP>z!+1U+`K5AY?CCW$%^>AJ9_)^7cF@1G`S*9P++(ZGUIjy&~<` zb!V^NzKiA3XdKAWgy8-Pa|d>;v!2Y6^00rd!KT5cK3sW`LC{$X(Dm~>9=;q6*9R?U zFYK-dPZcQpp4v@L?*!fE@fuf1*zdN=Pv=YCiqUQKOOX)-opU^pc?Q>hBM*B_WySnK zQi3N6_sKB^->jg-&C(pIydP+;!doWx}rkN#nlxl%i{5CmxeiS60yeQ$o^y z#I{g>^=p}qz|Z==_Y?Ot1L_0a7pxtYDT_DlZjBIsQCvda_lt$f_!z2>vg@XiR z@TD2gP3@8{5d?pUX2Yhr<2>~&_)7?TQc!`xXm*v=9cL|bYFm%y^}$Ks3Co{jR{ifk z9%jR?UaBHa0D4%9RVI*~l{g{@5AOI$QJO7@vEuILGpG3g8){)Rs#ZGx>`luIGmPT)ys^LExGu zI7RWcBXobRb}nsr-rRwdZ$0~qV6Bt3?}rbH8&RlIP4$DT?lkayv*F>VL{kS|ChuDI&yIR9 z{;K~|+IL68*>!!7mgpr~5G9d_5akwvs1YTCM2X&`MvvZ&Btk++QKF9CMwc-<36da) zVDy?GjBXf4`_A0Y{XF4$^R4x+_4;GhwJvA&*?XT|f9G7+cp=AJq?-0$=GVYbSjq=R zS(=|Vn{yW70@PEPep8uelx36D_v(=y^AF&O!w-`CCszwXaBsT&oWcec>-&d9h#fNa z{TErPscoh*A>Dg#maA+!n!T714;Em`7Gne^DWRh*xaOSedt5x^*_njsdmT40i4ORpr_O6+g_m7ku$cWuc$v8BVG~NtpvP%~08Kk80 zoiT*pqzNgu+Wnq}(i=sDls^$h z)9k)n$=0ALXVTv8Ux8g_FF9DmGbjnh?uA&=*wenH4}2F?JVl^>mqjeZ)7-5bVd8a@ z)J@#p;2^F;Q_%N;&5_^JI7}y->fGX@^MsV3&Nf=1;RUW4B;MG94X<#TsYbS3x(NTx zU85GcQzC9+9fB+GRR*4lZz#VJh-JHSAJ2HE@&phd=%FcGB78D z6e!dwW)=%$mx#t@6cxI@mr3FsuShJr*R!|_5m}CmHyFGu=Yog~a>vw<2ek|qZ8wED zjVCeGhj284d=az9=){R@mqYPpFN){MK9LGW6oqg|a6&JacpQDD40J!;Au`ZII+bgb z@&i;H))chO8dbu3Dv;1Oq z!V9Yugp@wJ-hA0V|GD*`6TEKfWtD9gAG~q(JX{A>KQm?ZY00mbi|2Ba!sjoepH?Rv z0$g`$aT!;tNu|~$XQhWo*Wbh|c4mDOUi>^88Zm*=+(TU7Ou`!XvE8HA*h%wSR2{`6 z3XRqy*tUWn)nslaPSg7x9qtt^e5G%BT{XVtF^Y+St
+ } /> { + const [deferredPrompt, setDeferredPrompt] = useState(null); + const [isVisible, setIsVisible] = useState(false); + const [installable, setInstallable] = useState(false); + + useEffect(() => { + // Check if app is already installed + const isStandalone = window.matchMedia('(display-mode: standalone)').matches + || window.navigator.standalone + || document.referrer.includes('android-app://'); + + if (isStandalone) { + console.log('📱 App is already installed'); + return; + } + + // Handle install prompt ready + const handleInstallReady = () => { + console.log('✅ Install prompt ready, showing banner'); + setDeferredPrompt(window.deferredPrompt); + setInstallable(true); + setIsVisible(true); + }; + + // Handle successful installation + const handleInstalled = () => { + console.log('🎉 PWA was installed'); + setIsVisible(false); + setInstallable(false); + setDeferredPrompt(null); + }; + + // Check if we already have a deferred prompt + if (window.deferredPrompt) { + handleInstallReady(); + } + + // Listen for custom events from pwa-handler.js + window.addEventListener('pwaInstallReady', handleInstallReady); + window.addEventListener('pwaInstalled', handleInstalled); + + return () => { + window.removeEventListener('pwaInstallReady', handleInstallReady); + window.removeEventListener('pwaInstalled', handleInstalled); + }; + }, []); + + const handleInstallClick = async () => { + if (!deferredPrompt) { + // Show manual installation instructions + console.log('ℹ️ No install prompt available, showing manual instructions'); + return; + } + + console.log('📲 Triggering install prompt'); + try { + // Show the prompt + await deferredPrompt.prompt(); + // Wait for the user to respond to the prompt + const { outcome } = await deferredPrompt.userChoice; + console.log(`👤 User response to install prompt: ${outcome}`); + + if (outcome === 'accepted') { + setDeferredPrompt(null); + setIsVisible(false); + setInstallable(false); + } + } catch (error) { + console.error('❌ Error during installation:', error); + // Keep the prompt for retry + setIsVisible(true); + } + }; + + if (!isVisible) return null; + + return ( +
+
+
+ Install Deriv Copy Trading + + {installable ? ( + "Get instant access to your trading activities, faster loading times, and a seamless experience!" + ) : ( + "Add to your home screen for quick access and enhanced features. Open this website in Chrome or Safari for the best experience." + )} + +
+ + +
+
+ +
+
+ ); +}; + +export default PWAInstallBanner; diff --git a/src/main.jsx b/src/main.jsx index b9a1a6d..3046f65 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,8 +1,37 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' +import { registerSW } from 'virtual:pwa-register' import './index.css' import App from './App.jsx' +// Immediately register service worker +console.log('🚀 Initializing service worker...') +try { + const updateSW = registerSW({ + immediate: true, + onRegisteredSW(swUrl, r) { + console.log('✅ Service worker registered:', swUrl) + r?.addEventListener('statechange', (e) => { + console.log('Service Worker state changed:', e.target.state) + }) + }, + onRegisterError(error) { + console.error('❌ Service worker registration failed:', error) + }, + onNeedRefresh() { + if (confirm('New content available. Reload?')) { + updateSW(true) + } + }, + onOfflineReady() { + console.log('✅ App ready to work offline') + }, + }) +} catch (error) { + console.error('❌ Service worker registration error:', error) +} + +// Initialize React after service worker createRoot(document.getElementById('root')).render( diff --git a/src/utils/pwa-handler.js b/src/utils/pwa-handler.js new file mode 100644 index 0000000..afe010f --- /dev/null +++ b/src/utils/pwa-handler.js @@ -0,0 +1,31 @@ +// Initialize PWA installation handling +const initPWAInstall = () => { + console.log('🚀 Initializing PWA install handler...'); + + // Global handler for beforeinstallprompt + window.addEventListener('beforeinstallprompt', (e) => { + console.log('🎯 beforeinstallprompt event captured globally'); + // Prevent Chrome 67 and earlier from automatically showing the prompt + e.preventDefault(); + // Stash the event so it can be triggered later + window.deferredPrompt = e; + console.log('💾 Install prompt stored for later use'); + + // Dispatch custom event for React components + window.dispatchEvent(new CustomEvent('pwaInstallReady')); + }); + + // Handle successful installation + window.addEventListener('appinstalled', () => { + console.log('🎉 PWA successfully installed'); + window.deferredPrompt = null; + // Dispatch custom event for React components + window.dispatchEvent(new CustomEvent('pwaInstalled')); + }); +}; + +// Execute initialization +initPWAInstall(); + +// Export for module usage +export { initPWAInstall }; diff --git a/tailwind.config.js b/tailwind.config.js index 4606a33..4e60406 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -66,6 +66,15 @@ export default { boxShadow: { 'soft': '0 2px 15px -3px rgba(0, 0, 0, 0.07), 0 10px 20px -2px rgba(0, 0, 0, 0.04)', }, + keyframes: { + slideIn: { + '0%': { transform: 'translateY(100%)', opacity: '0' }, + '100%': { transform: 'translateY(0)', opacity: '1' }, + } + }, + animation: { + 'slideIn': 'slideIn 0.3s ease-out', + }, }, }, plugins: [], diff --git a/vite.config.js b/vite.config.js index e3b32e1..f673d87 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,10 +1,13 @@ import { defineConfig, loadEnv } from 'vite' import react from '@vitejs/plugin-react' +import { VitePWA } from 'vite-plugin-pwa' import { PROD_CONFIG } from './src/config' export default defineConfig(({ mode }) => { const isProd = mode === 'production' const env = loadEnv(mode, process.cwd(), '') + const isDev = mode === 'development' + const base = '/copy-trading/' console.log('Loaded environment variables:', { APP_ID: env.VITE_APP_ID || PROD_CONFIG.APP_ID, @@ -13,11 +16,129 @@ export default defineConfig(({ mode }) => { }) return { - plugins: [react()], + base, + plugins: [ + react(), + VitePWA({ + registerType: 'prompt', + injectRegister: 'inline', + includeAssets: [ + 'favicon.ico', + 'apple-touch-icon.png', + 'masked-icon.svg', + 'pwa-192x192.png', + 'pwa-512x512.png' + ], + manifest: { + name: 'Deriv Copy Trading', + short_name: 'Copy Trading', + description: 'Copy successful traders and automatically replicate their trading strategies in real-time.', + theme_color: '#FF444F', + background_color: '#FFFFFF', + display: 'standalone', + start_url: '/copy-trading/', + scope: '/copy-trading/', + categories: ['finance', 'trading'], + icons: [ + { + src: 'pwa-192x192.png', + sizes: '192x192', + type: 'image/png', + purpose: 'any' + }, + { + src: 'pwa-512x512.png', + sizes: '512x512', + type: 'image/png', + purpose: 'any' + }, + { + src: 'pwa-maskable-192x192.png', + sizes: '192x192', + type: 'image/png', + purpose: 'maskable' + }, + { + src: 'pwa-maskable-512x512.png', + sizes: '512x512', + type: 'image/png', + purpose: 'maskable' + } + ], + shortcuts: [ + { + name: 'Dashboard', + url: '#/dashboard', + description: 'View your copy trading dashboard and monitor performance', + icons: [{ src: 'pwa-192x192.png', sizes: '192x192' }] + } + ], + screenshots: [ + { + src: 'mobile-screenshot.png', + sizes: '880x1490', + type: 'image/png', + label: 'Copy Trading Dashboard Mobile View', + form_factor: 'narrow' + }, + { + src: 'desktop-screenshot.png', + sizes: '1128x635', + type: 'image/png', + label: 'Copy Trading Dashboard Desktop View', + form_factor: 'wide', + platform: 'web' + } + ], + protocol_handlers: [ + { + protocol: 'web+copytrading', + url: '/copy-trading/handle-protocol?url=%s' + } + ] + }, + workbox: { + globPatterns: ['**/*.{js,css,html,ico,png,svg}'], + runtimeCaching: [ + { + urlPattern: /^https:\/\/api\.deriv\.com\/.*/i, + handler: 'NetworkFirst', + options: { + cacheName: 'api-cache', + expiration: { + maxEntries: 50, + maxAgeSeconds: 60 * 60 * 24 + }, + cacheableResponse: { + statuses: [0, 200] + } + } + } + ], + cleanupOutdatedCaches: true, + skipWaiting: true, + clientsClaim: true, + sourcemap: true + }, + devOptions: { + enabled: true, + type: 'module', + navigateFallback: 'index.html', + suppressWarnings: true + }, + strategies: 'generateSW', + minify: true, + manifestFilename: 'manifest.webmanifest', + includeManifestIcons: true, + registerSW: true, + buildBase: base, + base: base, + scope: base + }) + ], server: { - port: 8443, + port: 8443 }, - base: '/copy-trading/', build: { // Enable asset hashing for better cache control assetsDir: 'assets',

dTCRRgO!{JcFmm^X;8&fh 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 literal 0 HcmV?d00001 diff --git a/public/pwa-192x192.png b/public/pwa-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..3a45eee5635fdc641500ccbe747b1ac514bd4136 GIT binary patch literal 1208 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 literal 0 HcmV?d00001 diff --git a/public/pwa-maskable-192x192.png b/public/pwa-maskable-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..4e5f07f16d6c4434a1e5cd92ea0d96dbb5f06525 GIT binary patch literal 962 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