Index: frontend/node_modules/workbox-window/LICENSE
===================================================================
--- frontend/node_modules/workbox-window/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,19 @@
+Copyright 2018 Google LLC
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
Index: frontend/node_modules/workbox-window/README.md
===================================================================
--- frontend/node_modules/workbox-window/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-window
Index: frontend/node_modules/workbox-window/Workbox.d.ts
===================================================================
--- frontend/node_modules/workbox-window/Workbox.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/Workbox.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,272 @@
+import { TrustedScriptURL } from 'trusted-types/lib';
+import { WorkboxEventTarget } from './utils/WorkboxEventTarget.js';
+import './_version.js';
+/**
+ * A class to aid in handling service worker registration, updates, and
+ * reacting to service worker lifecycle events.
+ *
+ * @fires {@link workbox-window.Workbox#message}
+ * @fires {@link workbox-window.Workbox#installed}
+ * @fires {@link workbox-window.Workbox#waiting}
+ * @fires {@link workbox-window.Workbox#controlling}
+ * @fires {@link workbox-window.Workbox#activated}
+ * @fires {@link workbox-window.Workbox#redundant}
+ * @memberof workbox-window
+ */
+declare class Workbox extends WorkboxEventTarget {
+    private readonly _scriptURL;
+    private readonly _registerOptions;
+    private _updateFoundCount;
+    private readonly _swDeferred;
+    private readonly _activeDeferred;
+    private readonly _controllingDeferred;
+    private _registrationTime;
+    private _isUpdate?;
+    private _compatibleControllingSW?;
+    private _registration?;
+    private _sw?;
+    private readonly _ownSWs;
+    private _externalSW?;
+    private _waitingTimeout?;
+    /**
+     * Creates a new Workbox instance with a script URL and service worker
+     * options. The script URL and options are the same as those used when
+     * calling [navigator.serviceWorker.register(scriptURL, options)](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register).
+     *
+     * @param {string|TrustedScriptURL} scriptURL The service worker script
+     *     associated with this instance. Using a
+     *     [`TrustedScriptURL`](https://web.dev/trusted-types/) is supported.
+     * @param {Object} [registerOptions] The service worker options associated
+     *     with this instance.
+     */
+    constructor(scriptURL: string | TrustedScriptURL, registerOptions?: {});
+    /**
+     * Registers a service worker for this instances script URL and service
+     * worker options. By default this method delays registration until after
+     * the window has loaded.
+     *
+     * @param {Object} [options]
+     * @param {Function} [options.immediate=false] Setting this to true will
+     *     register the service worker immediately, even if the window has
+     *     not loaded (not recommended).
+     */
+    register({ immediate }?: {
+        immediate?: boolean | undefined;
+    }): Promise<ServiceWorkerRegistration | undefined>;
+    /**
+     * Checks for updates of the registered service worker.
+     */
+    update(): Promise<void>;
+    /**
+     * Resolves to the service worker registered by this instance as soon as it
+     * is active. If a service worker was already controlling at registration
+     * time then it will resolve to that if the script URLs (and optionally
+     * script versions) match, otherwise it will wait until an update is found
+     * and activates.
+     *
+     * @return {Promise<ServiceWorker>}
+     */
+    get active(): Promise<ServiceWorker>;
+    /**
+     * Resolves to the service worker registered by this instance as soon as it
+     * is controlling the page. If a service worker was already controlling at
+     * registration time then it will resolve to that if the script URLs (and
+     * optionally script versions) match, otherwise it will wait until an update
+     * is found and starts controlling the page.
+     * Note: the first time a service worker is installed it will active but
+     * not start controlling the page unless `clients.claim()` is called in the
+     * service worker.
+     *
+     * @return {Promise<ServiceWorker>}
+     */
+    get controlling(): Promise<ServiceWorker>;
+    /**
+     * Resolves with a reference to a service worker that matches the script URL
+     * of this instance, as soon as it's available.
+     *
+     * If, at registration time, there's already an active or waiting service
+     * worker with a matching script URL, it will be used (with the waiting
+     * service worker taking precedence over the active service worker if both
+     * match, since the waiting service worker would have been registered more
+     * recently).
+     * If there's no matching active or waiting service worker at registration
+     * time then the promise will not resolve until an update is found and starts
+     * installing, at which point the installing service worker is used.
+     *
+     * @return {Promise<ServiceWorker>}
+     */
+    getSW(): Promise<ServiceWorker>;
+    /**
+     * Sends the passed data object to the service worker registered by this
+     * instance (via {@link workbox-window.Workbox#getSW}) and resolves
+     * with a response (if any).
+     *
+     * A response can be set in a message handler in the service worker by
+     * calling `event.ports[0].postMessage(...)`, which will resolve the promise
+     * returned by `messageSW()`. If no response is set, the promise will never
+     * resolve.
+     *
+     * @param {Object} data An object to send to the service worker
+     * @return {Promise<Object>}
+     */
+    messageSW(data: object): Promise<any>;
+    /**
+     * Sends a `{type: 'SKIP_WAITING'}` message to the service worker that's
+     * currently in the `waiting` state associated with the current registration.
+     *
+     * If there is no current registration or no service worker is `waiting`,
+     * calling this will have no effect.
+     */
+    messageSkipWaiting(): void;
+    /**
+     * Checks for a service worker already controlling the page and returns
+     * it if its script URL matches.
+     *
+     * @private
+     * @return {ServiceWorker|undefined}
+     */
+    private _getControllingSWIfCompatible;
+    /**
+     * Registers a service worker for this instances script URL and register
+     * options and tracks the time registration was complete.
+     *
+     * @private
+     */
+    private _registerScript;
+    /**
+     * @private
+     */
+    private readonly _onUpdateFound;
+    /**
+     * @private
+     * @param {Event} originalEvent
+     */
+    private readonly _onStateChange;
+    /**
+     * @private
+     * @param {Event} originalEvent
+     */
+    private readonly _onControllerChange;
+    /**
+     * @private
+     * @param {Event} originalEvent
+     */
+    private readonly _onMessage;
+}
+export { Workbox };
+/**
+ * The `message` event is dispatched any time a `postMessage` is received.
+ *
+ * @event workbox-window.Workbox#message
+ * @type {WorkboxEvent}
+ * @property {*} data The `data` property from the original `message` event.
+ * @property {Event} originalEvent The original [`message`]{@link https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent}
+ *     event.
+ * @property {string} type `message`.
+ * @property {MessagePort[]} ports The `ports` value from `originalEvent`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+/**
+ * The `installed` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * {@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw|registered service worker}
+ * changes to `installed`.
+ *
+ * Then can happen either the very first time a service worker is installed,
+ * or after an update to the current service worker is found. In the case
+ * of an update being found, the event's `isUpdate` property will be `true`.
+ *
+ * @event workbox-window.Workbox#installed
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {string} type `installed`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+/**
+ * The `waiting` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
+ * changes to `installed` and then doesn't immediately change to `activating`.
+ * It may also be dispatched if a service worker with the same
+ * [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
+ * was already waiting when the {@link workbox-window.Workbox#register}
+ * method was called.
+ *
+ * @event workbox-window.Workbox#waiting
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event|undefined} originalEvent The original
+ *    [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event, or `undefined` in the case where the service worker was waiting
+ *     to before `.register()` was called.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {boolean|undefined} wasWaitingBeforeRegister True if a service worker with
+ *     a matching `scriptURL` was already waiting when this `Workbox`
+ *     instance called `register()`.
+ * @property {string} type `waiting`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+/**
+ * The `controlling` event is dispatched if a
+ * [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
+ * fires on the service worker [container]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer}
+ * and the [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
+ * of the new [controller]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/controller}
+ * matches the `scriptURL` of the `Workbox` instance's
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}.
+ *
+ * @event workbox-window.Workbox#controlling
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this service worker was registered.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {string} type `controlling`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+/**
+ * The `activated` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * {@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw|registered service worker}
+ * changes to `activated`.
+ *
+ * @event workbox-window.Workbox#activated
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {string} type `activated`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+/**
+ * The `redundant` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
+ * changes to `redundant`.
+ *
+ * @event workbox-window.Workbox#redundant
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {string} type `redundant`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
Index: frontend/node_modules/workbox-window/Workbox.js
===================================================================
--- frontend/node_modules/workbox-window/Workbox.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/Workbox.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,620 @@
+/*
+  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.
+*/
+import { Deferred } from 'workbox-core/_private/Deferred.js';
+import { dontWaitFor } from 'workbox-core/_private/dontWaitFor.js';
+import { logger } from 'workbox-core/_private/logger.js';
+import { messageSW } from './messageSW.js';
+import { WorkboxEventTarget } from './utils/WorkboxEventTarget.js';
+import { urlsMatch } from './utils/urlsMatch.js';
+import { WorkboxEvent } from './utils/WorkboxEvent.js';
+import './_version.js';
+// The time a SW must be in the waiting phase before we can conclude
+// `skipWaiting()` wasn't called. This 200 amount wasn't scientifically
+// chosen, but it seems to avoid false positives in my testing.
+const WAITING_TIMEOUT_DURATION = 200;
+// The amount of time after a registration that we can reasonably conclude
+// that the registration didn't trigger an update.
+const REGISTRATION_TIMEOUT_DURATION = 60000;
+// The de facto standard message that a service worker should be listening for
+// to trigger a call to skipWaiting().
+const SKIP_WAITING_MESSAGE = { type: 'SKIP_WAITING' };
+/**
+ * A class to aid in handling service worker registration, updates, and
+ * reacting to service worker lifecycle events.
+ *
+ * @fires {@link workbox-window.Workbox#message}
+ * @fires {@link workbox-window.Workbox#installed}
+ * @fires {@link workbox-window.Workbox#waiting}
+ * @fires {@link workbox-window.Workbox#controlling}
+ * @fires {@link workbox-window.Workbox#activated}
+ * @fires {@link workbox-window.Workbox#redundant}
+ * @memberof workbox-window
+ */
+class Workbox extends WorkboxEventTarget {
+    /**
+     * Creates a new Workbox instance with a script URL and service worker
+     * options. The script URL and options are the same as those used when
+     * calling [navigator.serviceWorker.register(scriptURL, options)](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register).
+     *
+     * @param {string|TrustedScriptURL} scriptURL The service worker script
+     *     associated with this instance. Using a
+     *     [`TrustedScriptURL`](https://web.dev/trusted-types/) is supported.
+     * @param {Object} [registerOptions] The service worker options associated
+     *     with this instance.
+     */
+    // eslint-disable-next-line @typescript-eslint/ban-types
+    constructor(scriptURL, registerOptions = {}) {
+        super();
+        this._registerOptions = {};
+        this._updateFoundCount = 0;
+        // Deferreds we can resolve later.
+        this._swDeferred = new Deferred();
+        this._activeDeferred = new Deferred();
+        this._controllingDeferred = new Deferred();
+        this._registrationTime = 0;
+        this._ownSWs = new Set();
+        /**
+         * @private
+         */
+        this._onUpdateFound = () => {
+            // `this._registration` will never be `undefined` after an update is found.
+            const registration = this._registration;
+            const installingSW = registration.installing;
+            // If the script URL passed to `navigator.serviceWorker.register()` is
+            // different from the current controlling SW's script URL, we know any
+            // successful registration calls will trigger an `updatefound` event.
+            // But if the registered script URL is the same as the current controlling
+            // SW's script URL, we'll only get an `updatefound` event if the file
+            // changed since it was last registered. This can be a problem if the user
+            // opens up the same page in a different tab, and that page registers
+            // a SW that triggers an update. It's a problem because this page has no
+            // good way of knowing whether the `updatefound` event came from the SW
+            // script it registered or from a registration attempt made by a newer
+            // version of the page running in another tab.
+            // To minimize the possibility of a false positive, we use the logic here:
+            const updateLikelyTriggeredExternally = 
+            // Since we enforce only calling `register()` once, and since we don't
+            // add the `updatefound` event listener until the `register()` call, if
+            // `_updateFoundCount` is > 0 then it means this method has already
+            // been called, thus this SW must be external
+            this._updateFoundCount > 0 ||
+                // If the script URL of the installing SW is different from this
+                // instance's script URL, we know it's definitely not from our
+                // registration.
+                !urlsMatch(installingSW.scriptURL, this._scriptURL.toString()) ||
+                // If all of the above are false, then we use a time-based heuristic:
+                // Any `updatefound` event that occurs long after our registration is
+                // assumed to be external.
+                performance.now() > this._registrationTime + REGISTRATION_TIMEOUT_DURATION
+                ? // If any of the above are not true, we assume the update was
+                    // triggered by this instance.
+                    true
+                : false;
+            if (updateLikelyTriggeredExternally) {
+                this._externalSW = installingSW;
+                registration.removeEventListener('updatefound', this._onUpdateFound);
+            }
+            else {
+                // If the update was not triggered externally we know the installing
+                // SW is the one we registered, so we set it.
+                this._sw = installingSW;
+                this._ownSWs.add(installingSW);
+                this._swDeferred.resolve(installingSW);
+                // The `installing` state isn't something we have a dedicated
+                // callback for, but we do log messages for it in development.
+                if (process.env.NODE_ENV !== 'production') {
+                    if (navigator.serviceWorker.controller) {
+                        logger.log('Updated service worker found. Installing now...');
+                    }
+                    else {
+                        logger.log('Service worker is installing...');
+                    }
+                }
+            }
+            // Increment the `updatefound` count, so future invocations of this
+            // method can be sure they were triggered externally.
+            ++this._updateFoundCount;
+            // Add a `statechange` listener regardless of whether this update was
+            // triggered externally, since we have callbacks for both.
+            installingSW.addEventListener('statechange', this._onStateChange);
+        };
+        /**
+         * @private
+         * @param {Event} originalEvent
+         */
+        this._onStateChange = (originalEvent) => {
+            // `this._registration` will never be `undefined` after an update is found.
+            const registration = this._registration;
+            const sw = originalEvent.target;
+            const { state } = sw;
+            const isExternal = sw === this._externalSW;
+            const eventProps = {
+                sw,
+                isExternal,
+                originalEvent,
+            };
+            if (!isExternal && this._isUpdate) {
+                eventProps.isUpdate = true;
+            }
+            this.dispatchEvent(new WorkboxEvent(state, eventProps));
+            if (state === 'installed') {
+                // This timeout is used to ignore cases where the service worker calls
+                // `skipWaiting()` in the install event, thus moving it directly in the
+                // activating state. (Since all service workers *must* go through the
+                // waiting phase, the only way to detect `skipWaiting()` called in the
+                // install event is to observe that the time spent in the waiting phase
+                // is very short.)
+                // NOTE: we don't need separate timeouts for the own and external SWs
+                // since they can't go through these phases at the same time.
+                this._waitingTimeout = self.setTimeout(() => {
+                    // Ensure the SW is still waiting (it may now be redundant).
+                    if (state === 'installed' && registration.waiting === sw) {
+                        this.dispatchEvent(new WorkboxEvent('waiting', eventProps));
+                        if (process.env.NODE_ENV !== 'production') {
+                            if (isExternal) {
+                                logger.warn('An external service worker has installed but is ' +
+                                    'waiting for this client to close before activating...');
+                            }
+                            else {
+                                logger.warn('The service worker has installed but is waiting ' +
+                                    'for existing clients to close before activating...');
+                            }
+                        }
+                    }
+                }, WAITING_TIMEOUT_DURATION);
+            }
+            else if (state === 'activating') {
+                clearTimeout(this._waitingTimeout);
+                if (!isExternal) {
+                    this._activeDeferred.resolve(sw);
+                }
+            }
+            if (process.env.NODE_ENV !== 'production') {
+                switch (state) {
+                    case 'installed':
+                        if (isExternal) {
+                            logger.warn('An external service worker has installed. ' +
+                                'You may want to suggest users reload this page.');
+                        }
+                        else {
+                            logger.log('Registered service worker installed.');
+                        }
+                        break;
+                    case 'activated':
+                        if (isExternal) {
+                            logger.warn('An external service worker has activated.');
+                        }
+                        else {
+                            logger.log('Registered service worker activated.');
+                            if (sw !== navigator.serviceWorker.controller) {
+                                logger.warn('The registered service worker is active but ' +
+                                    'not yet controlling the page. Reload or run ' +
+                                    '`clients.claim()` in the service worker.');
+                            }
+                        }
+                        break;
+                    case 'redundant':
+                        if (sw === this._compatibleControllingSW) {
+                            logger.log('Previously controlling service worker now redundant!');
+                        }
+                        else if (!isExternal) {
+                            logger.log('Registered service worker now redundant!');
+                        }
+                        break;
+                }
+            }
+        };
+        /**
+         * @private
+         * @param {Event} originalEvent
+         */
+        this._onControllerChange = (originalEvent) => {
+            const sw = this._sw;
+            const isExternal = sw !== navigator.serviceWorker.controller;
+            // Unconditionally dispatch the controlling event, with isExternal set
+            // to distinguish between controller changes due to the initial registration
+            // vs. an update-check or other tab's registration.
+            // See https://github.com/GoogleChrome/workbox/issues/2786
+            this.dispatchEvent(new WorkboxEvent('controlling', {
+                isExternal,
+                originalEvent,
+                sw,
+                isUpdate: this._isUpdate,
+            }));
+            if (!isExternal) {
+                if (process.env.NODE_ENV !== 'production') {
+                    logger.log('Registered service worker now controlling this page.');
+                }
+                this._controllingDeferred.resolve(sw);
+            }
+        };
+        /**
+         * @private
+         * @param {Event} originalEvent
+         */
+        this._onMessage = async (originalEvent) => {
+            // Can't change type 'any' of data.
+            // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+            const { data, ports, source } = originalEvent;
+            // Wait until there's an "own" service worker. This is used to buffer
+            // `message` events that may be received prior to calling `register()`.
+            await this.getSW();
+            // If the service worker that sent the message is in the list of own
+            // service workers for this instance, dispatch a `message` event.
+            // NOTE: we check for all previously owned service workers rather than
+            // just the current one because some messages (e.g. cache updates) use
+            // a timeout when sent and may be delayed long enough for a service worker
+            // update to be found.
+            if (this._ownSWs.has(source)) {
+                this.dispatchEvent(new WorkboxEvent('message', {
+                    // Can't change type 'any' of data.
+                    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+                    data,
+                    originalEvent,
+                    ports,
+                    sw: source,
+                }));
+            }
+        };
+        this._scriptURL = scriptURL;
+        this._registerOptions = registerOptions;
+        // Add a message listener immediately since messages received during
+        // page load are buffered only until the DOMContentLoaded event:
+        // https://github.com/GoogleChrome/workbox/issues/2202
+        navigator.serviceWorker.addEventListener('message', this._onMessage);
+    }
+    /**
+     * Registers a service worker for this instances script URL and service
+     * worker options. By default this method delays registration until after
+     * the window has loaded.
+     *
+     * @param {Object} [options]
+     * @param {Function} [options.immediate=false] Setting this to true will
+     *     register the service worker immediately, even if the window has
+     *     not loaded (not recommended).
+     */
+    async register({ immediate = false } = {}) {
+        if (process.env.NODE_ENV !== 'production') {
+            if (this._registrationTime) {
+                logger.error('Cannot re-register a Workbox instance after it has ' +
+                    'been registered. Create a new instance instead.');
+                return;
+            }
+        }
+        if (!immediate && document.readyState !== 'complete') {
+            await new Promise((res) => window.addEventListener('load', res));
+        }
+        // Set this flag to true if any service worker was controlling the page
+        // at registration time.
+        this._isUpdate = Boolean(navigator.serviceWorker.controller);
+        // Before registering, attempt to determine if a SW is already controlling
+        // the page, and if that SW script (and version, if specified) matches this
+        // instance's script.
+        this._compatibleControllingSW = this._getControllingSWIfCompatible();
+        this._registration = await this._registerScript();
+        // If we have a compatible controller, store the controller as the "own"
+        // SW, resolve active/controlling deferreds and add necessary listeners.
+        if (this._compatibleControllingSW) {
+            this._sw = this._compatibleControllingSW;
+            this._activeDeferred.resolve(this._compatibleControllingSW);
+            this._controllingDeferred.resolve(this._compatibleControllingSW);
+            this._compatibleControllingSW.addEventListener('statechange', this._onStateChange, { once: true });
+        }
+        // If there's a waiting service worker with a matching URL before the
+        // `updatefound` event fires, it likely means that this site is open
+        // in another tab, or the user refreshed the page (and thus the previous
+        // page wasn't fully unloaded before this page started loading).
+        // https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#waiting
+        const waitingSW = this._registration.waiting;
+        if (waitingSW &&
+            urlsMatch(waitingSW.scriptURL, this._scriptURL.toString())) {
+            // Store the waiting SW as the "own" Sw, even if it means overwriting
+            // a compatible controller.
+            this._sw = waitingSW;
+            // Run this in the next microtask, so any code that adds an event
+            // listener after awaiting `register()` will get this event.
+            dontWaitFor(Promise.resolve().then(() => {
+                this.dispatchEvent(new WorkboxEvent('waiting', {
+                    sw: waitingSW,
+                    wasWaitingBeforeRegister: true,
+                }));
+                if (process.env.NODE_ENV !== 'production') {
+                    logger.warn('A service worker was already waiting to activate ' +
+                        'before this script was registered...');
+                }
+            }));
+        }
+        // If an "own" SW is already set, resolve the deferred.
+        if (this._sw) {
+            this._swDeferred.resolve(this._sw);
+            this._ownSWs.add(this._sw);
+        }
+        if (process.env.NODE_ENV !== 'production') {
+            logger.log('Successfully registered service worker.', this._scriptURL.toString());
+            if (navigator.serviceWorker.controller) {
+                if (this._compatibleControllingSW) {
+                    logger.debug('A service worker with the same script URL ' +
+                        'is already controlling this page.');
+                }
+                else {
+                    logger.debug('A service worker with a different script URL is ' +
+                        'currently controlling the page. The browser is now fetching ' +
+                        'the new script now...');
+                }
+            }
+            const currentPageIsOutOfScope = () => {
+                const scopeURL = new URL(this._registerOptions.scope || this._scriptURL.toString(), document.baseURI);
+                const scopeURLBasePath = new URL('./', scopeURL.href).pathname;
+                return !location.pathname.startsWith(scopeURLBasePath);
+            };
+            if (currentPageIsOutOfScope()) {
+                logger.warn('The current page is not in scope for the registered ' +
+                    'service worker. Was this a mistake?');
+            }
+        }
+        this._registration.addEventListener('updatefound', this._onUpdateFound);
+        navigator.serviceWorker.addEventListener('controllerchange', this._onControllerChange);
+        return this._registration;
+    }
+    /**
+     * Checks for updates of the registered service worker.
+     */
+    async update() {
+        if (!this._registration) {
+            if (process.env.NODE_ENV !== 'production') {
+                logger.error('Cannot update a Workbox instance without ' +
+                    'being registered. Register the Workbox instance first.');
+            }
+            return;
+        }
+        // Try to update registration
+        await this._registration.update();
+    }
+    /**
+     * Resolves to the service worker registered by this instance as soon as it
+     * is active. If a service worker was already controlling at registration
+     * time then it will resolve to that if the script URLs (and optionally
+     * script versions) match, otherwise it will wait until an update is found
+     * and activates.
+     *
+     * @return {Promise<ServiceWorker>}
+     */
+    get active() {
+        return this._activeDeferred.promise;
+    }
+    /**
+     * Resolves to the service worker registered by this instance as soon as it
+     * is controlling the page. If a service worker was already controlling at
+     * registration time then it will resolve to that if the script URLs (and
+     * optionally script versions) match, otherwise it will wait until an update
+     * is found and starts controlling the page.
+     * Note: the first time a service worker is installed it will active but
+     * not start controlling the page unless `clients.claim()` is called in the
+     * service worker.
+     *
+     * @return {Promise<ServiceWorker>}
+     */
+    get controlling() {
+        return this._controllingDeferred.promise;
+    }
+    /**
+     * Resolves with a reference to a service worker that matches the script URL
+     * of this instance, as soon as it's available.
+     *
+     * If, at registration time, there's already an active or waiting service
+     * worker with a matching script URL, it will be used (with the waiting
+     * service worker taking precedence over the active service worker if both
+     * match, since the waiting service worker would have been registered more
+     * recently).
+     * If there's no matching active or waiting service worker at registration
+     * time then the promise will not resolve until an update is found and starts
+     * installing, at which point the installing service worker is used.
+     *
+     * @return {Promise<ServiceWorker>}
+     */
+    getSW() {
+        // If `this._sw` is set, resolve with that as we want `getSW()` to
+        // return the correct (new) service worker if an update is found.
+        return this._sw !== undefined
+            ? Promise.resolve(this._sw)
+            : this._swDeferred.promise;
+    }
+    /**
+     * Sends the passed data object to the service worker registered by this
+     * instance (via {@link workbox-window.Workbox#getSW}) and resolves
+     * with a response (if any).
+     *
+     * A response can be set in a message handler in the service worker by
+     * calling `event.ports[0].postMessage(...)`, which will resolve the promise
+     * returned by `messageSW()`. If no response is set, the promise will never
+     * resolve.
+     *
+     * @param {Object} data An object to send to the service worker
+     * @return {Promise<Object>}
+     */
+    // We might be able to change the 'data' type to Record<string, unknown> in the future.
+    // eslint-disable-next-line @typescript-eslint/ban-types
+    async messageSW(data) {
+        const sw = await this.getSW();
+        return messageSW(sw, data);
+    }
+    /**
+     * Sends a `{type: 'SKIP_WAITING'}` message to the service worker that's
+     * currently in the `waiting` state associated with the current registration.
+     *
+     * If there is no current registration or no service worker is `waiting`,
+     * calling this will have no effect.
+     */
+    messageSkipWaiting() {
+        if (this._registration && this._registration.waiting) {
+            void messageSW(this._registration.waiting, SKIP_WAITING_MESSAGE);
+        }
+    }
+    /**
+     * Checks for a service worker already controlling the page and returns
+     * it if its script URL matches.
+     *
+     * @private
+     * @return {ServiceWorker|undefined}
+     */
+    _getControllingSWIfCompatible() {
+        const controller = navigator.serviceWorker.controller;
+        if (controller &&
+            urlsMatch(controller.scriptURL, this._scriptURL.toString())) {
+            return controller;
+        }
+        else {
+            return undefined;
+        }
+    }
+    /**
+     * Registers a service worker for this instances script URL and register
+     * options and tracks the time registration was complete.
+     *
+     * @private
+     */
+    async _registerScript() {
+        try {
+            // this._scriptURL may be a TrustedScriptURL, but there's no support for
+            // passing that to register() in lib.dom right now.
+            // https://github.com/GoogleChrome/workbox/issues/2855
+            const reg = await navigator.serviceWorker.register(this._scriptURL, this._registerOptions);
+            // Keep track of when registration happened, so it can be used in the
+            // `this._onUpdateFound` heuristic. Also use the presence of this
+            // property as a way to see if `.register()` has been called.
+            this._registrationTime = performance.now();
+            return reg;
+        }
+        catch (error) {
+            if (process.env.NODE_ENV !== 'production') {
+                logger.error(error);
+            }
+            // Re-throw the error.
+            throw error;
+        }
+    }
+}
+export { Workbox };
+// The jsdoc comments below outline the events this instance may dispatch:
+// -----------------------------------------------------------------------
+/**
+ * The `message` event is dispatched any time a `postMessage` is received.
+ *
+ * @event workbox-window.Workbox#message
+ * @type {WorkboxEvent}
+ * @property {*} data The `data` property from the original `message` event.
+ * @property {Event} originalEvent The original [`message`]{@link https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent}
+ *     event.
+ * @property {string} type `message`.
+ * @property {MessagePort[]} ports The `ports` value from `originalEvent`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+/**
+ * The `installed` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * {@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw|registered service worker}
+ * changes to `installed`.
+ *
+ * Then can happen either the very first time a service worker is installed,
+ * or after an update to the current service worker is found. In the case
+ * of an update being found, the event's `isUpdate` property will be `true`.
+ *
+ * @event workbox-window.Workbox#installed
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {string} type `installed`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+/**
+ * The `waiting` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
+ * changes to `installed` and then doesn't immediately change to `activating`.
+ * It may also be dispatched if a service worker with the same
+ * [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
+ * was already waiting when the {@link workbox-window.Workbox#register}
+ * method was called.
+ *
+ * @event workbox-window.Workbox#waiting
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event|undefined} originalEvent The original
+ *    [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event, or `undefined` in the case where the service worker was waiting
+ *     to before `.register()` was called.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {boolean|undefined} wasWaitingBeforeRegister True if a service worker with
+ *     a matching `scriptURL` was already waiting when this `Workbox`
+ *     instance called `register()`.
+ * @property {string} type `waiting`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+/**
+ * The `controlling` event is dispatched if a
+ * [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
+ * fires on the service worker [container]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer}
+ * and the [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
+ * of the new [controller]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/controller}
+ * matches the `scriptURL` of the `Workbox` instance's
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}.
+ *
+ * @event workbox-window.Workbox#controlling
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this service worker was registered.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {string} type `controlling`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+/**
+ * The `activated` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * {@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw|registered service worker}
+ * changes to `activated`.
+ *
+ * @event workbox-window.Workbox#activated
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {string} type `activated`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+/**
+ * The `redundant` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
+ * changes to `redundant`.
+ *
+ * @event workbox-window.Workbox#redundant
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {string} type `redundant`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
Index: frontend/node_modules/workbox-window/Workbox.mjs
===================================================================
--- frontend/node_modules/workbox-window/Workbox.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/Workbox.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export * from './Workbox.js';
Index: frontend/node_modules/workbox-window/_version.js
===================================================================
--- frontend/node_modules/workbox-window/_version.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/_version.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,6 @@
+"use strict";
+// @ts-ignore
+try {
+    self['workbox:window:6.5.4'] && _();
+}
+catch (e) { }
Index: frontend/node_modules/workbox-window/_version.mjs
===================================================================
--- frontend/node_modules/workbox-window/_version.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/_version.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+try{self['workbox:window:6.6.0']&&_()}catch(e){}// eslint-disable-line
Index: frontend/node_modules/workbox-window/index.d.ts
===================================================================
--- frontend/node_modules/workbox-window/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,8 @@
+import { messageSW } from './messageSW.js';
+import { Workbox } from './Workbox.js';
+import './_version.js';
+/**
+ * @module workbox-window
+ */
+export { messageSW, Workbox };
+export * from './utils/WorkboxEvent.js';
Index: frontend/node_modules/workbox-window/index.js
===================================================================
--- frontend/node_modules/workbox-window/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,16 @@
+/*
+  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.
+*/
+import { messageSW } from './messageSW.js';
+import { Workbox } from './Workbox.js';
+import './_version.js';
+/**
+ * @module workbox-window
+ */
+export { messageSW, Workbox };
+// See https://github.com/GoogleChrome/workbox/issues/2770
+export * from './utils/WorkboxEvent.js';
Index: frontend/node_modules/workbox-window/index.mjs
===================================================================
--- frontend/node_modules/workbox-window/index.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/index.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export * from './index.js';
Index: frontend/node_modules/workbox-window/messageSW.d.ts
===================================================================
--- frontend/node_modules/workbox-window/messageSW.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/messageSW.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+import './_version.js';
+/**
+ * Sends a data object to a service worker via `postMessage` and resolves with
+ * a response (if any).
+ *
+ * A response can be set in a message handler in the service worker by
+ * calling `event.ports[0].postMessage(...)`, which will resolve the promise
+ * returned by `messageSW()`. If no response is set, the promise will not
+ * resolve.
+ *
+ * @param {ServiceWorker} sw The service worker to send the message to.
+ * @param {Object} data An object to send to the service worker.
+ * @return {Promise<Object|undefined>}
+ * @memberof workbox-window
+ */
+declare function messageSW(sw: ServiceWorker, data: {}): Promise<any>;
+export { messageSW };
Index: frontend/node_modules/workbox-window/messageSW.js
===================================================================
--- frontend/node_modules/workbox-window/messageSW.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/messageSW.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,34 @@
+/*
+  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.
+*/
+import './_version.js';
+/**
+ * Sends a data object to a service worker via `postMessage` and resolves with
+ * a response (if any).
+ *
+ * A response can be set in a message handler in the service worker by
+ * calling `event.ports[0].postMessage(...)`, which will resolve the promise
+ * returned by `messageSW()`. If no response is set, the promise will not
+ * resolve.
+ *
+ * @param {ServiceWorker} sw The service worker to send the message to.
+ * @param {Object} data An object to send to the service worker.
+ * @return {Promise<Object|undefined>}
+ * @memberof workbox-window
+ */
+// Better not change type of data.
+// eslint-disable-next-line @typescript-eslint/ban-types
+function messageSW(sw, data) {
+    return new Promise((resolve) => {
+        const messageChannel = new MessageChannel();
+        messageChannel.port1.onmessage = (event) => {
+            resolve(event.data);
+        };
+        sw.postMessage(data, [messageChannel.port2]);
+    });
+}
+export { messageSW };
Index: frontend/node_modules/workbox-window/messageSW.mjs
===================================================================
--- frontend/node_modules/workbox-window/messageSW.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/messageSW.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export * from './messageSW.js';
Index: frontend/node_modules/workbox-window/package.json
===================================================================
--- frontend/node_modules/workbox-window/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,31 @@
+{
+  "name": "workbox-window",
+  "version": "6.6.0",
+  "license": "MIT",
+  "author": "Google's Web DevRel Team",
+  "description": "Simplifies communications with Workbox packages running in the service worker",
+  "repository": "googlechrome/workbox",
+  "bugs": "https://github.com/googlechrome/workbox/issues",
+  "homepage": "https://github.com/GoogleChrome/workbox",
+  "keywords": [
+    "workbox",
+    "workboxjs",
+    "service worker",
+    "sw",
+    "window",
+    "message",
+    "postMessage"
+  ],
+  "workbox": {
+    "packageType": "window",
+    "primaryBuild": "build/workbox-window.prod.mjs"
+  },
+  "main": "build/workbox-window.prod.umd.js",
+  "module": "build/workbox-window.prod.es5.mjs",
+  "types": "index.d.ts",
+  "dependencies": {
+    "@types/trusted-types": "^2.0.2",
+    "workbox-core": "6.6.0"
+  },
+  "gitHead": "252644491d9bb5a67518935ede6df530107c9475"
+}
Index: frontend/node_modules/workbox-window/src/Workbox.ts
===================================================================
--- frontend/node_modules/workbox-window/src/Workbox.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/src/Workbox.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,740 @@
+/*
+  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.
+*/
+
+import {Deferred} from 'workbox-core/_private/Deferred.js';
+import {dontWaitFor} from 'workbox-core/_private/dontWaitFor.js';
+import {logger} from 'workbox-core/_private/logger.js';
+import {TrustedScriptURL} from 'trusted-types/lib';
+
+import {messageSW} from './messageSW.js';
+import {WorkboxEventTarget} from './utils/WorkboxEventTarget.js';
+import {urlsMatch} from './utils/urlsMatch.js';
+import {WorkboxEvent, WorkboxLifecycleEventMap} from './utils/WorkboxEvent.js';
+
+import './_version.js';
+
+// The time a SW must be in the waiting phase before we can conclude
+// `skipWaiting()` wasn't called. This 200 amount wasn't scientifically
+// chosen, but it seems to avoid false positives in my testing.
+const WAITING_TIMEOUT_DURATION = 200;
+
+// The amount of time after a registration that we can reasonably conclude
+// that the registration didn't trigger an update.
+const REGISTRATION_TIMEOUT_DURATION = 60000;
+
+// The de facto standard message that a service worker should be listening for
+// to trigger a call to skipWaiting().
+const SKIP_WAITING_MESSAGE = {type: 'SKIP_WAITING'};
+
+/**
+ * A class to aid in handling service worker registration, updates, and
+ * reacting to service worker lifecycle events.
+ *
+ * @fires {@link workbox-window.Workbox#message}
+ * @fires {@link workbox-window.Workbox#installed}
+ * @fires {@link workbox-window.Workbox#waiting}
+ * @fires {@link workbox-window.Workbox#controlling}
+ * @fires {@link workbox-window.Workbox#activated}
+ * @fires {@link workbox-window.Workbox#redundant}
+ * @memberof workbox-window
+ */
+class Workbox extends WorkboxEventTarget {
+  private readonly _scriptURL: string | TrustedScriptURL;
+  private readonly _registerOptions: RegistrationOptions = {};
+  private _updateFoundCount = 0;
+
+  // Deferreds we can resolve later.
+  private readonly _swDeferred: Deferred<ServiceWorker> = new Deferred();
+  private readonly _activeDeferred: Deferred<ServiceWorker> = new Deferred();
+  private readonly _controllingDeferred: Deferred<ServiceWorker> =
+    new Deferred();
+
+  private _registrationTime: DOMHighResTimeStamp = 0;
+  private _isUpdate?: boolean;
+  private _compatibleControllingSW?: ServiceWorker;
+  private _registration?: ServiceWorkerRegistration;
+  private _sw?: ServiceWorker;
+  private readonly _ownSWs: Set<ServiceWorker> = new Set();
+  private _externalSW?: ServiceWorker;
+  private _waitingTimeout?: number;
+
+  /**
+   * Creates a new Workbox instance with a script URL and service worker
+   * options. The script URL and options are the same as those used when
+   * calling [navigator.serviceWorker.register(scriptURL, options)](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register).
+   *
+   * @param {string|TrustedScriptURL} scriptURL The service worker script
+   *     associated with this instance. Using a
+   *     [`TrustedScriptURL`](https://web.dev/trusted-types/) is supported.
+   * @param {Object} [registerOptions] The service worker options associated
+   *     with this instance.
+   */
+  // eslint-disable-next-line @typescript-eslint/ban-types
+  constructor(scriptURL: string | TrustedScriptURL, registerOptions: {} = {}) {
+    super();
+
+    this._scriptURL = scriptURL;
+    this._registerOptions = registerOptions;
+
+    // Add a message listener immediately since messages received during
+    // page load are buffered only until the DOMContentLoaded event:
+    // https://github.com/GoogleChrome/workbox/issues/2202
+    navigator.serviceWorker.addEventListener('message', this._onMessage);
+  }
+
+  /**
+   * Registers a service worker for this instances script URL and service
+   * worker options. By default this method delays registration until after
+   * the window has loaded.
+   *
+   * @param {Object} [options]
+   * @param {Function} [options.immediate=false] Setting this to true will
+   *     register the service worker immediately, even if the window has
+   *     not loaded (not recommended).
+   */
+  async register({immediate = false} = {}): Promise<
+    ServiceWorkerRegistration | undefined
+  > {
+    if (process.env.NODE_ENV !== 'production') {
+      if (this._registrationTime) {
+        logger.error(
+          'Cannot re-register a Workbox instance after it has ' +
+            'been registered. Create a new instance instead.',
+        );
+        return;
+      }
+    }
+
+    if (!immediate && document.readyState !== 'complete') {
+      await new Promise((res) => window.addEventListener('load', res));
+    }
+
+    // Set this flag to true if any service worker was controlling the page
+    // at registration time.
+    this._isUpdate = Boolean(navigator.serviceWorker.controller);
+
+    // Before registering, attempt to determine if a SW is already controlling
+    // the page, and if that SW script (and version, if specified) matches this
+    // instance's script.
+    this._compatibleControllingSW = this._getControllingSWIfCompatible();
+
+    this._registration = await this._registerScript();
+
+    // If we have a compatible controller, store the controller as the "own"
+    // SW, resolve active/controlling deferreds and add necessary listeners.
+    if (this._compatibleControllingSW) {
+      this._sw = this._compatibleControllingSW;
+      this._activeDeferred.resolve(this._compatibleControllingSW);
+      this._controllingDeferred.resolve(this._compatibleControllingSW);
+
+      this._compatibleControllingSW.addEventListener(
+        'statechange',
+        this._onStateChange,
+        {once: true},
+      );
+    }
+
+    // If there's a waiting service worker with a matching URL before the
+    // `updatefound` event fires, it likely means that this site is open
+    // in another tab, or the user refreshed the page (and thus the previous
+    // page wasn't fully unloaded before this page started loading).
+    // https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#waiting
+    const waitingSW = this._registration.waiting;
+    if (
+      waitingSW &&
+      urlsMatch(waitingSW.scriptURL, this._scriptURL.toString())
+    ) {
+      // Store the waiting SW as the "own" Sw, even if it means overwriting
+      // a compatible controller.
+      this._sw = waitingSW;
+
+      // Run this in the next microtask, so any code that adds an event
+      // listener after awaiting `register()` will get this event.
+      dontWaitFor(
+        Promise.resolve().then(() => {
+          this.dispatchEvent(
+            new WorkboxEvent('waiting', {
+              sw: waitingSW,
+              wasWaitingBeforeRegister: true,
+            }),
+          );
+          if (process.env.NODE_ENV !== 'production') {
+            logger.warn(
+              'A service worker was already waiting to activate ' +
+                'before this script was registered...',
+            );
+          }
+        }),
+      );
+    }
+
+    // If an "own" SW is already set, resolve the deferred.
+    if (this._sw) {
+      this._swDeferred.resolve(this._sw);
+      this._ownSWs.add(this._sw);
+    }
+
+    if (process.env.NODE_ENV !== 'production') {
+      logger.log(
+        'Successfully registered service worker.',
+        this._scriptURL.toString(),
+      );
+
+      if (navigator.serviceWorker.controller) {
+        if (this._compatibleControllingSW) {
+          logger.debug(
+            'A service worker with the same script URL ' +
+              'is already controlling this page.',
+          );
+        } else {
+          logger.debug(
+            'A service worker with a different script URL is ' +
+              'currently controlling the page. The browser is now fetching ' +
+              'the new script now...',
+          );
+        }
+      }
+
+      const currentPageIsOutOfScope = () => {
+        const scopeURL = new URL(
+          this._registerOptions.scope || this._scriptURL.toString(),
+          document.baseURI,
+        );
+        const scopeURLBasePath = new URL('./', scopeURL.href).pathname;
+        return !location.pathname.startsWith(scopeURLBasePath);
+      };
+      if (currentPageIsOutOfScope()) {
+        logger.warn(
+          'The current page is not in scope for the registered ' +
+            'service worker. Was this a mistake?',
+        );
+      }
+    }
+
+    this._registration.addEventListener('updatefound', this._onUpdateFound);
+    navigator.serviceWorker.addEventListener(
+      'controllerchange',
+      this._onControllerChange,
+    );
+
+    return this._registration;
+  }
+
+  /**
+   * Checks for updates of the registered service worker.
+   */
+  async update(): Promise<void> {
+    if (!this._registration) {
+      if (process.env.NODE_ENV !== 'production') {
+        logger.error(
+          'Cannot update a Workbox instance without ' +
+            'being registered. Register the Workbox instance first.',
+        );
+      }
+      return;
+    }
+
+    // Try to update registration
+    await this._registration.update();
+  }
+
+  /**
+   * Resolves to the service worker registered by this instance as soon as it
+   * is active. If a service worker was already controlling at registration
+   * time then it will resolve to that if the script URLs (and optionally
+   * script versions) match, otherwise it will wait until an update is found
+   * and activates.
+   *
+   * @return {Promise<ServiceWorker>}
+   */
+  get active(): Promise<ServiceWorker> {
+    return this._activeDeferred.promise;
+  }
+
+  /**
+   * Resolves to the service worker registered by this instance as soon as it
+   * is controlling the page. If a service worker was already controlling at
+   * registration time then it will resolve to that if the script URLs (and
+   * optionally script versions) match, otherwise it will wait until an update
+   * is found and starts controlling the page.
+   * Note: the first time a service worker is installed it will active but
+   * not start controlling the page unless `clients.claim()` is called in the
+   * service worker.
+   *
+   * @return {Promise<ServiceWorker>}
+   */
+  get controlling(): Promise<ServiceWorker> {
+    return this._controllingDeferred.promise;
+  }
+
+  /**
+   * Resolves with a reference to a service worker that matches the script URL
+   * of this instance, as soon as it's available.
+   *
+   * If, at registration time, there's already an active or waiting service
+   * worker with a matching script URL, it will be used (with the waiting
+   * service worker taking precedence over the active service worker if both
+   * match, since the waiting service worker would have been registered more
+   * recently).
+   * If there's no matching active or waiting service worker at registration
+   * time then the promise will not resolve until an update is found and starts
+   * installing, at which point the installing service worker is used.
+   *
+   * @return {Promise<ServiceWorker>}
+   */
+  getSW(): Promise<ServiceWorker> {
+    // If `this._sw` is set, resolve with that as we want `getSW()` to
+    // return the correct (new) service worker if an update is found.
+    return this._sw !== undefined
+      ? Promise.resolve(this._sw)
+      : this._swDeferred.promise;
+  }
+
+  /**
+   * Sends the passed data object to the service worker registered by this
+   * instance (via {@link workbox-window.Workbox#getSW}) and resolves
+   * with a response (if any).
+   *
+   * A response can be set in a message handler in the service worker by
+   * calling `event.ports[0].postMessage(...)`, which will resolve the promise
+   * returned by `messageSW()`. If no response is set, the promise will never
+   * resolve.
+   *
+   * @param {Object} data An object to send to the service worker
+   * @return {Promise<Object>}
+   */
+  // We might be able to change the 'data' type to Record<string, unknown> in the future.
+  // eslint-disable-next-line @typescript-eslint/ban-types
+  async messageSW(data: object): Promise<any> {
+    const sw = await this.getSW();
+    return messageSW(sw, data);
+  }
+
+  /**
+   * Sends a `{type: 'SKIP_WAITING'}` message to the service worker that's
+   * currently in the `waiting` state associated with the current registration.
+   *
+   * If there is no current registration or no service worker is `waiting`,
+   * calling this will have no effect.
+   */
+  messageSkipWaiting(): void {
+    if (this._registration && this._registration.waiting) {
+      void messageSW(this._registration.waiting, SKIP_WAITING_MESSAGE);
+    }
+  }
+
+  /**
+   * Checks for a service worker already controlling the page and returns
+   * it if its script URL matches.
+   *
+   * @private
+   * @return {ServiceWorker|undefined}
+   */
+  private _getControllingSWIfCompatible() {
+    const controller = navigator.serviceWorker.controller;
+    if (
+      controller &&
+      urlsMatch(controller.scriptURL, this._scriptURL.toString())
+    ) {
+      return controller;
+    } else {
+      return undefined;
+    }
+  }
+
+  /**
+   * Registers a service worker for this instances script URL and register
+   * options and tracks the time registration was complete.
+   *
+   * @private
+   */
+  private async _registerScript() {
+    try {
+      // this._scriptURL may be a TrustedScriptURL, but there's no support for
+      // passing that to register() in lib.dom right now.
+      // https://github.com/GoogleChrome/workbox/issues/2855
+      const reg = await navigator.serviceWorker.register(
+        this._scriptURL as string,
+        this._registerOptions,
+      );
+
+      // Keep track of when registration happened, so it can be used in the
+      // `this._onUpdateFound` heuristic. Also use the presence of this
+      // property as a way to see if `.register()` has been called.
+      this._registrationTime = performance.now();
+
+      return reg;
+    } catch (error) {
+      if (process.env.NODE_ENV !== 'production') {
+        logger.error(error);
+      }
+      // Re-throw the error.
+      throw error;
+    }
+  }
+
+  /**
+   * @private
+   */
+  private readonly _onUpdateFound = () => {
+    // `this._registration` will never be `undefined` after an update is found.
+    const registration = this._registration!;
+    const installingSW = registration.installing as ServiceWorker;
+
+    // If the script URL passed to `navigator.serviceWorker.register()` is
+    // different from the current controlling SW's script URL, we know any
+    // successful registration calls will trigger an `updatefound` event.
+    // But if the registered script URL is the same as the current controlling
+    // SW's script URL, we'll only get an `updatefound` event if the file
+    // changed since it was last registered. This can be a problem if the user
+    // opens up the same page in a different tab, and that page registers
+    // a SW that triggers an update. It's a problem because this page has no
+    // good way of knowing whether the `updatefound` event came from the SW
+    // script it registered or from a registration attempt made by a newer
+    // version of the page running in another tab.
+    // To minimize the possibility of a false positive, we use the logic here:
+    const updateLikelyTriggeredExternally =
+      // Since we enforce only calling `register()` once, and since we don't
+      // add the `updatefound` event listener until the `register()` call, if
+      // `_updateFoundCount` is > 0 then it means this method has already
+      // been called, thus this SW must be external
+      this._updateFoundCount > 0 ||
+      // If the script URL of the installing SW is different from this
+      // instance's script URL, we know it's definitely not from our
+      // registration.
+      !urlsMatch(installingSW.scriptURL, this._scriptURL.toString()) ||
+      // If all of the above are false, then we use a time-based heuristic:
+      // Any `updatefound` event that occurs long after our registration is
+      // assumed to be external.
+      performance.now() > this._registrationTime + REGISTRATION_TIMEOUT_DURATION
+        ? // If any of the above are not true, we assume the update was
+          // triggered by this instance.
+          true
+        : false;
+
+    if (updateLikelyTriggeredExternally) {
+      this._externalSW = installingSW;
+      registration.removeEventListener('updatefound', this._onUpdateFound);
+    } else {
+      // If the update was not triggered externally we know the installing
+      // SW is the one we registered, so we set it.
+      this._sw = installingSW;
+      this._ownSWs.add(installingSW);
+      this._swDeferred.resolve(installingSW);
+
+      // The `installing` state isn't something we have a dedicated
+      // callback for, but we do log messages for it in development.
+      if (process.env.NODE_ENV !== 'production') {
+        if (navigator.serviceWorker.controller) {
+          logger.log('Updated service worker found. Installing now...');
+        } else {
+          logger.log('Service worker is installing...');
+        }
+      }
+    }
+
+    // Increment the `updatefound` count, so future invocations of this
+    // method can be sure they were triggered externally.
+    ++this._updateFoundCount;
+
+    // Add a `statechange` listener regardless of whether this update was
+    // triggered externally, since we have callbacks for both.
+    installingSW.addEventListener('statechange', this._onStateChange);
+  };
+
+  /**
+   * @private
+   * @param {Event} originalEvent
+   */
+  private readonly _onStateChange = (originalEvent: Event) => {
+    // `this._registration` will never be `undefined` after an update is found.
+    const registration = this._registration!;
+    const sw = originalEvent.target as ServiceWorker;
+    const {state} = sw;
+    const isExternal = sw === this._externalSW;
+
+    const eventProps: {
+      sw: ServiceWorker;
+      originalEvent: Event;
+      isUpdate?: boolean;
+      isExternal: boolean;
+    } = {
+      sw,
+      isExternal,
+      originalEvent,
+    };
+    if (!isExternal && this._isUpdate) {
+      eventProps.isUpdate = true;
+    }
+
+    this.dispatchEvent(
+      new WorkboxEvent(state as keyof WorkboxLifecycleEventMap, eventProps),
+    );
+
+    if (state === 'installed') {
+      // This timeout is used to ignore cases where the service worker calls
+      // `skipWaiting()` in the install event, thus moving it directly in the
+      // activating state. (Since all service workers *must* go through the
+      // waiting phase, the only way to detect `skipWaiting()` called in the
+      // install event is to observe that the time spent in the waiting phase
+      // is very short.)
+      // NOTE: we don't need separate timeouts for the own and external SWs
+      // since they can't go through these phases at the same time.
+      this._waitingTimeout = self.setTimeout(() => {
+        // Ensure the SW is still waiting (it may now be redundant).
+        if (state === 'installed' && registration.waiting === sw) {
+          this.dispatchEvent(new WorkboxEvent('waiting', eventProps));
+
+          if (process.env.NODE_ENV !== 'production') {
+            if (isExternal) {
+              logger.warn(
+                'An external service worker has installed but is ' +
+                  'waiting for this client to close before activating...',
+              );
+            } else {
+              logger.warn(
+                'The service worker has installed but is waiting ' +
+                  'for existing clients to close before activating...',
+              );
+            }
+          }
+        }
+      }, WAITING_TIMEOUT_DURATION);
+    } else if (state === 'activating') {
+      clearTimeout(this._waitingTimeout);
+      if (!isExternal) {
+        this._activeDeferred.resolve(sw);
+      }
+    }
+
+    if (process.env.NODE_ENV !== 'production') {
+      switch (state) {
+        case 'installed':
+          if (isExternal) {
+            logger.warn(
+              'An external service worker has installed. ' +
+                'You may want to suggest users reload this page.',
+            );
+          } else {
+            logger.log('Registered service worker installed.');
+          }
+          break;
+        case 'activated':
+          if (isExternal) {
+            logger.warn('An external service worker has activated.');
+          } else {
+            logger.log('Registered service worker activated.');
+            if (sw !== navigator.serviceWorker.controller) {
+              logger.warn(
+                'The registered service worker is active but ' +
+                  'not yet controlling the page. Reload or run ' +
+                  '`clients.claim()` in the service worker.',
+              );
+            }
+          }
+          break;
+        case 'redundant':
+          if (sw === this._compatibleControllingSW) {
+            logger.log('Previously controlling service worker now redundant!');
+          } else if (!isExternal) {
+            logger.log('Registered service worker now redundant!');
+          }
+          break;
+      }
+    }
+  };
+
+  /**
+   * @private
+   * @param {Event} originalEvent
+   */
+  private readonly _onControllerChange = (originalEvent: Event) => {
+    const sw = this._sw;
+    const isExternal = sw !== navigator.serviceWorker.controller;
+
+    // Unconditionally dispatch the controlling event, with isExternal set
+    // to distinguish between controller changes due to the initial registration
+    // vs. an update-check or other tab's registration.
+    // See https://github.com/GoogleChrome/workbox/issues/2786
+    this.dispatchEvent(
+      new WorkboxEvent('controlling', {
+        isExternal,
+        originalEvent,
+        sw,
+        isUpdate: this._isUpdate,
+      }),
+    );
+
+    if (!isExternal) {
+      if (process.env.NODE_ENV !== 'production') {
+        logger.log('Registered service worker now controlling this page.');
+      }
+      this._controllingDeferred.resolve(sw);
+    }
+  };
+
+  /**
+   * @private
+   * @param {Event} originalEvent
+   */
+  private readonly _onMessage = async (originalEvent: MessageEvent) => {
+    // Can't change type 'any' of data.
+    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+    const {data, ports, source} = originalEvent;
+
+    // Wait until there's an "own" service worker. This is used to buffer
+    // `message` events that may be received prior to calling `register()`.
+    await this.getSW();
+
+    // If the service worker that sent the message is in the list of own
+    // service workers for this instance, dispatch a `message` event.
+    // NOTE: we check for all previously owned service workers rather than
+    // just the current one because some messages (e.g. cache updates) use
+    // a timeout when sent and may be delayed long enough for a service worker
+    // update to be found.
+    if (this._ownSWs.has(source as ServiceWorker)) {
+      this.dispatchEvent(
+        new WorkboxEvent('message', {
+          // Can't change type 'any' of data.
+          // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+          data,
+          originalEvent,
+          ports,
+          sw: source as ServiceWorker,
+        }),
+      );
+    }
+  };
+}
+
+export {Workbox};
+
+// The jsdoc comments below outline the events this instance may dispatch:
+// -----------------------------------------------------------------------
+
+/**
+ * The `message` event is dispatched any time a `postMessage` is received.
+ *
+ * @event workbox-window.Workbox#message
+ * @type {WorkboxEvent}
+ * @property {*} data The `data` property from the original `message` event.
+ * @property {Event} originalEvent The original [`message`]{@link https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent}
+ *     event.
+ * @property {string} type `message`.
+ * @property {MessagePort[]} ports The `ports` value from `originalEvent`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+
+/**
+ * The `installed` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * {@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw|registered service worker}
+ * changes to `installed`.
+ *
+ * Then can happen either the very first time a service worker is installed,
+ * or after an update to the current service worker is found. In the case
+ * of an update being found, the event's `isUpdate` property will be `true`.
+ *
+ * @event workbox-window.Workbox#installed
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {string} type `installed`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+
+/**
+ * The `waiting` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
+ * changes to `installed` and then doesn't immediately change to `activating`.
+ * It may also be dispatched if a service worker with the same
+ * [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
+ * was already waiting when the {@link workbox-window.Workbox#register}
+ * method was called.
+ *
+ * @event workbox-window.Workbox#waiting
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event|undefined} originalEvent The original
+ *    [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event, or `undefined` in the case where the service worker was waiting
+ *     to before `.register()` was called.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {boolean|undefined} wasWaitingBeforeRegister True if a service worker with
+ *     a matching `scriptURL` was already waiting when this `Workbox`
+ *     instance called `register()`.
+ * @property {string} type `waiting`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+
+/**
+ * The `controlling` event is dispatched if a
+ * [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
+ * fires on the service worker [container]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer}
+ * and the [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
+ * of the new [controller]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/controller}
+ * matches the `scriptURL` of the `Workbox` instance's
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}.
+ *
+ * @event workbox-window.Workbox#controlling
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this service worker was registered.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {string} type `controlling`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+
+/**
+ * The `activated` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * {@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw|registered service worker}
+ * changes to `activated`.
+ *
+ * @event workbox-window.Workbox#activated
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {boolean|undefined} isExternal True if this event is associated
+ *     with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
+ * @property {string} type `activated`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
+
+/**
+ * The `redundant` event is dispatched if the state of a
+ * {@link workbox-window.Workbox} instance's
+ * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
+ * changes to `redundant`.
+ *
+ * @event workbox-window.Workbox#redundant
+ * @type {WorkboxEvent}
+ * @property {ServiceWorker} sw The service worker instance.
+ * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
+ *     event.
+ * @property {boolean|undefined} isUpdate True if a service worker was already
+ *     controlling when this `Workbox` instance called `register()`.
+ * @property {string} type `redundant`.
+ * @property {Workbox} target The `Workbox` instance.
+ */
Index: frontend/node_modules/workbox-window/src/_version.ts
===================================================================
--- frontend/node_modules/workbox-window/src/_version.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/src/_version.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2 @@
+// @ts-ignore
+try{self['workbox:window:6.6.0']&&_()}catch(e){}
Index: frontend/node_modules/workbox-window/src/index.ts
===================================================================
--- frontend/node_modules/workbox-window/src/index.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/src/index.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+/*
+  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.
+*/
+
+import {messageSW} from './messageSW.js';
+import {Workbox} from './Workbox.js';
+
+import './_version.js';
+
+/**
+ * @module workbox-window
+ */
+export {messageSW, Workbox};
+
+// See https://github.com/GoogleChrome/workbox/issues/2770
+export * from './utils/WorkboxEvent.js';
Index: frontend/node_modules/workbox-window/src/messageSW.ts
===================================================================
--- frontend/node_modules/workbox-window/src/messageSW.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/src/messageSW.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,37 @@
+/*
+  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.
+*/
+
+import './_version.js';
+
+/**
+ * Sends a data object to a service worker via `postMessage` and resolves with
+ * a response (if any).
+ *
+ * A response can be set in a message handler in the service worker by
+ * calling `event.ports[0].postMessage(...)`, which will resolve the promise
+ * returned by `messageSW()`. If no response is set, the promise will not
+ * resolve.
+ *
+ * @param {ServiceWorker} sw The service worker to send the message to.
+ * @param {Object} data An object to send to the service worker.
+ * @return {Promise<Object|undefined>}
+ * @memberof workbox-window
+ */
+// Better not change type of data.
+// eslint-disable-next-line @typescript-eslint/ban-types
+function messageSW(sw: ServiceWorker, data: {}): Promise<any> {
+  return new Promise((resolve) => {
+    const messageChannel = new MessageChannel();
+    messageChannel.port1.onmessage = (event: MessageEvent) => {
+      resolve(event.data);
+    };
+    sw.postMessage(data, [messageChannel.port2]);
+  });
+}
+
+export {messageSW};
Index: frontend/node_modules/workbox-window/src/utils/WorkboxEvent.ts
===================================================================
--- frontend/node_modules/workbox-window/src/utils/WorkboxEvent.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/src/utils/WorkboxEvent.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,59 @@
+/*
+  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.
+*/
+
+import {WorkboxEventTarget} from './WorkboxEventTarget.js';
+import '../_version.js';
+
+/**
+ * A minimal `Event` subclass shim.
+ * This doesn't *actually* subclass `Event` because not all browsers support
+ * constructable `EventTarget`, and using a real `Event` will error.
+ * @private
+ */
+export class WorkboxEvent<K extends keyof WorkboxEventMap> {
+  target?: WorkboxEventTarget;
+  sw?: ServiceWorker;
+  originalEvent?: Event;
+  isExternal?: boolean;
+
+  constructor(
+    public type: K,
+    props: Omit<WorkboxEventMap[K], 'target' | 'type'>,
+  ) {
+    Object.assign(this, props);
+  }
+}
+
+export interface WorkboxMessageEvent extends WorkboxEvent<'message'> {
+  data: any;
+  originalEvent: Event;
+  ports: readonly MessagePort[];
+}
+
+export interface WorkboxLifecycleEvent
+  extends WorkboxEvent<keyof WorkboxLifecycleEventMap> {
+  isUpdate?: boolean;
+}
+
+export interface WorkboxLifecycleWaitingEvent extends WorkboxLifecycleEvent {
+  wasWaitingBeforeRegister?: boolean;
+}
+
+export interface WorkboxLifecycleEventMap {
+  installing: WorkboxLifecycleEvent;
+  installed: WorkboxLifecycleEvent;
+  waiting: WorkboxLifecycleWaitingEvent;
+  activating: WorkboxLifecycleEvent;
+  activated: WorkboxLifecycleEvent;
+  controlling: WorkboxLifecycleEvent;
+  redundant: WorkboxLifecycleEvent;
+}
+
+export interface WorkboxEventMap extends WorkboxLifecycleEventMap {
+  message: WorkboxMessageEvent;
+}
Index: frontend/node_modules/workbox-window/src/utils/WorkboxEventTarget.ts
===================================================================
--- frontend/node_modules/workbox-window/src/utils/WorkboxEventTarget.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/src/utils/WorkboxEventTarget.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,77 @@
+/*
+  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.
+*/
+
+import {WorkboxEvent, WorkboxEventMap} from './WorkboxEvent.js';
+
+export type ListenerCallback = (event: WorkboxEvent<any>) => any;
+
+/**
+ * A minimal `EventTarget` shim.
+ * This is necessary because not all browsers support constructable
+ * `EventTarget`, so using a real `EventTarget` will error.
+ * @private
+ */
+export class WorkboxEventTarget {
+  private readonly _eventListenerRegistry: Map<
+    keyof WorkboxEventMap,
+    Set<ListenerCallback>
+  > = new Map();
+
+  /**
+   * @param {string} type
+   * @param {Function} listener
+   * @private
+   */
+  addEventListener<K extends keyof WorkboxEventMap>(
+    type: K,
+    listener: (event: WorkboxEventMap[K]) => any,
+  ): void {
+    const foo = this._getEventListenersByType(type);
+    foo.add(listener as ListenerCallback);
+  }
+
+  /**
+   * @param {string} type
+   * @param {Function} listener
+   * @private
+   */
+  removeEventListener<K extends keyof WorkboxEventMap>(
+    type: K,
+    listener: (event: WorkboxEventMap[K]) => any,
+  ): void {
+    this._getEventListenersByType(type).delete(listener as ListenerCallback);
+  }
+
+  /**
+   * @param {Object} event
+   * @private
+   */
+  dispatchEvent(event: WorkboxEvent<any>): void {
+    event.target = this;
+
+    const listeners = this._getEventListenersByType(event.type);
+    for (const listener of listeners) {
+      listener(event);
+    }
+  }
+
+  /**
+   * Returns a Set of listeners associated with the passed event type.
+   * If no handlers have been registered, an empty Set is returned.
+   *
+   * @param {string} type The event type.
+   * @return {Set<ListenerCallback>} An array of handler functions.
+   * @private
+   */
+  private _getEventListenersByType(type: keyof WorkboxEventMap) {
+    if (!this._eventListenerRegistry.has(type)) {
+      this._eventListenerRegistry.set(type, new Set());
+    }
+    return this._eventListenerRegistry.get(type)!;
+  }
+}
Index: frontend/node_modules/workbox-window/src/utils/urlsMatch.ts
===================================================================
--- frontend/node_modules/workbox-window/src/utils/urlsMatch.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/src/utils/urlsMatch.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,23 @@
+/*
+  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.
+*/
+
+import '../_version.js';
+
+/**
+ * Returns true if two URLs have the same `.href` property. The URLS can be
+ * relative, and if they are the current location href is used to resolve URLs.
+ *
+ * @private
+ * @param {string} url1
+ * @param {string} url2
+ * @return {boolean}
+ */
+export function urlsMatch(url1: string, url2: string): boolean {
+  const {href} = location;
+  return new URL(url1, href).href === new URL(url2, href).href;
+}
Index: frontend/node_modules/workbox-window/tsconfig.json
===================================================================
--- frontend/node_modules/workbox-window/tsconfig.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/tsconfig.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,15 @@
+{
+  "extends": "../../tsconfig",
+  "compilerOptions": {
+    "lib": ["es2017", "dom"],
+    "outDir": "./",
+    "rootDir": "./src",
+    "tsBuildInfoFile": "./tsconfig.tsbuildinfo"
+  },
+  "include": ["src/**/*.ts"],
+  "references": [
+    {
+      "path": "../workbox-core/"
+    }
+  ]
+}
Index: frontend/node_modules/workbox-window/tsconfig.tsbuildinfo
===================================================================
--- frontend/node_modules/workbox-window/tsconfig.tsbuildinfo	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/tsconfig.tsbuildinfo	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+{"program":{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../infra/type-overrides.d.ts","../workbox-core/_version.d.ts","../workbox-core/_private/deferred.d.ts","../workbox-core/_private/dontwaitfor.d.ts","../workbox-core/_private/logger.d.ts","./node_modules/@types/trusted-types/lib/index.d.ts","./src/_version.ts","./src/messagesw.ts","./src/utils/workboxevent.ts","./src/utils/workboxeventtarget.ts","./src/utils/urlsmatch.ts","./src/workbox.ts","./src/index.ts","./node_modules/@types/trusted-types/index.d.ts","../../node_modules/@babel/types/lib/index.d.ts","../../node_modules/@types/babel__generator/index.d.ts","../../node_modules/@babel/parser/typings/babel-parser.d.ts","../../node_modules/@types/babel__template/index.d.ts","../../node_modules/@types/babel__traverse/index.d.ts","../../node_modules/@types/babel__core/index.d.ts","../../node_modules/@types/babel__preset-env/index.d.ts","../../node_modules/@types/common-tags/index.d.ts","../../node_modules/@types/eslint/helpers.d.ts","../../node_modules/@types/json-schema/index.d.ts","../../node_modules/@types/estree/index.d.ts","../../node_modules/@types/eslint/index.d.ts","../../node_modules/@types/eslint-scope/index.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/ts3.4/base.d.ts","../../node_modules/@types/node/globals.global.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/ts3.6/base.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/base.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/@types/fs-extra/index.d.ts","../../node_modules/@types/minimatch/index.d.ts","../../node_modules/@types/glob/index.d.ts","../../node_modules/@types/html-minifier-terser/index.d.ts","../../node_modules/@types/linkify-it/index.d.ts","../../node_modules/@types/lodash/common/common.d.ts","../../node_modules/@types/lodash/common/array.d.ts","../../node_modules/@types/lodash/common/collection.d.ts","../../node_modules/@types/lodash/common/date.d.ts","../../node_modules/@types/lodash/common/function.d.ts","../../node_modules/@types/lodash/common/lang.d.ts","../../node_modules/@types/lodash/common/math.d.ts","../../node_modules/@types/lodash/common/number.d.ts","../../node_modules/@types/lodash/common/object.d.ts","../../node_modules/@types/lodash/common/seq.d.ts","../../node_modules/@types/lodash/common/string.d.ts","../../node_modules/@types/lodash/common/util.d.ts","../../node_modules/@types/lodash/index.d.ts","../../node_modules/@types/mdurl/encode.d.ts","../../node_modules/@types/mdurl/decode.d.ts","../../node_modules/@types/mdurl/parse.d.ts","../../node_modules/@types/mdurl/format.d.ts","../../node_modules/@types/mdurl/index.d.ts","../../node_modules/@types/markdown-it/lib/common/utils.d.ts","../../node_modules/@types/markdown-it/lib/token.d.ts","../../node_modules/@types/markdown-it/lib/rules_inline/state_inline.d.ts","../../node_modules/@types/markdown-it/lib/helpers/parse_link_label.d.ts","../../node_modules/@types/markdown-it/lib/helpers/parse_link_destination.d.ts","../../node_modules/@types/markdown-it/lib/helpers/parse_link_title.d.ts","../../node_modules/@types/markdown-it/lib/helpers/index.d.ts","../../node_modules/@types/markdown-it/lib/ruler.d.ts","../../node_modules/@types/markdown-it/lib/rules_block/state_block.d.ts","../../node_modules/@types/markdown-it/lib/parser_block.d.ts","../../node_modules/@types/markdown-it/lib/rules_core/state_core.d.ts","../../node_modules/@types/markdown-it/lib/parser_core.d.ts","../../node_modules/@types/markdown-it/lib/parser_inline.d.ts","../../node_modules/@types/markdown-it/lib/renderer.d.ts","../../node_modules/@types/markdown-it/lib/index.d.ts","../../node_modules/@types/markdown-it/index.d.ts","../../node_modules/@types/minimist/index.d.ts","../../node_modules/@types/normalize-package-data/index.d.ts","../../node_modules/@types/parse-json/index.d.ts","../../node_modules/@types/resolve/index.d.ts","../../node_modules/@types/semver/classes/semver.d.ts","../../node_modules/@types/semver/functions/parse.d.ts","../../node_modules/@types/semver/functions/valid.d.ts","../../node_modules/@types/semver/functions/clean.d.ts","../../node_modules/@types/semver/functions/inc.d.ts","../../node_modules/@types/semver/functions/diff.d.ts","../../node_modules/@types/semver/functions/major.d.ts","../../node_modules/@types/semver/functions/minor.d.ts","../../node_modules/@types/semver/functions/patch.d.ts","../../node_modules/@types/semver/functions/prerelease.d.ts","../../node_modules/@types/semver/functions/compare.d.ts","../../node_modules/@types/semver/functions/rcompare.d.ts","../../node_modules/@types/semver/functions/compare-loose.d.ts","../../node_modules/@types/semver/functions/compare-build.d.ts","../../node_modules/@types/semver/functions/sort.d.ts","../../node_modules/@types/semver/functions/rsort.d.ts","../../node_modules/@types/semver/functions/gt.d.ts","../../node_modules/@types/semver/functions/lt.d.ts","../../node_modules/@types/semver/functions/eq.d.ts","../../node_modules/@types/semver/functions/neq.d.ts","../../node_modules/@types/semver/functions/gte.d.ts","../../node_modules/@types/semver/functions/lte.d.ts","../../node_modules/@types/semver/functions/cmp.d.ts","../../node_modules/@types/semver/functions/coerce.d.ts","../../node_modules/@types/semver/classes/comparator.d.ts","../../node_modules/@types/semver/classes/range.d.ts","../../node_modules/@types/semver/functions/satisfies.d.ts","../../node_modules/@types/semver/ranges/max-satisfying.d.ts","../../node_modules/@types/semver/ranges/min-satisfying.d.ts","../../node_modules/@types/semver/ranges/to-comparators.d.ts","../../node_modules/@types/semver/ranges/min-version.d.ts","../../node_modules/@types/semver/ranges/valid.d.ts","../../node_modules/@types/semver/ranges/outside.d.ts","../../node_modules/@types/semver/ranges/gtr.d.ts","../../node_modules/@types/semver/ranges/ltr.d.ts","../../node_modules/@types/semver/ranges/intersects.d.ts","../../node_modules/@types/semver/ranges/simplify.d.ts","../../node_modules/@types/semver/ranges/subset.d.ts","../../node_modules/@types/semver/internals/identifiers.d.ts","../../node_modules/@types/semver/index.d.ts","../../node_modules/@types/source-list-map/index.d.ts","../../node_modules/@types/stringify-object/index.d.ts","../../node_modules/@types/tapable/index.d.ts","../../node_modules/@types/uglify-js/node_modules/source-map/source-map.d.ts","../../node_modules/@types/uglify-js/index.d.ts","../../node_modules/@types/webpack-sources/node_modules/source-map/source-map.d.ts","../../node_modules/@types/webpack-sources/lib/source.d.ts","../../node_modules/@types/webpack-sources/lib/compatsource.d.ts","../../node_modules/@types/webpack-sources/lib/concatsource.d.ts","../../node_modules/@types/webpack-sources/lib/originalsource.d.ts","../../node_modules/@types/webpack-sources/lib/prefixsource.d.ts","../../node_modules/@types/webpack-sources/lib/rawsource.d.ts","../../node_modules/@types/webpack-sources/lib/replacesource.d.ts","../../node_modules/@types/webpack-sources/lib/sizeonlysource.d.ts","../../node_modules/@types/webpack-sources/lib/sourcemapsource.d.ts","../../node_modules/@types/webpack-sources/lib/index.d.ts","../../node_modules/@types/webpack-sources/lib/cachedsource.d.ts","../../node_modules/@types/webpack-sources/index.d.ts"],"fileInfos":[{"version":"8730f4bf322026ff5229336391a18bcaa1f94d4f82416c8b2f3954e2ccaae2ba","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06",{"version":"3aafcb693fe5b5c3bd277bd4c3a617b53db474fe498fc5df067c5603b1eebde7","affectsGlobalScope":true},{"version":"adb996790133eb33b33aadb9c09f15c2c575e71fb57a62de8bf74dbf59ec7dfb","affectsGlobalScope":true},{"version":"8cc8c5a3bac513368b0157f3d8b31cfdcfe78b56d3724f30f80ed9715e404af8","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398","affectsGlobalScope":true},{"version":"5f406584aef28a331c36523df688ca3650288d14f39c5d2e555c95f0d2ff8f6f","affectsGlobalScope":true},{"version":"22f230e544b35349cfb3bd9110b6ef37b41c6d6c43c3314a31bd0d9652fcec72","affectsGlobalScope":true},{"version":"7ea0b55f6b315cf9ac2ad622b0a7813315bb6e97bf4bb3fbf8f8affbca7dc695","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"eb26de841c52236d8222f87e9e6a235332e0788af8c87a71e9e210314300410a","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"81cac4cbc92c0c839c70f8ffb94eb61e2d32dc1c3cf6d95844ca099463cf37ea","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"09aa50414b80c023553090e2f53827f007a301bc34b0495bfb2c3c08ab9ad1eb","affectsGlobalScope":true},{"version":"2768ef564cfc0689a1b76106c421a2909bdff0acbe87da010785adab80efdd5c","affectsGlobalScope":true},{"version":"52d1bb7ab7a3306fd0375c8bff560feed26ed676a5b0457fa8027b563aecb9a4","affectsGlobalScope":true},{"version":"0396119f8b76a074eddc16de8dbc4231a448f2534f4c64c5ab7b71908eb6e646","affectsGlobalScope":true},"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","88fa7615e71089c0cab3b688aae073a6e9dae6f489ec1357da407c155d2e9d84","365f3bd8994af50572b562a002e0fa2e72e74f54ed996e2444ea3df562678f50",{"version":"d763b9ef68a16f3896187af5b51b5a959b479218cc65c2930bcb440cbbf10728","affectsGlobalScope":true},"2fcd2d22b1f30555e785105597cd8f57ed50300e213c4f1bbca6ae149f782c38",{"version":"d272efd56da42fb165cae8d084db44065fc350e1c8b360c4cafbcb308bb9dc6d","signature":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","affectsGlobalScope":true},{"version":"748fbd9cc071296ba928bf2611f6c47a04f15370907a51f20bf74dbb194018e5","signature":"759f43eb885b9cba0c0bbb706f70b9723c79db41df105b9404053242846851dd"},{"version":"f1cf4d050360461e021c3e28762afc82760c7f95b58930b757d68e775cd5d6ea","signature":"73a9260bf2aa47f7046f4df2560672284f9f451d500d81c12267aa85667dfeac"},{"version":"d2ac52ee1f774b75fe44fc4cbbfaa76074923c78edf5899684701bfc53faf7d8","signature":"60f19322d7e043b7bc55cefa04764ca3849a1bb2b7cf3c76eeafea8d0d21fcb0"},{"version":"2f8bf938d1327d80ae6e5b3345cb822821bbf5b3e92baef949142b29dad9bfcb","signature":"5bdd9132b5e1fde4442a53530751ff0778664918844b1ddbdfe0d05ebe7dc1c5"},{"version":"7828953854ab8c6c47a67c447fe2585dadfdd807e570471f2e0ca7d2629f08cd","signature":"4209522796417c3f3e426113ce3abbb829685eb5612ceb4d0c2a2bb701d9a4c3"},{"version":"40522cc72b5227d8ec2bb98648ddc095d978f2fcf45c52232c8c3209dca0c3a4","signature":"bf71a95d2678d0809906515a82fa9c345757863a025e6bcc59a05a1f76c2f5f5"},{"version":"bb4248c7f953233ac52332088fac897d62b82be07244e551d87c5049600b6cf7","affectsGlobalScope":true},"3eb8ad25895d53cc6229dc83decbc338d649ed6f3d5b537c9966293b056b1f57","b25c5f2970d06c729f464c0aeaa64b1a5b5f1355aa93554bb5f9c199b8624b1e","8678956904af215fe917b2df07b6c54f876fa64eb1f8a158e4ff38404cef3ff4","3051751533eee92572241b3cef28333212401408c4e7aa21718714b793c0f4ed","691aea9772797ca98334eb743e7686e29325b02c6931391bcee4cc7bf27a9f3b","6f1d39d26959517da3bd105c552eded4c34702705c64d75b03f54d864b6e41c2","5d1b955e6b1974fe5f47fbde474343113ab701ca30b80e463635a29e58d80944","3b93231babdb3ee9470a7e6103e48bf6585c4185f96941c08a77e097f8f469ae",{"version":"f345b0888d003fd69cb32bad3a0aa04c615ccafc572019e4bd86a52bd5e49e46","affectsGlobalScope":true},"0359682c54e487c4cab2b53b2b4d35cc8dea4d9914bc6abcdb5701f8b8e745a4","6a38e250306ceccbab257d11b846d5bd12491157d20901fa01afe4050c93c1b5","ffa048767a32a0f6354e611b15d8b53d882da1a9a35455c35c3f6811f2416d17","e050a0afcdbb269720a900c85076d18e0c1ab73e580202a2bf6964978181222a",{"version":"68aba9c37b535b42ce96b78a4cfa93813bf4525f86dceb88a6d726c5f7c6c14f","affectsGlobalScope":true},"c438b413e94ff76dfa20ae005f33a1c84f2480d1d66e0fd687501020d0de9b50","bc6a78961535181265845bf9b9e8a147ffd0ca275097ceb670a9b92afa825152","1fc4b0908c44f39b1f2e5a728d472670a0ea0970d2c6b5691c88167fe541ff82","123ec69e4b3a686eb49afd94ebe3292a5c84a867ecbcb6bb84bdd720a12af803",{"version":"51851805d06a6878796c3a00ccf0839fe18111a38d1bae84964c269f16bcc2b7","affectsGlobalScope":true},"90c85ddbb8de82cd19198bda062065fc51b7407c0f206f2e399e65a52e979720","c5ecc351d5eaa36dc682b4c398b57a9d37c108857b71a09464a06e0185831ac2","7ecfe97b43aa6c8b8f90caa599d5648bb559962e74e6f038f73a77320569dd78","7db7569fbb3e2b01ba8751c761cdd3f0debd104170d5665b7dc20a11630df3a9",{"version":"cde4d7f6274468180fa39847b183aec22626e8212ff885d535c53f4cd7c225fd","affectsGlobalScope":true},{"version":"072b0ac82ae8fe05b0d4f2eadb7f6edd0ebd84175ecad2f9e09261290a86bcee","affectsGlobalScope":true},"f6eedd1053167b8a651d8d9c70b1772e1b501264a36dfa881d7d4b30d623a9bc","fb28748ff8d015f52e99daee4f454e57cec1a22141f1257c317f3630a15edeb7","08fb2b0e1ef13a2df43f6d8e97019c36dfbc0475cf4d274c6838e2c9223fe39d","5d9394b829cfd504b2fe17287aaad8ce1dcfb2a2183c962a90a85b96da2c1c90","c969bf4c7cdfe4d5dd28aa09432f99d09ad1d8d8b839959646579521d0467d1a","6c3857edaeeaaf43812f527830ebeece9266b6e8eb5271ab6d2f0008306c9947","bc6a77e750f4d34584e46b1405b771fb69a224197dd6bafe5b0392a29a70b665","46cac76114704902baa535b30fb66a26aeaf9430f3b3ab44746e329f12e85498","ed4ae81196cccc10f297d228bca8d02e31058e6d723a3c5bc4be5fb3c61c6a34","84044697c8b3e08ef24e4b32cfe6440143d07e469a5e34bda0635276d32d9f35","6999f789ed86a40f3bc4d7e644e8d42ffda569465969df8077cd6c4e3505dd76",{"version":"0c9f2b308e5696d0802b613aff47c99f092add29408e654f7ab6026134250c18","affectsGlobalScope":true},"4a9008d79750801375605e6cfefa4e04643f20f2aaa58404c6aae1c894e9b049","884560fda6c3868f925f022adc3a1289fe6507bbb45adb10fa1bbcc73a941bb0","6b2bb67b0942bcfce93e1d6fad5f70afd54940a2b13df7f311201fba54b2cbe9","dd3706b25d06fe23c73d16079e8c66ac775831ef419da00716bf2aee530a04a4","1298327149e93a60c24a3b5db6048f7cc8fd4e3259e91d05fc44306a04b1b873","d67e08745494b000da9410c1ae2fdc9965fc6d593fe0f381a47491f75417d457","b40652bf8ce4a18133b31349086523b219724dca8df3448c1a0742528e7ad5b9","3181290a158e54a78c1a57c41791ec1cbdc860ae565916daa1bf4e425b7edac7","a77fdb357c78b70142b2fdbbfb72958d69e8f765fd2a3c69946c1018e89d4638","3c2ac350c3baa61fd2b1925844109e098f4376d0768a4643abc82754fd752748","826d48e49c905cedb906cbde6ccaf758827ff5867d4daa006b5a79e0fb489357","5ef157fbb39494a581bd24f21b60488fe248d452c479738b5e41b48720ea69b8","289be113bad7ee27ee7fa5b1e373c964c9789a5e9ed7db5ddcb631371120b953","a1136cf18dbe1b9b600c65538fd48609a1a4772d115a0c1d775839fe6544487c","24638ed25631a94a9b0d7b580b146329f82e158e8d1e90171a73d87bebf79255","638f49a0db5d30977533a8cfabf3e10ab30724360424698e8d5fd41ca272e070","d44028ae0127eb3e9fcfa5f55a8b81d64775ce15aca1020fe25c511bbb055834",{"version":"2708349d5a11a5c2e5f3a0765259ebe7ee00cdcc8161cb9990cb4910328442a1","affectsGlobalScope":true},"4e0a4d84b15692ea8669fe4f3d05a4f204567906b1347da7a58b75f45bae48d3","0f04bc8950ad634ac8ac70f704f200ef06f8852af9017f97c446de4def5b3546","d0c575d48d6dad75648017ff18762eb97f9398cc9486541b3070e79ce12719e6","d20072cb51d8baad944bedd935a25c7f10c29744e9a648d2c72c215337356077","35cbbc58882d2c158032d7f24ba8953d7e1caeb8cb98918d85819496109f55d2","8d01c38ccb9af3a4035a68818799e5ef32ccc8cf70bdb83e181e1921d7ad32f6","1d1e6bd176eee5970968423d7e215bfd66828b6db8d54d17afec05a831322633","393137c76bd922ba70a2f8bf1ade4f59a16171a02fb25918c168d48875b0cfb0","6767cce098e1e6369c26258b7a1f9e569c5467d501a47a090136d5ea6e80ae6d","6503fb6addf62f9b10f8564d9869ad824565a914ec1ac3dd7d13da14a3f57036","3594c022901a1c8993b0f78a3f534cfb81e7b619ed215348f7f6882f3db02abc","438284c7c455a29b9c0e2d1e72abc62ee93d9a163029ffe918a34c5db3b92da2","0c75b204aed9cf6ff1c7b4bed87a3ece0d9d6fc857a6350c0c95ed0c38c814e8","187119ff4f9553676a884e296089e131e8cc01691c546273b1d0089c3533ce42","c9f396e71966bd3a890d8a36a6a497dbf260e9b868158ea7824d4b5421210afe","509235563ea2b939e1bbe92aae17e71e6a82ceab8f568b45fb4fce7d72523a32","9364c7566b0be2f7b70ff5285eb34686f83ccb01bda529b82d23b2a844653bfb","00baffbe8a2f2e4875367479489b5d43b5fc1429ecb4a4cc98cfc3009095f52a","c311349ec71bb69399ffc4092853e7d8a86c1ca39ddb4cd129e775c19d985793","3c92b6dfd43cc1c2485d9eba5ff0b74a19bb8725b692773ef1d66dac48cda4bd","4908e4c00832b26ce77a629de8501b0e23a903c094f9e79a7fec313a15da796a","2630a7cbb597e85d713b7ef47f2946d4280d3d4c02733282770741d40672b1a5",{"version":"0714e2046df66c0e93c3330d30dbc0565b3e8cd3ee302cf99e4ede6220e5fec8","affectsGlobalScope":true},"f313731860257325f13351575f381fef333d4dfe30daf5a2e72f894208feea08","951b37f7d86f6012f09e6b35f1de57c69d75f16908cb0adaa56b93675ea0b853","3816fc03ffd9cbd1a7a3362a264756a4a1d547caabea50ca68303046be40e376","0c417b4ec46b88fb62a43ec00204700b560d01eb5677c7faa8ecd34610f096a8","13d29cdeb64e8496424edf42749bbb47de5e42d201cf958911a4638cbcffbd3f","0f9e381eecc5860f693c31fe463b3ca20a64ca9b8db0cf6208cd4a053f064809","95902d5561c6aac5dfc40568a12b0aca324037749dcd32a81f23423bfde69bab","5dfb2aca4136abdc5a2740f14be8134a6e6b66fd53470bb2e954e40f8abfaf3e","577463167dd69bd81f76697dfc3f7b22b77a6152f60a602a9218e52e3183ad67","b8396e9024d554b611cbe31a024b176ba7116063d19354b5a02dccd8f0118989","4b28e1c5bf88d891e07a1403358b81a51b3ba2eae1ffada51cca7476b5ac6407","7150ad575d28bf98fae321a1c0f10ad17b127927811f488ded6ff1d88d4244e5","8b155c4757d197969553de3762c8d23d5866710301de41e1b66b97c9ed867003","93733466609dd8bf72eace502a24ca7574bd073d934216e628f1b615c8d3cb3c","45e9228761aabcadb79c82fb3008523db334491525bdb8e74e0f26eaf7a4f7f4","aeacac2778c9821512b6b889da79ac31606a863610c8f28da1e483579627bf90","569fdb354062fc098a6a3ba93a029edf22d6fe480cf72b231b3c07832b2e7c97","bf9876e62fb7f4237deafab8c7444770ef6e82b4cad2d5dc768664ff340feeb2","6cf60e76d37faf0fbc2f80a873eab0fd545f6b1bf300e7f0823f956ddb3083e9","6adaa6103086f931e3eee20f0987e86e8879e9d13aa6bd6075ccfc58b9c5681c","ee0af0f2b8d3b4d0baf669f2ff6fcef4a8816a473c894cc7c905029f7505fed0","3602dfff3072caea42f23a9b63fb34a7b0c95a62b93ce2add5fe6b159447845e","c9ad058b2cc9ce6dc2ed92960d6d009e8c04bef46d3f5312283debca6869f613","2b8264b2fefd7367e0f20e2c04eed5d3038831fe00f5efbc110ff0131aab899b","8a19491eba2108d5c333c249699f40aff05ad312c04a17504573b27d91f0aede","2b93035328f7778d200252681c1d86285d501ed424825a18f81e4c3028aa51d9","2ac9c8332c5f8510b8bdd571f8271e0f39b0577714d5e95c1e79a12b2616f069","42c21aa963e7b86fa00801d96e88b36803188018d5ad91db2a9101bccd40b3ff","d31eb848cdebb4c55b4893b335a7c0cca95ad66dee13cbb7d0893810c0a9c301","77c1d91a129ba60b8c405f9f539e42df834afb174fe0785f89d92a2c7c16b77a","7a9e0a564fee396cacf706523b5aeed96e04c6b871a8bebefad78499fbffc5bc","906c751ef5822ec0dadcea2f0e9db64a33fb4ee926cc9f7efa38afe5d5371b2a","5387c049e9702f2d2d7ece1a74836a14b47fbebe9bbeb19f94c580a37c855351","c68391fb9efad5d99ff332c65b1606248c4e4a9f1dd9a087204242b56c7126d6","e9cf02252d3a0ced987d24845dcb1f11c1be5541f17e5daa44c6de2d18138d0c","e8b02b879754d85f48489294f99147aeccc352c760d95a6fe2b6e49cd400b2fe","9f6908ab3d8a86c68b86e38578afc7095114e66b2fc36a2a96e9252aac3998e0","0eedb2344442b143ddcd788f87096961cd8572b64f10b4afc3356aa0460171c6","71405cc70f183d029cc5018375f6c35117ffdaf11846c35ebf85ee3956b1b2a6","c68baff4d8ba346130e9753cefe2e487a16731bf17e05fdacc81e8c9a26aae9d","2cd15528d8bb5d0453aa339b4b52e0696e8b07e790c153831c642c3dea5ac8af","479d622e66283ffa9883fbc33e441f7fc928b2277ff30aacbec7b7761b4e9579","ade307876dc5ca267ca308d09e737b611505e015c535863f22420a11fffc1c54","f8cdefa3e0dee639eccbe9794b46f90291e5fd3989fcba60d2f08fde56179fb9","86c5a62f99aac7053976e317dbe9acb2eaf903aaf3d2e5bb1cafe5c2df7b37a8","2b300954ce01a8343866f737656e13243e86e5baef51bd0631b21dcef1f6e954","a2d409a9ffd872d6b9d78ead00baa116bbc73cfa959fce9a2f29d3227876b2a1","b288936f560cd71f4a6002953290de9ff8dfbfbf37f5a9391be5c83322324898","61178a781ef82e0ff54f9430397e71e8f365fc1e3725e0e5346f2de7b0d50dfa","6a6ccb37feb3aad32d9be026a3337db195979cd5727a616fc0f557e974101a54","c649ea79205c029a02272ef55b7ab14ada0903db26144d2205021f24727ac7a3","38e2b02897c6357bbcff729ef84c736727b45cc152abe95a7567caccdfad2a1d","d6610ea7e0b1a7686dba062a1e5544dd7d34140f4545305b7c6afaebfb348341","3dee35db743bdba2c8d19aece7ac049bde6fa587e195d86547c882784e6ba34c","b15e55c5fa977c2f25ca0b1db52cfa2d1fd4bf0baf90a8b90d4a7678ca462ff1","f41d30972724714763a2698ae949fbc463afb203b5fa7c4ad7e4de0871129a17","843dd7b6a7c6269fd43827303f5cbe65c1fecabc30b4670a50d5a15d57daeeb9","f06d8b8567ee9fd799bf7f806efe93b67683ef24f4dea5b23ef12edff4434d9d","6017384f697ff38bc3ef6a546df5b230c3c31329db84cbfe686c83bec011e2b2","e1a5b30d9248549ca0c0bb1d653bafae20c64c4aa5928cc4cd3017b55c2177b0","a593632d5878f17295bd53e1c77f27bf4c15212822f764a2bfc1702f4b413fa0","a868a534ba1c2ca9060b8a13b0ffbbbf78b4be7b0ff80d8c75b02773f7192c29","da7545aba8f54a50fde23e2ede00158dc8112560d934cee58098dfb03aae9b9d","34baf65cfee92f110d6653322e2120c2d368ee64b3c7981dff08ed105c4f19b0","6aee496bf0ecfbf6731aa8cca32f4b6e92cdc0a444911a7d88410408a45ecc5d","67fc055eb86a0632e2e072838f889ffe1754083cb13c8c80a06a7d895d877aae","67d3e19b3b6e2c082ffd11ae5064c7a81b13d151326953b90fc26103067a1945","d558a0fe921ebcc88d3212c2c42108abf9f0d694d67ebdeba37d7728c044f579","2887592574fcdfd087647c539dcb0fbe5af2521270dad4a37f9d17c16190d579","9d74c7330800b325bb19cc8c1a153a612c080a60094e1ab6cfb6e39cf1b88c36","b90c59ac4682368a01c83881b814738eb151de8a58f52eb7edadea2bcffb11b9","8560a87b2e9f8e2c3808c8f6172c9b7eb6c9b08cb9f937db71c285ecf292c81d","ffe3931ff864f28d80ae2f33bd11123ad3d7bad9896b910a1e61504cc093e1f5","083c1bd82f8dc3a1ed6fc9e8eaddf141f7c05df418eca386598821e045253af9","274ebe605bd7f71ce161f9f5328febc7d547a2929f803f04b44ec4a7d8729517","6ca0207e70d985a24396583f55836b10dc181063ab6069733561bfde404d1bad","5908142efeaab38ffdf43927ee0af681ae77e0d7672b956dfb8b6c705dbfe106","f772b188b943549b5c5eb803133314b8aa7689eced80eed0b70e2f30ca07ab9c","0026b816ef05cfbf290e8585820eef0f13250438669107dfc44482bac007b14f","05d64cc1118031b29786632a9a0f6d7cf1dcacb303f27023a466cf3cdc860538","e0fff9119e1a5d2fdd46345734126cd6cb99c2d98a9debf0257047fe3937cc3f","d84398556ba4595ee6be554671da142cfe964cbdebb2f0c517a10f76f2b016c0","e275297155ec3251200abbb334c7f5641fecc68b2a9573e40eed50dff7584762"],"options":{"composite":true,"declaration":true,"module":99,"noFallthroughCasesInSwitch":true,"noImplicitReturns":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./","preserveConstEnums":true,"rootDir":"./src","strict":true,"target":4,"tsBuildInfoFile":"./tsconfig.tsbuildinfo"},"fileIdsList":[[44],[44,45,46,47,48],[44,46],[54,55],[52,53,54],[69,103],[68,103,105],[109,111,112,113,114,115,116,117,118,119,120,121],[109,110,112,113,114,115,116,117,118,119,120,121],[110,111,112,113,114,115,116,117,118,119,120,121],[109,110,111,113,114,115,116,117,118,119,120,121],[109,110,111,112,114,115,116,117,118,119,120,121],[109,110,111,112,113,115,116,117,118,119,120,121],[109,110,111,112,113,114,116,117,118,119,120,121],[109,110,111,112,113,114,115,117,118,119,120,121],[109,110,111,112,113,114,115,116,118,119,120,121],[109,110,111,112,113,114,115,116,117,119,120,121],[109,110,111,112,113,114,115,116,117,118,120,121],[109,110,111,112,113,114,115,116,117,118,119,121],[109,110,111,112,113,114,115,116,117,118,119,120],[141],[126],[130,131,132],[129],[131],[108,127,128,133,136,138,139,140],[128,134,135,141],[134,137],[128,129,134,141],[128,141],[122,123,124,125],[100,101],[68,69,76,85],[60,68,76],[92],[64,69,77],[85],[66,68,76],[68],[68,70,85,91],[69],[76,85,91],[68,69,71,76,85,88,91],[68,71,88,91],[102],[91],[66,68,85],[58],[90],[68,85],[83,92,94],[64,66,76,85],[57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96],[97,98,99],[76],[82],[68,70,85,91,94],[103],[147,186],[147,171,186],[186],[147],[147,172,186],[147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185],[172,186],[190],[103,193,194,195,196,197,198,199,200,201,202,203],[192,193,202],[193,202],[187,192,193,202],[192,193,194,195,196,197,198,199,200,201,203],[193],[64,192,202],[35],[37,38,41],[39],[38],[32,33,34,35,37,38,39,40],[35,39]],"referencedMap":[[46,1],[49,2],[45,1],[47,3],[48,1],[56,4],[55,5],[104,6],[106,7],[110,8],[111,9],[109,10],[112,11],[113,12],[114,13],[115,14],[116,15],[117,16],[118,17],[119,18],[120,19],[121,20],[142,21],[127,22],[133,23],[130,24],[132,25],[141,26],[136,27],[138,28],[139,29],[140,30],[135,30],[137,30],[129,30],[125,22],[126,31],[124,22],[102,32],[60,33],[61,34],[62,35],[63,36],[64,37],[65,38],[67,39],[69,40],[70,41],[71,42],[72,43],[73,44],[103,45],[74,39],[75,46],[76,47],[79,48],[80,49],[83,50],[84,51],[85,39],[88,52],[97,53],[100,54],[90,55],[91,56],[93,37],[95,57],[96,37],[146,58],[171,59],[172,60],[147,61],[150,61],[169,59],[170,59],[160,59],[159,62],[157,59],[152,59],[165,59],[163,59],[167,59],[151,59],[164,59],[168,59],[153,59],[154,59],[166,59],[148,59],[155,59],[156,59],[158,59],[162,59],[173,63],[161,59],[149,59],[186,64],[180,63],[182,65],[181,63],[174,63],[175,63],[177,63],[179,63],[183,65],[184,65],[176,65],[178,65],[191,66],[204,67],[203,68],[194,69],[195,70],[202,71],[196,70],[197,69],[198,69],[199,69],[200,72],[193,73],[201,68],[43,74],[42,75],[38,76],[39,77],[41,78]],"exportedModulesMap":[[46,1],[49,2],[45,1],[47,3],[48,1],[56,4],[55,5],[104,6],[106,7],[110,8],[111,9],[109,10],[112,11],[113,12],[114,13],[115,14],[116,15],[117,16],[118,17],[119,18],[120,19],[121,20],[142,21],[127,22],[133,23],[130,24],[132,25],[141,26],[136,27],[138,28],[139,29],[140,30],[135,30],[137,30],[129,30],[125,22],[126,31],[124,22],[102,32],[60,33],[61,34],[62,35],[63,36],[64,37],[65,38],[67,39],[69,40],[70,41],[71,42],[72,43],[73,44],[103,45],[74,39],[75,46],[76,47],[79,48],[80,49],[83,50],[84,51],[85,39],[88,52],[97,53],[100,54],[90,55],[91,56],[93,37],[95,57],[96,37],[146,58],[171,59],[172,60],[147,61],[150,61],[169,59],[170,59],[160,59],[159,62],[157,59],[152,59],[165,59],[163,59],[167,59],[151,59],[164,59],[168,59],[153,59],[154,59],[166,59],[148,59],[155,59],[156,59],[158,59],[162,59],[173,63],[161,59],[149,59],[186,64],[180,63],[182,65],[181,63],[174,63],[175,63],[177,63],[179,63],[183,65],[184,65],[176,65],[178,65],[191,66],[204,67],[203,68],[194,69],[195,70],[202,71],[196,70],[197,69],[198,69],[199,69],[200,72],[193,73],[201,68],[43,74],[42,75],[38,76],[39,77],[41,79]],"semanticDiagnosticsPerFile":[30,46,44,49,45,50,47,48,51,56,52,55,54,104,106,107,53,108,110,111,109,112,113,114,115,116,117,118,119,120,121,142,127,133,131,130,132,141,136,138,139,140,134,135,137,129,128,123,122,125,126,124,105,143,101,58,102,59,60,61,62,63,64,65,66,67,68,69,70,57,98,71,72,73,103,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,97,100,90,91,92,93,94,99,95,96,144,145,146,171,172,147,150,169,170,160,159,157,152,165,163,167,151,164,168,153,154,166,148,155,156,158,162,173,161,149,186,185,180,182,181,174,175,177,179,183,184,176,178,187,188,189,191,190,204,203,194,195,202,196,197,198,199,200,193,201,192,6,8,7,2,9,10,11,12,13,14,15,16,3,4,20,17,18,19,21,22,23,5,24,25,26,27,28,1,29,32,33,34,31,43,35,36,42,37,40,38,39,41],"latestChangedDtsFile":"./index.d.ts"},"version":"4.9.5"}
Index: frontend/node_modules/workbox-window/utils/WorkboxEvent.d.ts
===================================================================
--- frontend/node_modules/workbox-window/utils/WorkboxEvent.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/utils/WorkboxEvent.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+import { WorkboxEventTarget } from './WorkboxEventTarget.js';
+import '../_version.js';
+/**
+ * A minimal `Event` subclass shim.
+ * This doesn't *actually* subclass `Event` because not all browsers support
+ * constructable `EventTarget`, and using a real `Event` will error.
+ * @private
+ */
+export declare class WorkboxEvent<K extends keyof WorkboxEventMap> {
+    type: K;
+    target?: WorkboxEventTarget;
+    sw?: ServiceWorker;
+    originalEvent?: Event;
+    isExternal?: boolean;
+    constructor(type: K, props: Omit<WorkboxEventMap[K], 'target' | 'type'>);
+}
+export interface WorkboxMessageEvent extends WorkboxEvent<'message'> {
+    data: any;
+    originalEvent: Event;
+    ports: readonly MessagePort[];
+}
+export interface WorkboxLifecycleEvent extends WorkboxEvent<keyof WorkboxLifecycleEventMap> {
+    isUpdate?: boolean;
+}
+export interface WorkboxLifecycleWaitingEvent extends WorkboxLifecycleEvent {
+    wasWaitingBeforeRegister?: boolean;
+}
+export interface WorkboxLifecycleEventMap {
+    installing: WorkboxLifecycleEvent;
+    installed: WorkboxLifecycleEvent;
+    waiting: WorkboxLifecycleWaitingEvent;
+    activating: WorkboxLifecycleEvent;
+    activated: WorkboxLifecycleEvent;
+    controlling: WorkboxLifecycleEvent;
+    redundant: WorkboxLifecycleEvent;
+}
+export interface WorkboxEventMap extends WorkboxLifecycleEventMap {
+    message: WorkboxMessageEvent;
+}
Index: frontend/node_modules/workbox-window/utils/WorkboxEvent.js
===================================================================
--- frontend/node_modules/workbox-window/utils/WorkboxEvent.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/utils/WorkboxEvent.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+/*
+  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.
+*/
+import '../_version.js';
+/**
+ * A minimal `Event` subclass shim.
+ * This doesn't *actually* subclass `Event` because not all browsers support
+ * constructable `EventTarget`, and using a real `Event` will error.
+ * @private
+ */
+export class WorkboxEvent {
+    constructor(type, props) {
+        this.type = type;
+        Object.assign(this, props);
+    }
+}
Index: frontend/node_modules/workbox-window/utils/WorkboxEvent.mjs
===================================================================
--- frontend/node_modules/workbox-window/utils/WorkboxEvent.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/utils/WorkboxEvent.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export * from './WorkboxEvent.js';
Index: frontend/node_modules/workbox-window/utils/WorkboxEventTarget.d.ts
===================================================================
--- frontend/node_modules/workbox-window/utils/WorkboxEventTarget.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/utils/WorkboxEventTarget.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,37 @@
+import { WorkboxEvent, WorkboxEventMap } from './WorkboxEvent.js';
+export type ListenerCallback = (event: WorkboxEvent<any>) => any;
+/**
+ * A minimal `EventTarget` shim.
+ * This is necessary because not all browsers support constructable
+ * `EventTarget`, so using a real `EventTarget` will error.
+ * @private
+ */
+export declare class WorkboxEventTarget {
+    private readonly _eventListenerRegistry;
+    /**
+     * @param {string} type
+     * @param {Function} listener
+     * @private
+     */
+    addEventListener<K extends keyof WorkboxEventMap>(type: K, listener: (event: WorkboxEventMap[K]) => any): void;
+    /**
+     * @param {string} type
+     * @param {Function} listener
+     * @private
+     */
+    removeEventListener<K extends keyof WorkboxEventMap>(type: K, listener: (event: WorkboxEventMap[K]) => any): void;
+    /**
+     * @param {Object} event
+     * @private
+     */
+    dispatchEvent(event: WorkboxEvent<any>): void;
+    /**
+     * Returns a Set of listeners associated with the passed event type.
+     * If no handlers have been registered, an empty Set is returned.
+     *
+     * @param {string} type The event type.
+     * @return {Set<ListenerCallback>} An array of handler functions.
+     * @private
+     */
+    private _getEventListenersByType;
+}
Index: frontend/node_modules/workbox-window/utils/WorkboxEventTarget.js
===================================================================
--- frontend/node_modules/workbox-window/utils/WorkboxEventTarget.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/utils/WorkboxEventTarget.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,60 @@
+/*
+  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 minimal `EventTarget` shim.
+ * This is necessary because not all browsers support constructable
+ * `EventTarget`, so using a real `EventTarget` will error.
+ * @private
+ */
+export class WorkboxEventTarget {
+    constructor() {
+        this._eventListenerRegistry = new Map();
+    }
+    /**
+     * @param {string} type
+     * @param {Function} listener
+     * @private
+     */
+    addEventListener(type, listener) {
+        const foo = this._getEventListenersByType(type);
+        foo.add(listener);
+    }
+    /**
+     * @param {string} type
+     * @param {Function} listener
+     * @private
+     */
+    removeEventListener(type, listener) {
+        this._getEventListenersByType(type).delete(listener);
+    }
+    /**
+     * @param {Object} event
+     * @private
+     */
+    dispatchEvent(event) {
+        event.target = this;
+        const listeners = this._getEventListenersByType(event.type);
+        for (const listener of listeners) {
+            listener(event);
+        }
+    }
+    /**
+     * Returns a Set of listeners associated with the passed event type.
+     * If no handlers have been registered, an empty Set is returned.
+     *
+     * @param {string} type The event type.
+     * @return {Set<ListenerCallback>} An array of handler functions.
+     * @private
+     */
+    _getEventListenersByType(type) {
+        if (!this._eventListenerRegistry.has(type)) {
+            this._eventListenerRegistry.set(type, new Set());
+        }
+        return this._eventListenerRegistry.get(type);
+    }
+}
Index: frontend/node_modules/workbox-window/utils/WorkboxEventTarget.mjs
===================================================================
--- frontend/node_modules/workbox-window/utils/WorkboxEventTarget.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/utils/WorkboxEventTarget.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export * from './WorkboxEventTarget.js';
Index: frontend/node_modules/workbox-window/utils/urlsMatch.d.ts
===================================================================
--- frontend/node_modules/workbox-window/utils/urlsMatch.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/utils/urlsMatch.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,11 @@
+import '../_version.js';
+/**
+ * Returns true if two URLs have the same `.href` property. The URLS can be
+ * relative, and if they are the current location href is used to resolve URLs.
+ *
+ * @private
+ * @param {string} url1
+ * @param {string} url2
+ * @return {boolean}
+ */
+export declare function urlsMatch(url1: string, url2: string): boolean;
Index: frontend/node_modules/workbox-window/utils/urlsMatch.js
===================================================================
--- frontend/node_modules/workbox-window/utils/urlsMatch.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/utils/urlsMatch.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+/*
+  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.
+*/
+import '../_version.js';
+/**
+ * Returns true if two URLs have the same `.href` property. The URLS can be
+ * relative, and if they are the current location href is used to resolve URLs.
+ *
+ * @private
+ * @param {string} url1
+ * @param {string} url2
+ * @return {boolean}
+ */
+export function urlsMatch(url1, url2) {
+    const { href } = location;
+    return new URL(url1, href).href === new URL(url2, href).href;
+}
Index: frontend/node_modules/workbox-window/utils/urlsMatch.mjs
===================================================================
--- frontend/node_modules/workbox-window/utils/urlsMatch.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/workbox-window/utils/urlsMatch.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export * from './urlsMatch.js';
