From 2facc8480de6ba36d67675eed6a0baf016013cf4 Mon Sep 17 00:00:00 2001 From: Paul Robert Lloyd Date: Sat, 23 Aug 2025 09:59:35 +0100 Subject: [PATCH 1/4] =?UTF-8?q?Don=E2=80=99t=20precompile=20unused=20asset?= =?UTF-8?q?s=20from=20GOV.UK=20Frontend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/application.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config/application.rb b/config/application.rb index 104aac8d24..8e80e6ede1 100644 --- a/config/application.rb +++ b/config/application.rb @@ -66,10 +66,6 @@ class Application < Rails::Application config.time_zone = "London" - config.assets.paths << Rails.root.join( - "node_modules/govuk-frontend/dist/govuk/assets" - ) - config.exceptions_app = routes config.active_model.i18n_customize_full_message = true From 4af63ca3e1a0d1d663bc82ff174d1e105a37e426 Mon Sep 17 00:00:00 2001 From: Paul Robert Lloyd Date: Sat, 23 Aug 2025 10:02:34 +0100 Subject: [PATCH 2/4] Exclude SCSS stylesheets from asset precompilation --- config/application.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/application.rb b/config/application.rb index 8e80e6ede1..c24b01ac49 100644 --- a/config/application.rb +++ b/config/application.rb @@ -66,6 +66,8 @@ class Application < Rails::Application config.time_zone = "London" + config.assets.excluded_paths = [Rails.root.join("app/assets/stylesheets")] + config.exceptions_app = routes config.active_model.i18n_customize_full_message = true From f018d92520ac0bd4cf92199820ed498de0d6526c Mon Sep 17 00:00:00 2001 From: Paul Robert Lloyd Date: Sat, 23 Aug 2025 10:27:42 +0100 Subject: [PATCH 3/4] Remove service worker This was intended for offline recording, but has been disabled prior to the pilot. --- Procfile.dev | 1 - app/javascript/application.js | 3 - app/javascript/serviceworker-companion.js | 20 - app/javascript/serviceworker/cache.spec.ts | 53 - app/javascript/serviceworker/cache.ts | 50 - app/javascript/serviceworker/child-route.js | 25 - .../serviceworker/child-route.spec.js | 45 - app/javascript/serviceworker/main.js | 70 - app/javascript/serviceworker/messages.js | 17 - app/javascript/serviceworker/messages.spec.js | 31 - app/javascript/serviceworker/network.spec.ts | 36 - app/javascript/serviceworker/network.ts | 15 - app/javascript/serviceworker/online-status.js | 43 - .../serviceworker/online-status.spec.js | 89 - app/javascript/serviceworker/record-route.js | 32 - .../serviceworker/record-route.spec.js | 45 - .../serviceworker/setup-offline-route.spec.ts | 76 - .../serviceworker/setup-offline-route.ts | 36 - .../serviceworker/simple-crypto.test.ts | 42 - app/javascript/serviceworker/simple-crypto.ts | 141 -- app/javascript/serviceworker/store.spec.ts | 101 - app/javascript/serviceworker/store.ts | 87 - lib/tasks/serviceworker.rake | 14 - package.json | 6 +- yarn.lock | 1878 +---------------- 25 files changed, 23 insertions(+), 2933 deletions(-) delete mode 100644 app/javascript/serviceworker-companion.js delete mode 100644 app/javascript/serviceworker/cache.spec.ts delete mode 100644 app/javascript/serviceworker/cache.ts delete mode 100644 app/javascript/serviceworker/child-route.js delete mode 100644 app/javascript/serviceworker/child-route.spec.js delete mode 100644 app/javascript/serviceworker/main.js delete mode 100644 app/javascript/serviceworker/messages.js delete mode 100644 app/javascript/serviceworker/messages.spec.js delete mode 100644 app/javascript/serviceworker/network.spec.ts delete mode 100644 app/javascript/serviceworker/network.ts delete mode 100644 app/javascript/serviceworker/online-status.js delete mode 100644 app/javascript/serviceworker/online-status.spec.js delete mode 100644 app/javascript/serviceworker/record-route.js delete mode 100644 app/javascript/serviceworker/record-route.spec.js delete mode 100644 app/javascript/serviceworker/setup-offline-route.spec.ts delete mode 100644 app/javascript/serviceworker/setup-offline-route.ts delete mode 100644 app/javascript/serviceworker/simple-crypto.test.ts delete mode 100644 app/javascript/serviceworker/simple-crypto.ts delete mode 100644 app/javascript/serviceworker/store.spec.ts delete mode 100644 app/javascript/serviceworker/store.ts delete mode 100644 lib/tasks/serviceworker.rake diff --git a/Procfile.dev b/Procfile.dev index e66e566bf8..849b447422 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -1,4 +1,3 @@ web: unset PORT && bin/rails server css: yarn build:css --watch js: yarn build --watch -sw: yarn build:serviceworker --watch diff --git a/app/javascript/application.js b/app/javascript/application.js index 844f4027cf..df69cf5e75 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1,7 +1,4 @@ import "@hotwired/turbo-rails"; -// import { initServiceWorker } from "./serviceworker-companion"; import "./controllers"; Turbo.session.drive = false; - -// initServiceWorker(); diff --git a/app/javascript/serviceworker-companion.js b/app/javascript/serviceworker-companion.js deleted file mode 100644 index 8d7a5f1a5e..0000000000 --- a/app/javascript/serviceworker-companion.js +++ /dev/null @@ -1,20 +0,0 @@ -import { Workbox } from "workbox-window"; - -export let wb; - -const keepServiceWorkerAlive = () => { - setInterval(() => { - wb.messageSW({ - type: "GET_CONNECTION_STATUS", - }); - }, 20 * 1000); -}; - -export function initServiceWorker() { - if ("serviceWorker" in navigator) { - wb = new Workbox("/sw.js"); - wb.register(); - - keepServiceWorkerAlive(); - } -} diff --git a/app/javascript/serviceworker/cache.spec.ts b/app/javascript/serviceworker/cache.spec.ts deleted file mode 100644 index 93be86ca53..0000000000 --- a/app/javascript/serviceworker/cache.spec.ts +++ /dev/null @@ -1,53 +0,0 @@ -require("jest-fetch-mock").enableMocks(); -import { init as initCache, addAll, match, put } from "./cache"; -import { add, getByUrl } from "./store"; - -jest.mock("./store"); -jest.mock("./simple-crypto"); - -beforeEach(async () => { - await initCache("test"); -}); - -describe("addAll", () => { - test("fetches and adds all the passed in requests", async () => { - const urls = ["https://example.com/test", "https://example.com/test2"]; - - await addAll(urls); - - expect(add).toHaveBeenCalledWith("cachedResponses", urls[0], new Blob()); - expect(add).toHaveBeenCalledWith("cachedResponses", urls[1], new Blob()); - }); -}); - -describe("match", () => { - test("matches a request with its response", async () => { - (getByUrl as jest.Mock).mockResolvedValueOnce({ - body: new Response("foo"), - }); - - const result = await match("test"); - - expect(result).toEqual(new Response(new Blob())); - }); - - test("returns undefined if no match", async () => { - (getByUrl as jest.Mock).mockResolvedValueOnce(undefined); - - const result = await match("test"); - - expect(result).toBeUndefined(); - }); -}); - -describe("put", () => { - test("caches to the store", async () => { - const url = "https://example.com/test"; - - const response = new Response(); - - await put(url, response); - - expect(add).toHaveBeenCalledWith("cachedResponses", url, new Blob()); - }); -}); diff --git a/app/javascript/serviceworker/cache.ts b/app/javascript/serviceworker/cache.ts deleted file mode 100644 index 09320d5563..0000000000 --- a/app/javascript/serviceworker/cache.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { SimpleCrypto } from "./simple-crypto"; -import { add, getByUrl } from "./store"; - -let secret: SimpleCrypto; - -const encryptBlob = async (blob: Blob): Promise => { - const encrypted = await secret.encrypt(await blob.text()); - return new Blob([encrypted], { type: blob.type }); -}; - -const decryptBlob = async (blob: Blob): Promise => { - const decrypted = await secret.decrypt(await blob.text()); - return new Blob([decrypted], { type: blob.type }); -}; - -const urlOf = (request: RequestInfo): string => new Request(request).url; - -export const init = async (passphrase: string) => { - secret = new SimpleCrypto(passphrase, "my-salt"); - await secret.init(); -}; - -export const addAll = async (requests: RequestInfo[]): Promise => { - const responses = await Promise.all( - requests.map((request) => fetch(request)), - ); - - await Promise.all( - requests.map((request, index) => put(urlOf(request), responses[index])), - ); -}; - -export const match = async ( - request: RequestInfo, -): Promise => { - const requestObject = await getByUrl("cachedResponses", urlOf(request)); - if (!requestObject) return undefined; - - const decryptedBlob = await decryptBlob(requestObject.body); - return new Response(decryptedBlob); -}; - -export const put = async ( - request: RequestInfo, - response: Response, -): Promise => { - const body = await response.clone().blob(); - const encryptedBlob = await encryptBlob(body); - return await add("cachedResponses", urlOf(request), encryptedBlob); -}; diff --git a/app/javascript/serviceworker/child-route.js b/app/javascript/serviceworker/child-route.js deleted file mode 100644 index bb30faf10a..0000000000 --- a/app/javascript/serviceworker/child-route.js +++ /dev/null @@ -1,25 +0,0 @@ -import { isOnline } from "./online-status"; -import { put, match } from "./cache"; - -const getCampaignIdFromURL = (url) => url.match("/sessions/(\\d+)/")[1]; - -const programmeShowTemplateURL = (programmeId) => - `/sessions/${programmeId}/vaccinations/show-template`; - -export const childRoute = new RegExp("/sessions/(\\d+)/vaccinations/(\\d+)$"); - -export const childRouteHandler = async ({ request }) => { - try { - if (!isOnline()) throw new NetworkError("Offline"); - - var response = await fetch(request); - put(request, response.clone()); - } catch (err) { - const programmeId = getCampaignIdFromURL(request.url); - const programmeUrl = programmeShowTemplateURL(programmeId); - - var response = await match(programmeUrl); - } - - return response; -}; diff --git a/app/javascript/serviceworker/child-route.spec.js b/app/javascript/serviceworker/child-route.spec.js deleted file mode 100644 index 2cf189723d..0000000000 --- a/app/javascript/serviceworker/child-route.spec.js +++ /dev/null @@ -1,45 +0,0 @@ -import { match } from "./cache"; -import { setOfflineMode } from "./online-status"; -import { childRoute, childRouteHandler } from "./child-route"; - -jest.mock("./cache"); - -describe("childRoute", () => { - test("matches correctly", () => { - expect(childRoute.exec("/sessions/1/vaccinations/2")) - .toMatchInlineSnapshot(` - [ - "/sessions/1/vaccinations/2", - "1", - "2", - ] - `); - }); -}); - -const url = "/sessions/1/vaccinations/2"; - -describe("childRouteHandler", () => { - test("returns response when fetch works", async () => { - const response = { clone: jest.fn() }; - global.fetch = jest.fn(() => Promise.resolve(response)); - - expect(await childRouteHandler({ request: { url } })).toBe(response); - }); - - test("returns cached response when fetch fails", async () => { - global.fetch = jest.fn(() => { - throw new NetworkError("I'm too lazy to connect, yawn"); - }); - match.mockResolvedValue("foo"); - - expect(await childRouteHandler({ request: { url } })).toBe("foo"); - }); - - test("returns cached response when offline", async () => { - setOfflineMode(); - match.mockResolvedValue("foo"); - - expect(await childRouteHandler({ request: { url } })).toBe("foo"); - }); -}); diff --git a/app/javascript/serviceworker/main.js b/app/javascript/serviceworker/main.js deleted file mode 100644 index ca60df0514..0000000000 --- a/app/javascript/serviceworker/main.js +++ /dev/null @@ -1,70 +0,0 @@ -import { registerRoute } from "workbox-routing"; - -import { cacheOnly, networkFirst } from "./network"; -import { isOnline, refreshOnlineStatus } from "./online-status"; -import { handler as messageHandler } from "./messages"; -import { childRoute, childRouteHandler } from "./child-route"; -import { recordRoute, recordRouteHandler } from "./record-route"; -import { - setupOfflineRoute, - setupOfflineRouteHandler, -} from "./setup-offline-route"; -import { getAll, destroy } from "./store"; - -const setDefaultHandler = () => { - self.addEventListener("fetch", (event) => { - event.respondWith( - isOnline ? networkFirst(event.request) : cacheOnly(event.request), - ); - }); -}; - -const flushRequest = async (request) => { - console.debug( - "[Service Worker refreshOnlineStatus] sending request:", - request, - ); - try { - const csrf = await fetch("/csrf"); - const { token } = await csrf.json(); - const response = await fetch(request.url, { - method: "PUT", - body: JSON.stringify(request.body), - redirect: "manual", - headers: { - "X-CSRF-Token": token, - }, - }); - - // Unfollowed redirects have a status code of 0 - const requestSuccessful = response.status === 0; - - if (requestSuccessful) { - destroy("delayedRequests", request.id); - } else { - console.debug( - "[Service Worker refreshOnlineStatus] error sending request:", - request, - response, - ); - } - } catch (err) { - console.debug( - "[Service Worker refreshOnlineStatus] error sending request:", - err, - ); - } -}; - -refreshOnlineStatus(async () => { - const requests = await getAll("delayedRequests"); - - await Promise.all(requests.map(flushRequest)); -}); - -self.addEventListener("message", messageHandler); -console.debug("[Service Worker] registering routes"); -registerRoute(childRoute, childRouteHandler); -registerRoute(recordRoute, recordRouteHandler, "POST"); -registerRoute(setupOfflineRoute, setupOfflineRouteHandler, "POST"); -setDefaultHandler(); diff --git a/app/javascript/serviceworker/messages.js b/app/javascript/serviceworker/messages.js deleted file mode 100644 index ac3938331b..0000000000 --- a/app/javascript/serviceworker/messages.js +++ /dev/null @@ -1,17 +0,0 @@ -import { isOnline, toggleOnlineStatus } from "./online-status"; - -const messageHandlers = { - TOGGLE_CONNECTION: (event) => { - event.ports[0].postMessage(toggleOnlineStatus()); - }, - - GET_CONNECTION_STATUS: (event) => { - event.ports[0].postMessage(isOnline()); - }, -}; - -export const handler = (event) => { - if (event.data && event.data.type) { - messageHandlers[event.data.type](event); - } -}; diff --git a/app/javascript/serviceworker/messages.spec.js b/app/javascript/serviceworker/messages.spec.js deleted file mode 100644 index 800cfd094e..0000000000 --- a/app/javascript/serviceworker/messages.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import { toggleOnlineStatus, isOnline } from "./online-status"; -import { handler } from "./messages"; - -jest.mock("./online-status"); -jest.mock("./cache"); - -const postMessage = jest.fn(); -const event = (type, payload) => ({ - data: { type, payload }, - ports: [{ postMessage }], -}); - -describe("messageHandler", () => { - describe("TOGGLE_CONNECTION", () => { - test("works", () => { - toggleOnlineStatus.mockReturnValue("toggled online status"); - handler(event("TOGGLE_CONNECTION")); - expect(toggleOnlineStatus).toHaveBeenCalled(); - expect(postMessage).toHaveBeenCalledWith("toggled online status"); - }); - }); - - describe("GET_CONNECTION_STATUS", () => { - test("works", () => { - isOnline.mockReturnValue("online status"); - handler(event("GET_CONNECTION_STATUS")); - expect(isOnline).toHaveBeenCalled(); - expect(postMessage).toHaveBeenCalledWith("online status"); - }); - }); -}); diff --git a/app/javascript/serviceworker/network.spec.ts b/app/javascript/serviceworker/network.spec.ts deleted file mode 100644 index c1507ad45a..0000000000 --- a/app/javascript/serviceworker/network.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -require("jest-fetch-mock").enableMocks(); -import { cacheOnly, networkFirst } from "./network"; -import { match } from "./cache"; - -jest.mock("./cache"); - -describe("cacheOnly", () => { - test("returns cached response if available", async () => { - (match as jest.Mock).mockReturnValueOnce("test"); - const request = new Request("https://example.com/test"); - const response = await cacheOnly(request); - - expect(match).toHaveBeenCalledWith(request); - expect(response).toEqual("test"); - }); -}); - -describe("networkFirst", () => { - test("returns network response if available", async () => { - const request = new Request("https://example.com/test"); - const response = await networkFirst(request); - - expect(response).toHaveProperty("status", 200); - }); - - test("returns cached response if network request fails", async () => { - (fetch as jest.Mock).mockRejectedValueOnce(new Error("test")); - (match as jest.Mock).mockReturnValueOnce("test"); - - const request = new Request("https://example.com/test"); - const response = await networkFirst(request); - - expect(match).toHaveBeenCalledWith(request); - expect(response).toEqual("test"); - }); -}); diff --git a/app/javascript/serviceworker/network.ts b/app/javascript/serviceworker/network.ts deleted file mode 100644 index 11a7d1291e..0000000000 --- a/app/javascript/serviceworker/network.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { match } from "./cache"; - -export const cacheOnly = async (request: Request): Promise => { - return await match(request); -}; - -export const networkFirst = async (request: Request): Promise => { - try { - var networkResponse = await fetch(request); - } catch (err) { - return cacheOnly(request); - } - - return networkResponse; -}; diff --git a/app/javascript/serviceworker/online-status.js b/app/javascript/serviceworker/online-status.js deleted file mode 100644 index caf53650c9..0000000000 --- a/app/javascript/serviceworker/online-status.js +++ /dev/null @@ -1,43 +0,0 @@ -const REFRESH_INTERVAL = 5 * 1000; - -let online = true; - -export const setOfflineMode = () => (online = false); - -export const setOnlineMode = () => (online = true); - -export const toggleOnlineStatus = () => { - return online ? setOfflineMode() : setOnlineMode(); -}; - -export const isOnline = () => online; - -const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); - -export const fetchWithTimeout = async (resource, options = {}) => { - const { timeout = 10000 } = options; - delete options.timeout; - - const controller = new AbortController(); - const abortTimerId = setTimeout(() => controller.abort(), timeout); - const response = await fetch(resource, { - ...options, - signal: controller.signal, - }); - clearTimeout(abortTimerId); - return response; -}; - -export const refreshOnlineStatus = async (cb) => { - await sleep(REFRESH_INTERVAL); - - try { - await fetchWithTimeout("/up"); - - await cb(); - } catch (err) { - // Offline, do nothing - } - - refreshOnlineStatus(cb); -}; diff --git a/app/javascript/serviceworker/online-status.spec.js b/app/javascript/serviceworker/online-status.spec.js deleted file mode 100644 index 6a74e38f85..0000000000 --- a/app/javascript/serviceworker/online-status.spec.js +++ /dev/null @@ -1,89 +0,0 @@ -require("jest-fetch-mock").enableMocks(); -import { - isOnline, - setOfflineMode, - setOnlineMode, - toggleOnlineStatus, - refreshOnlineStatus, - fetchWithTimeout, -} from "./online-status"; - -describe("isOnline", () => { - test("works", () => { - expect(isOnline()).toBe(true); - }); -}); - -describe("toggleOnlineStatus", () => { - test("works", () => { - toggleOnlineStatus(); - expect(isOnline()).toBe(false); - toggleOnlineStatus(); - expect(isOnline()).toBe(true); - }); -}); - -describe("setOfflineMode", () => { - test("works", () => { - setOfflineMode(); - expect(isOnline()).toBe(false); - }); -}); - -describe("setOnlineMode", () => { - test("works", () => { - setOfflineMode(); - setOnlineMode(); - expect(isOnline()).toBe(true); - }); -}); - -describe("fetchWithTimeout", () => { - test("works if request is shorter than timeout", async () => { - fetch.mockResponseOnce( - () => - new Promise((resolve) => setTimeout(() => resolve({ body: "ok" }), 1)), - ); - await expect(fetchWithTimeout("/")).resolves.not.toThrow(); - }); - - test("times out if request takes longer than timeout", async () => { - fetch.mockResponseOnce( - () => - new Promise((resolve) => setTimeout(() => resolve({ body: "ok" }), 2)), - ); - await expect(fetchWithTimeout("/", { timeout: 1 })).rejects.toThrow(); - }); -}); - -describe("refreshOnlineStatus", () => { - const cb = jest.fn(); - - const tick = async () => { - jest.advanceTimersToNextTimer(1); // Wait the sleep - await Promise.resolve(); // Resolve the fetchWithTimeout - await Promise.resolve(); // Resolve the fetch - await Promise.resolve(); // Resolve the cb - }; - - beforeAll(() => { - jest.useFakeTimers(); - }); - - test("works", async () => { - refreshOnlineStatus(cb); - - expect(cb).toHaveBeenCalledTimes(0); - - await tick(); - expect(cb).toHaveBeenCalledTimes(1); - - await tick(); - expect(cb).toHaveBeenCalledTimes(2); - - fetch.mockReject(new Error("Offline")); - - await tick(); - expect(cb).toHaveBeenCalledTimes(2); - }); -}); diff --git a/app/javascript/serviceworker/record-route.js b/app/javascript/serviceworker/record-route.js deleted file mode 100644 index 495a440b7f..0000000000 --- a/app/javascript/serviceworker/record-route.js +++ /dev/null @@ -1,32 +0,0 @@ -import { isOnline } from "./online-status"; -import { match } from "./cache"; -import { add } from "./store"; - -const getCampaignIdFromURL = (url) => url.match("/sessions/(\\d+)/")[1]; - -const recordTemplateURL = (programmeId) => - `/sessions/${programmeId}/vaccinations/record-template`; - -export const recordRoute = new RegExp( - "/sessions/(\\d+)/vaccinations/(\\d+)/record$", -); - -export const recordRouteHandler = async ({ request }) => { - const clonedRequest = request.clone(); - const data = Object.fromEntries(await request.formData()); - - try { - if (!isOnline()) throw new NetworkError("Offline"); - - var response = await fetch(clonedRequest, { method: "POST" }); - } catch (err) { - const programmeId = getCampaignIdFromURL(request.url); - const programmeUrl = recordTemplateURL(programmeId); - - add("delayedRequests", clonedRequest.url, data); - - var response = await match(programmeUrl); - } - - return response; -}; diff --git a/app/javascript/serviceworker/record-route.spec.js b/app/javascript/serviceworker/record-route.spec.js deleted file mode 100644 index b8e0815e61..0000000000 --- a/app/javascript/serviceworker/record-route.spec.js +++ /dev/null @@ -1,45 +0,0 @@ -require("jest-fetch-mock").enableMocks(); -import { match } from "./cache"; -import { setOfflineMode } from "./online-status"; -import { recordRoute, recordRouteHandler } from "./record-route"; - -jest.mock("./cache"); -jest.mock("./store"); - -const url = "/sessions/1/vaccinations/2/record"; -const request = new Request(url); -request.formData = () => Promise.resolve([["foo", "bar"]]); - -describe("recordRoute", () => { - test("matches correctly", () => { - expect(recordRoute.exec(url)).toMatchInlineSnapshot(` - [ - "/sessions/1/vaccinations/2/record", - "1", - "2", - ] - `); - }); -}); - -describe("recordRouteHandler", () => { - test("returns response when fetch works", async () => { - fetch.mockResolvedValue("foo"); - - expect(await recordRouteHandler({ request })).toBe("foo"); - }); - - test("saves request for later when fetch fails", async () => { - fetch.mockRejectedValue("I'm too lazy to connect, yawn"); - match.mockResolvedValue("foo"); - - expect(await recordRouteHandler({ request })).toBe("foo"); - }); - - test("saves request for later when offline", async () => { - setOfflineMode(); - match.mockResolvedValue("foo"); - - expect(await recordRouteHandler({ request })).toBe("foo"); - }); -}); diff --git a/app/javascript/serviceworker/setup-offline-route.spec.ts b/app/javascript/serviceworker/setup-offline-route.spec.ts deleted file mode 100644 index f4030bc58b..0000000000 --- a/app/javascript/serviceworker/setup-offline-route.spec.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { init as initCache, addAll } from "./cache"; -import { - setupOfflineRoute, - setupOfflineRouteHandler, -} from "./setup-offline-route"; - -jest.mock("./cache"); - -const url = "/sessions/1/setup-offline"; - -afterEach(() => { - jest.clearAllMocks(); -}); - -describe("setupOfflineRoute", () => { - test("matches correctly", () => { - expect(setupOfflineRoute.exec(url)).toMatchInlineSnapshot(` - [ - "/sessions/1/setup-offline", - "1", - ] - `); - }); -}); - -describe("setupOfflineRouteHandler", () => { - test("sets up offline working when fetch works", async () => { - const request = { - url, - clone: jest.fn(() => request), - formData: jest.fn(() => - Promise.resolve([ - ["offline_password[assets_css]", "/css"], - ["offline_password[assets_js]", "/js"], - ["offline_password[password]", "password"], - ]), - ), - }; - const response = { type: "opaqueredirect" }; - global.fetch = jest.fn(() => Promise.resolve(response)) as any; - - expect(await setupOfflineRouteHandler({ request })).toBe(response); - expect(initCache).toHaveBeenCalledWith("password"); - expect((addAll as any).mock.calls).toMatchInlineSnapshot(` - [ - [ - [ - "/css", - "/js", - "/favicon.ico", - "/start", - "/dashboard", - "/sessions/1", - "/sessions/1/vaccinations", - "/sessions/1/vaccinations.json", - "/sessions/1/vaccinations/record-template", - "/sessions/1/vaccinations/show-template", - ], - ], - ] - `); - }); - - test("does not set up offline working when fetch fails", async () => { - const request = { - url, - clone: jest.fn(() => request), - }; - const response = { type: "error" }; - global.fetch = jest.fn(() => Promise.resolve(response)) as any; - - expect(await setupOfflineRouteHandler({ request })).toBe(response); - expect(initCache).not.toHaveBeenCalled(); - expect(addAll).not.toHaveBeenCalled(); - }); -}); diff --git a/app/javascript/serviceworker/setup-offline-route.ts b/app/javascript/serviceworker/setup-offline-route.ts deleted file mode 100644 index 83821506ca..0000000000 --- a/app/javascript/serviceworker/setup-offline-route.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { init as initCache, addAll } from "./cache"; - -const getCampaignIdFromURL = (url: string) => url.match("/sessions/(\\d+)/")[1]; - -export const setupOfflineRoute = new RegExp("/sessions/(\\d+)/setup-offline$"); - -export const setupOfflineRouteHandler = async ({ request }) => { - const clonedRequest = request.clone(); - const response = await fetch(request, { method: "POST" }); - const success = response.type === "opaqueredirect"; - - if (success) { - const formData = Object.fromEntries(await clonedRequest.formData()); - const css = formData["offline_password[assets_css]"]; - const js = formData["offline_password[assets_js]"]; - const password = formData["offline_password[password]"]; - - await initCache(password); - - const programmeId = getCampaignIdFromURL(request.url); - await addAll([ - css, - js, - `/favicon.ico`, - `/start`, - `/dashboard`, - `/sessions/${programmeId}`, - `/sessions/${programmeId}/vaccinations`, - `/sessions/${programmeId}/vaccinations.json`, - `/sessions/${programmeId}/vaccinations/record-template`, - `/sessions/${programmeId}/vaccinations/show-template`, - ]); - } - - return response; -}; diff --git a/app/javascript/serviceworker/simple-crypto.test.ts b/app/javascript/serviceworker/simple-crypto.test.ts deleted file mode 100644 index 2a6456a4ff..0000000000 --- a/app/javascript/serviceworker/simple-crypto.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -import crypto from "crypto"; -import { SimpleCrypto } from "./simple-crypto"; - -// Stub out TextEncoder, TextDecoder, and crypto.subtle for Jest. -// These are available in the browser, but not in Node. -global.TextEncoder = require("util").TextEncoder; -global.TextDecoder = require("util").TextDecoder; -Object.defineProperty(global.self, "crypto", { - value: { - getRandomValues: (arr: any) => crypto.randomBytes(arr.length), - subtle: crypto.webcrypto.subtle, - }, -}); - -describe("SimpleCrypto", () => { - const passphrase = "my-passphrase"; - const salt = "my-salt"; - const payload = "Hello, world! 🌎"; - let secret: SimpleCrypto; - - beforeEach(async () => { - secret = new SimpleCrypto(passphrase, salt); - await secret.init(); - }); - - test("encrypts and decrypts a payload correctly", async () => { - const encrypted = await secret.encrypt(payload); - expect(encrypted).not.toEqual(payload); - - const decrypted = await secret.decrypt(encrypted); - expect(decrypted).toEqual(payload); - }); - - test("works with a large payload", async () => { - const largePayload = new Array(500000).fill("x").join(""); - const encrypted = await secret.encrypt(largePayload); - expect(encrypted).not.toEqual(largePayload); - - const decrypted = await secret.decrypt(encrypted); - expect(decrypted).toEqual(largePayload); - }); -}); diff --git a/app/javascript/serviceworker/simple-crypto.ts b/app/javascript/serviceworker/simple-crypto.ts deleted file mode 100644 index 4be558bd8c..0000000000 --- a/app/javascript/serviceworker/simple-crypto.ts +++ /dev/null @@ -1,141 +0,0 @@ -// This converts a buffer to a base64 string using the FileReader API. -// This appears to be the fastest method. -// See https://stackoverflow.com/a/9458996/2490003 -const bufferToBase64 = (buffer: ArrayBuffer): Promise => { - const blob = new Blob([buffer], { type: "application/octet-binary" }); - const reader = new FileReader(); - - return new Promise((resolve, reject) => { - reader.onloadend = () => { - resolve((reader.result as string).split(",")[1]); - }; - reader.onerror = reject; - reader.readAsDataURL(blob); - }); -}; - -const base64ToBuffer = (base64: string): Uint8Array => { - const binaryString = self.atob(base64); - const len = binaryString.length; - const bytes = new Uint8Array(len); - for (let i = 0; i < len; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - return bytes; -}; - -/** - * This is an encryption class that uses the Web Crypto API to encrypt and decrypt a string using a passphrase and a salt. - * - * Usage: - * const secret = new SimpleCrypto("my-passphrase", "my-salt"); - * await secret.init(); - * const encrypted = await secret.encrypt("hello world"); - * const decrypted = await secret.decrypt(encrypted); - */ -export class SimpleCrypto { - private passphrase: string; - private salt: string; - private key?: CryptoKey; - - /** - * @param passphrase The passphrase to use. This can be provided by the user and should be stored securely. - * @param salt A preferably random string that is used to salt the passphrase, to ensure that ciphertexts of the same data with the same passphrase are different. - * @returns A new SimpleCrypto instance. - */ - constructor(passphrase: string, salt: string) { - this.passphrase = passphrase; - this.salt = salt; - } - - /** - * Parses the passphrase and salt into a determinstic CryptoKey that can be used for encryption and decryption. - * - * @returns A Promise that resolves when the key is ready. - * */ - public async init(): Promise { - const encoder = new TextEncoder(); - - // First, import an initial key from the passphrase. On its own, this key - // is not secure, as it could be brute forced, so we can't directly use it - // to encrypt and decrypt data. - const initialKey = await crypto.subtle.importKey( - "raw", - encoder.encode(this.passphrase), - { name: "PBKDF2" }, - false, - ["deriveBits", "deriveKey"], - ); - - // Derive a new key from the initial key. Using salt makes it unique per - // user, and using lots of iterations makes it computationally expensive to - // brute force. - this.key = await crypto.subtle.deriveKey( - { - name: "PBKDF2", - salt: encoder.encode(this.salt), - iterations: 100000, - hash: "SHA-256", - }, - initialKey, - { name: "AES-GCM", length: 256 }, - false, - ["encrypt", "decrypt"], - ); - } - - /** - * Encrypts the provided plaintext string. - * - * @param plaintext The plaintext string to encrypt. - * @returns A base64-encoded string containing the initialization vector and the ciphertext. - */ - public async encrypt(plaintext: string): Promise { - const encoder = new TextEncoder(); - - // Each AES-GCM encryption requires a unique initialization vector, or - // iv. The iv should be 12 bytes long and is safe to store in plaintext - // alongside the ciphertext. - const iv = crypto.getRandomValues(new Uint8Array(12)); - - const ciphertext: ArrayBuffer = await crypto.subtle.encrypt( - { - name: "AES-GCM", - iv, - }, - this.key, - encoder.encode(plaintext), - ); - - // Prepend the iv to the ciphertext, so that it can be retrieved later, - // then base64-encode the result. - return await bufferToBase64( - new Uint8Array([...iv, ...new Uint8Array(ciphertext)]), - ); - } - - /** - * Decrypts the provided ciphertext string. - * - * @param ciphertextBase64 A base64-encoded string containing the initialization vector and the ciphertext. - * @returns The decrypted plaintext string. - */ - public async decrypt(ciphertextBase64: string): Promise { - const decoder = new TextDecoder(); - - const ciphertextBuffer = base64ToBuffer(ciphertextBase64); - const iv = ciphertextBuffer.slice(0, 12); - const ciphertext = ciphertextBuffer.slice(12); - - const plaintext: Uint8Array = await crypto.subtle.decrypt( - { - name: "AES-GCM", - iv, - }, - this.key, - ciphertext, - ); - - return decoder.decode(plaintext); - } -} diff --git a/app/javascript/serviceworker/store.spec.ts b/app/javascript/serviceworker/store.spec.ts deleted file mode 100644 index 3223c600b4..0000000000 --- a/app/javascript/serviceworker/store.spec.ts +++ /dev/null @@ -1,101 +0,0 @@ -import "fake-indexeddb/auto"; -import FDBFactory from "fake-indexeddb/lib/FDBFactory"; -import { add, destroy, getByUrl, getAll } from "./store"; - -beforeEach(() => { - // Reset database https://github.com/dumbmatter/fakeIndexedDB/issues/40 - indexedDB = new FDBFactory(); -}); - -describe("add", () => { - it("saves the request", async () => { - await add("delayedRequests", "/api", { name: "John" }); - - const requests = await getAll("delayedRequests"); - - expect(requests).toMatchInlineSnapshot(` - [ - { - "body": { - "name": "John", - }, - "id": 1, - "url": "/api", - }, - ] - `); - }); - - it("dedupes requests by url", async () => { - await add("cachedResponses", "/api", { name: "John" }); - await add("cachedResponses", "/api", { name: "John" }); - - const requests = await getAll("cachedResponses"); - - expect(requests).toMatchInlineSnapshot(` - [ - { - "body": { - "name": "John", - }, - "id": 1, - "url": "/api", - }, - ] - `); - }); -}); - -describe("getAll", () => { - it("returns all requests", async () => { - let requests = await getAll("delayedRequests"); - - expect(requests).toMatchInlineSnapshot(`[]`); - - await add("delayedRequests", "/api", { name: "John" }); - - requests = await getAll("delayedRequests"); - - expect(requests).toMatchInlineSnapshot(` - [ - { - "body": { - "name": "John", - }, - "id": 1, - "url": "/api", - }, - ] - `); - }); -}); - -describe("getByUrl", () => { - it("gets a request by url", async () => { - await add("delayedRequests", "/api", { name: "John" }); - - const request = await getByUrl("delayedRequests", "/api"); - - expect(request).toMatchInlineSnapshot(` - { - "body": { - "name": "John", - }, - "id": 1, - "url": "/api", - } - `); - }); -}); - -describe("destroy", () => { - it("deletes a request", async () => { - await add("delayedRequests", "/api", { name: "John" }); - - await destroy("delayedRequests", 1); - - const requests = await getAll("delayedRequests"); - - expect(requests).toMatchInlineSnapshot(`[]`); - }); -}); diff --git a/app/javascript/serviceworker/store.ts b/app/javascript/serviceworker/store.ts deleted file mode 100644 index 63081996b3..0000000000 --- a/app/javascript/serviceworker/store.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { openDB, DBSchema } from "idb"; - -type StoreName = "cachedResponses" | "delayedRequests"; - -interface RequestObject { - id?: number; - url: string; - body: any; -} - -interface OfflineDatabase extends DBSchema { - delayedRequests: { - key: number; - value: RequestObject; - indexes: { url: string }; - }; - cachedResponses: { - key: number; - value: RequestObject; - indexes: { url: string }; - }; -} - -const DB_NAME = "offline"; -const DB_VERSION = 2; - -const openTx = async (storeName: StoreName, mode: "readwrite" | "readonly") => { - const db = await openDB(DB_NAME, DB_VERSION, { - upgrade(db) { - const delayedStore = db.createObjectStore("delayedRequests", { - keyPath: "id", - autoIncrement: true, - }); - - delayedStore.createIndex("url", "url", { unique: false }); - - const cachedStore = db.createObjectStore("cachedResponses", { - keyPath: "id", - autoIncrement: true, - }); - - cachedStore.createIndex("url", "url", { unique: true }); - }, - }); - - return db.transaction(storeName, mode); -}; - -export const add = async (storeName: StoreName, url: string, body: any) => { - const tx = await openTx(storeName, "readwrite"); - const request = await tx.store.index("url").get(url); - - if (storeName === "cachedResponses" && request) { - await tx.store.put({ ...request, body }); - } else { - await tx.store.add({ url, body }); - } - - await tx.done; -}; - -export const destroy = async (storeName: StoreName, id: number) => { - const tx = await openTx(storeName, "readwrite"); - await tx.store.delete(id); - await tx.done; -}; - -export const getByUrl = async ( - storeName: StoreName, - url: string, -): Promise => { - const tx = await openTx(storeName, "readonly"); - const request = await tx.store.index("url").get(url); - await tx.done; - - return request; -}; - -export const getAll = async ( - storeName: StoreName, -): Promise => { - const tx = await openTx(storeName, "readonly"); - const requests = await tx.store.getAll(); - await tx.done; - - return requests; -}; diff --git a/lib/tasks/serviceworker.rake b/lib/tasks/serviceworker.rake deleted file mode 100644 index 8ac97c6341..0000000000 --- a/lib/tasks/serviceworker.rake +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -namespace :serviceworker do - desc "Precompile serviceworker JS" - # Copy how the assets:precompile task depends on yarn being installed. - task precompile: %w[yarn:install] do - sh "yarn build:serviceworker" - end -end - -# Note this invokes serviceworker:precompile after assets:precompile is run. -Rake::Task["assets:precompile"].enhance do - Rake::Task["serviceworker:precompile"].invoke -end diff --git a/package.json b/package.json index 813b89ec08..89eb7f375d 100644 --- a/package.json +++ b/package.json @@ -10,14 +10,12 @@ "idb": "^8.0.3", "nhsuk-frontend": "^10.0.0", "sass": "^1.91.0", - "stimulus": "^3.2.2", - "workbox-build": "^7.3.0" + "stimulus": "^3.2.2" }, "scripts": { "build:css": "sass ./app/assets/stylesheets:./app/assets/builds --no-source-map --pkg-importer=node --quiet-deps --style compressed", "build": "esbuild app/javascript/*.[jt]s app/javascript/controllers/*.[jt]s --bundle --sourcemap --outdir=app/assets/builds --public-path=assets --minify", - "build:serviceworker": "esbuild app/javascript/serviceworker/main.js --bundle --sourcemap --outfile=public/sw.js --minify", - "test:e2e": "PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1 playwright test", + "test:e2e": "playwright test", "test:load": "artillery run tests/load.yml", "test": "jest" }, diff --git a/yarn.lock b/yarn.lock index 0b7c98988f..490265cd8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,15 +10,6 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@apideck/better-ajv-errors@^0.3.1": - version "0.3.6" - resolved "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz" - integrity sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA== - dependencies: - json-schema "^0.4.0" - jsonpointer "^5.0.0" - leven "^3.1.0" - "@asamuzakjp/css-color@^3.2.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@asamuzakjp/css-color/-/css-color-3.2.0.tgz#cc42f5b85c593f79f1fa4f25d2b9b321e61d1794" @@ -78,11 +69,6 @@ js-tokens "^4.0.0" picocolors "^1.1.1" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1", "@babel/compat-data@^7.20.5": - version "7.20.10" - resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz" - integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== - "@babel/compat-data@^7.23.5": version "7.24.4" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.4.tgz#6f102372e9094f25d908ca0d34fc74c74606059a" @@ -93,7 +79,7 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.27.5.tgz#7d0658ec1a8420fc866d1df1b03bea0e79934c82" integrity sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg== -"@babel/core@^7.1.0", "@babel/core@^7.12.17", "@babel/core@^7.12.3", "@babel/core@^7.24.4": +"@babel/core@^7.1.0", "@babel/core@^7.12.17", "@babel/core@^7.12.3": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.5.tgz#15ab5b98e101972d171aeef92ac70d8d6718f06a" integrity sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA== @@ -166,32 +152,6 @@ "@jridgewell/trace-mapping" "^0.3.25" jsesc "^3.0.2" -"@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz" - integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.18.6" - "@babel/types" "^7.18.9" - -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0", "@babel/helper-compilation-targets@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz" - integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ== - dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" - lru-cache "^5.1.1" - semver "^6.3.0" - "@babel/helper-compilation-targets@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" @@ -214,40 +174,6 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.5", "@babel/helper-create-class-features-plugin@^7.20.7": - version "7.20.12" - resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz" - integrity sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-member-expression-to-functions" "^7.20.7" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/helper-split-export-declaration" "^7.18.6" - -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz" - integrity sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - regexpu-core "^5.2.1" - -"@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz" - integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== - dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - "@babel/helper-environment-visitor@^7.18.9": version "7.18.9" resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz" @@ -258,21 +184,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== -"@babel/helper-explode-assignable-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz" - integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== - dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" - "@babel/helper-function-name@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" @@ -281,13 +192,6 @@ "@babel/template" "^7.22.15" "@babel/types" "^7.23.0" -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" - "@babel/helper-hoist-variables@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" @@ -295,14 +199,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-member-expression-to-functions@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz" - integrity sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw== - dependencies: - "@babel/types" "^7.20.7" - -"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.18.6": +"@babel/helper-module-imports@^7.18.6": version "7.18.6" resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz" integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== @@ -324,7 +221,7 @@ "@babel/traverse" "^7.27.1" "@babel/types" "^7.27.1" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11": +"@babel/helper-module-transforms@^7.20.11": version "7.20.11" resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz" integrity sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg== @@ -358,14 +255,7 @@ "@babel/helper-validator-identifier" "^7.27.1" "@babel/traverse" "^7.27.3" -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0": version "7.20.2" resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz" integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== @@ -375,28 +265,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== -"@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz" - integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-wrap-function" "^7.18.9" - "@babel/types" "^7.18.9" - -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz" - integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.20.7" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.7" - "@babel/types" "^7.20.7" - "@babel/helper-simple-access@^7.20.2": version "7.20.2" resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz" @@ -411,13 +279,6 @@ dependencies: "@babel/types" "^7.24.5" -"@babel/helper-skip-transparent-expression-wrappers@^7.20.0": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz" - integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== - dependencies: - "@babel/types" "^7.20.0" - "@babel/helper-split-export-declaration@^7.18.6": version "7.18.6" resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz" @@ -489,11 +350,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== - "@babel/helper-validator-option@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" @@ -504,16 +360,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== -"@babel/helper-wrap-function@^7.18.9": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz" - integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q== - dependencies: - "@babel/helper-function-name" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.5" - "@babel/types" "^7.20.5" - "@babel/helpers@^7.24.5": version "7.26.10" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.10.tgz#6baea3cd62ec2d0c1068778d63cb1314f6637384" @@ -592,151 +438,6 @@ dependencies: "@babel/types" "^7.26.10" -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz" - integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz" - integrity sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/plugin-proposal-optional-chaining" "^7.20.7" - -"@babel/plugin-proposal-async-generator-functions@^7.20.1": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz" - integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz" - integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-proposal-class-static-block@^7.18.6": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz" - integrity sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.20.7" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-proposal-dynamic-import@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz" - integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz" - integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz" - integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz" - integrity sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz" - integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-numeric-separator@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz" - integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.20.2": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz" - integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== - dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.20.7" - -"@babel/plugin-proposal-optional-catch-binding@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.18.9", "@babel/plugin-proposal-optional-chaining@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz" - integrity sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-private-methods@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz" - integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-proposal-private-property-in-object@^7.18.6": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz" - integrity sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.20.5" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz" - integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" @@ -765,27 +466,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-import-assertions@^7.20.0": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz" - integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== - dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/plugin-syntax-import-attributes@^7.24.7": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07" @@ -877,128 +557,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-arrow-functions@^7.18.6": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz" - integrity sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-async-to-generator@^7.18.6": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz" - integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q== - dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" - -"@babel/plugin-transform-block-scoped-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-block-scoping@^7.20.2": - version "7.20.11" - resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz" - integrity sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-classes@^7.20.2": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz" - integrity sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-split-export-declaration" "^7.18.6" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.18.9": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz" - integrity sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/template" "^7.20.7" - -"@babel/plugin-transform-destructuring@^7.20.2": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz" - integrity sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz" - integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-duplicate-keys@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz" - integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-exponentiation-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz" - integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-for-of@^7.18.8": - version "7.18.8" - resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz" - integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== - dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-member-expression-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-modules-amd@^7.19.6": - version "7.20.11" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz" - integrity sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g== - dependencies: - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-modules-commonjs@^7.12.13", "@babel/plugin-transform-modules-commonjs@^7.19.6": +"@babel/plugin-transform-modules-commonjs@^7.12.13": version "7.20.11" resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz" integrity sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw== @@ -1007,227 +566,7 @@ "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-simple-access" "^7.20.2" -"@babel/plugin-transform-modules-systemjs@^7.19.6": - version "7.20.11" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz" - integrity sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw== - dependencies: - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-identifier" "^7.19.1" - -"@babel/plugin-transform-modules-umd@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz" - integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== - dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz" - integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.20.5" - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-new-target@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz" - integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-object-super@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" - -"@babel/plugin-transform-parameters@^7.20.1", "@babel/plugin-transform-parameters@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz" - integrity sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-property-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-regenerator@^7.18.6": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz" - integrity sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - regenerator-transform "^0.15.1" - -"@babel/plugin-transform-reserved-words@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz" - integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-shorthand-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-spread@^7.19.0": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz" - integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - -"@babel/plugin-transform-sticky-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz" - integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-template-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-typeof-symbol@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz" - integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-unicode-escapes@^7.18.10": - version "7.18.10" - resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz" - integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-unicode-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz" - integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/preset-env@^7.11.0": - version "7.20.2" - resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz" - integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg== - dependencies: - "@babel/compat-data" "^7.20.1" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.20.1" - "@babel/plugin-proposal-class-properties" "^7.18.6" - "@babel/plugin-proposal-class-static-block" "^7.18.6" - "@babel/plugin-proposal-dynamic-import" "^7.18.6" - "@babel/plugin-proposal-export-namespace-from" "^7.18.9" - "@babel/plugin-proposal-json-strings" "^7.18.6" - "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" - "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.20.2" - "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-private-methods" "^7.18.6" - "@babel/plugin-proposal-private-property-in-object" "^7.18.6" - "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.20.0" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.18.6" - "@babel/plugin-transform-async-to-generator" "^7.18.6" - "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.20.2" - "@babel/plugin-transform-classes" "^7.20.2" - "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.20.2" - "@babel/plugin-transform-dotall-regex" "^7.18.6" - "@babel/plugin-transform-duplicate-keys" "^7.18.9" - "@babel/plugin-transform-exponentiation-operator" "^7.18.6" - "@babel/plugin-transform-for-of" "^7.18.8" - "@babel/plugin-transform-function-name" "^7.18.9" - "@babel/plugin-transform-literals" "^7.18.9" - "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.19.6" - "@babel/plugin-transform-modules-commonjs" "^7.19.6" - "@babel/plugin-transform-modules-systemjs" "^7.19.6" - "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" - "@babel/plugin-transform-new-target" "^7.18.6" - "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.20.1" - "@babel/plugin-transform-property-literals" "^7.18.6" - "@babel/plugin-transform-regenerator" "^7.18.6" - "@babel/plugin-transform-reserved-words" "^7.18.6" - "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.19.0" - "@babel/plugin-transform-sticky-regex" "^7.18.6" - "@babel/plugin-transform-template-literals" "^7.18.9" - "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.10" - "@babel/plugin-transform-unicode-regex" "^7.18.6" - "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.20.2" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - core-js-compat "^3.25.1" - semver "^6.3.0" - -"@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz" - integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/runtime@^7.11.2", "@babel/runtime@^7.8.4": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.10.tgz#a07b4d8fa27af131a633d7b3524db803eb4764c2" - integrity sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3": +"@babel/template@^7.20.7", "@babel/template@^7.3.3": version "7.20.7" resolved "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz" integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== @@ -1272,7 +611,7 @@ "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" -"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7": +"@babel/traverse@^7.20.10": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== @@ -1317,7 +656,7 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3": version "7.20.7" resolved "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz" integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== @@ -1952,14 +1291,6 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== -"@jridgewell/source-map@^0.3.3": - version "0.3.6" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" - integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - "@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" @@ -2113,61 +1444,6 @@ resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-8.0.200.tgz#1d27d9d55e45266e061190db045925e0b4d53d6b" integrity sha512-EDqWyxck22BHmv1e+mD8Kl6GmtNkhEPdRfGFT7kvsv1yoXd9iYrqHDVAaR8bKmU/syC5eEZ2I5aWWxtB73ukMw== -"@rollup/plugin-babel@^5.2.0": - version "5.3.1" - resolved "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz" - integrity sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@rollup/pluginutils" "^3.1.0" - -"@rollup/plugin-node-resolve@^15.2.3": - version "15.2.3" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz#e5e0b059bd85ca57489492f295ce88c2d4b0daf9" - integrity sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ== - dependencies: - "@rollup/pluginutils" "^5.0.1" - "@types/resolve" "1.20.2" - deepmerge "^4.2.2" - is-builtin-module "^3.2.1" - is-module "^1.0.0" - resolve "^1.22.1" - -"@rollup/plugin-replace@^2.4.1": - version "2.4.2" - resolved "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz" - integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== - dependencies: - "@rollup/pluginutils" "^3.1.0" - magic-string "^0.25.7" - -"@rollup/plugin-terser@^0.4.3": - version "0.4.4" - resolved "https://registry.yarnpkg.com/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz#15dffdb3f73f121aa4fbb37e7ca6be9aeea91962" - integrity sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A== - dependencies: - serialize-javascript "^6.0.1" - smob "^1.0.0" - terser "^5.17.4" - -"@rollup/pluginutils@^3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz" - integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== - dependencies: - "@types/estree" "0.0.39" - estree-walker "^1.0.1" - picomatch "^2.2.2" - -"@rollup/pluginutils@^5.0.1": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" - integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^2.0.2" - picomatch "^2.3.1" - "@sinclair/typebox@^0.34.0": version "0.34.35" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.34.35.tgz#185c57551d5edf9a2f6e9d012822b06f942cfbfc" @@ -2187,16 +1463,6 @@ dependencies: "@sinonjs/commons" "^3.0.1" -"@surma/rollup-plugin-off-main-thread@^2.2.3": - version "2.2.3" - resolved "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz" - integrity sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ== - dependencies: - ejs "^3.1.6" - json5 "^2.2.0" - magic-string "^0.25.0" - string.prototype.matchall "^4.0.6" - "@tybys/wasm-util@^0.9.0": version "0.9.0" resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.9.0.tgz#3e75eb00604c8d6db470bf18c37b7d984a0e3355" @@ -2248,16 +1514,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/estree@0.0.39": - version "0.0.39" - resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz" - integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== - -"@types/estree@^1.0.0": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== - "@types/graceful-fs@^4.1.2": version "4.1.6" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" @@ -2318,11 +1574,6 @@ resolved "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz" integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== -"@types/resolve@1.20.2": - version "1.20.2" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" - integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== - "@types/stack-utils@^2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" @@ -2333,11 +1584,6 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397" integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw== -"@types/trusted-types@^2.0.2": - version "2.0.2" - resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz" - integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== - "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" @@ -2464,11 +1710,6 @@ accessible-autocomplete@^3.0.1: resolved "https://registry.yarnpkg.com/accessible-autocomplete/-/accessible-autocomplete-3.0.1.tgz#8ddf4934d0b4ba6acb28de486dd505e062cdc86e" integrity sha512-xMshgc2LT5addvvfCTGzIkRrvhbOFeylFSnSMfS/PdjvvvElZkakCwxO3/yJYBWyi1hi3tZloqOJQ5kqqJtH4g== -acorn@^8.8.2: - version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" - integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== - adler-32@~1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.3.1.tgz#1dbf0b36dda0012189a32b3679061932df1821e2" @@ -2479,16 +1720,6 @@ agent-base@^7.1.0, agent-base@^7.1.2: resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1" integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw== -ajv@^8.6.0: - version "8.12.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - ansi-escapes@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -2578,26 +1809,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== -async@^3.2.3: - version "3.2.4" - resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - axe-core@~4.10.3: version "4.10.3" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.3.tgz#04145965ac7894faddbac30861e5d8f11bfd14fc" @@ -2671,30 +1887,6 @@ babel-plugin-jest-hoist@^26.6.2: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz" - integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== - dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" - semver "^6.1.1" - -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz" - integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" - -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz" - integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - babel-preset-current-node-syntax@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" @@ -2818,16 +2010,6 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" -browserslist@^4.21.3, browserslist@^4.21.4: - version "4.21.4" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== - dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" - browserslist@^4.22.2: version "4.23.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" @@ -2860,11 +2042,6 @@ buffer-from@^1.0.0: resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -builtin-modules@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" - integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== - cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -2880,14 +2057,6 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - callsites@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -2903,11 +2072,6 @@ camelcase@^6.3.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001400: - version "1.0.30001442" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz" - integrity sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow== - caniuse-lite@^1.0.30001587: version "1.0.30001614" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz#f894b4209376a0bf923d67d9c361d96b1dfebe39" @@ -2942,7 +2106,7 @@ chalk@^2.0.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -3038,16 +2202,6 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -common-tags@^1.8.0: - version "1.8.2" - resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz" - integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== - component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" @@ -3073,13 +2227,6 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== -core-js-compat@^3.25.1: - version "3.27.1" - resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.1.tgz" - integrity sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA== - dependencies: - browserslist "^4.21.4" - crc-32@~1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" @@ -3126,11 +2273,6 @@ crypto-js@^4.2.0: resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== - cssstyle@^4.2.1: version "4.4.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-4.4.0.tgz#a185e81564a6047693586d904d278cbe8565ba07" @@ -3183,24 +2325,11 @@ dedent@^1.6.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.6.0.tgz#79d52d6389b1ffa67d2bcef59ba51847a9d503b2" integrity sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA== -deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== - deepmerge@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -3245,18 +2374,6 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -ejs@^3.1.6: - version "3.1.10" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" - integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== - dependencies: - jake "^10.8.5" - -electron-to-chromium@^1.4.251: - version "1.4.284" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz" - integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== - electron-to-chromium@^1.4.668: version "1.4.751" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.751.tgz#b5b19742a435c589de02f60c16618150498bbd59" @@ -3306,62 +2423,6 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.0" - resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.0.tgz" - integrity sha512-GUGtW7eXQay0c+PRq0sGIKSdaBorfVqsCMhGHo4elP7YVqZu9nCZS4UkK4gv71gOWNMra/PaSKD3ao1oWExO0g== - dependencies: - call-bind "^1.0.2" - es-set-tostringtag "^2.0.0" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.4" - is-array-buffer "^3.0.0" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.10" - is-weakref "^1.0.2" - object-inspect "^1.12.2" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" - -es-set-tostringtag@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== - dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - has-tostringtag "^1.0.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - esbuild-jest@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/esbuild-jest/-/esbuild-jest-0.5.0.tgz#7a9964bfdecafca3b675a8aeb08193bcdba8b9d7" @@ -3428,21 +2489,6 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -estree-walker@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz" - integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== - -estree-walker@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - exec-sh@^0.3.2: version "0.3.6" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" @@ -3554,11 +2600,6 @@ fake-indexeddb@^4.0.2: dependencies: realistic-structured-clone "^3.0.0" -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" @@ -3571,13 +2612,6 @@ fb-watchman@^2.0.0, fb-watchman@^2.0.2: dependencies: bser "2.1.1" -filelist@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" - integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== - dependencies: - minimatch "^5.0.1" - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -3610,13 +2644,6 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -3637,22 +2664,12 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -fs-extra@^9.0.1: - version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@2.3.2, fsevents@^2.1.2, fsevents@~2.3.2: +fsevents@2.3.2, fsevents@^2.1.2: version "2.3.2" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -3662,31 +2679,6 @@ fsevents@^2.3.3: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - -functions-have-names@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" @@ -3697,20 +2689,6 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-own-enumerable-property-symbols@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" - integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== - get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -3728,14 +2706,6 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -3753,7 +2723,7 @@ glob@^10.3.10: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" -glob@^7.1.4, glob@^7.1.6: +glob@^7.1.4: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -3770,39 +2740,20 @@ globals@^11.1.0: resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - govuk-frontend@^5.11.2: version "5.11.2" - resolved "https://registry.yarnpkg.com/govuk-frontend/-/govuk-frontend-5.11.2.tgz#4c6f5f9617636c002f27c99ba62d2631be7ed19f" - integrity sha512-eHV8EMxYNjc+omFhB0HktQ3QmA3ZRdDsgRDlUIik+TpUHerR3XKXpo4zh/OGO2/C2mz65cX0XT0k4QrRFJZU8Q== - -graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.10" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + resolved "https://registry.yarnpkg.com/govuk-frontend/-/govuk-frontend-5.11.2.tgz#4c6f5f9617636c002f27c99ba62d2631be7ed19f" + integrity sha512-eHV8EMxYNjc+omFhB0HktQ3QmA3ZRdDsgRDlUIik+TpUHerR3XKXpo4zh/OGO2/C2mz65cX0XT0k4QrRFJZU8Q== graceful-fs@^4.2.11: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== +graceful-fs@^4.2.4: + version "4.2.10" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== has-flag@^3.0.0: version "3.0.0" @@ -3814,30 +2765,6 @@ has-flag@^4.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -3869,20 +2796,6 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hasown@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== - dependencies: - function-bind "^1.1.2" - html-encoding-sniffer@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz#696df529a7cfd82446369dc5193e590a3735b448" @@ -3923,11 +2836,6 @@ iconv-lite@0.6.3: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -idb@^7.0.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" - integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== - idb@^8.0.3: version "8.0.3" resolved "https://registry.yarnpkg.com/idb/-/idb-8.0.3.tgz#c91e558f15a8d53f1d7f53a094d226fc3ad71fd9" @@ -3964,15 +2872,6 @@ inherits@2: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -internal-slot@^1.0.3, internal-slot@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz" - integrity sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ== - dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - side-channel "^1.0.4" - is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -3987,52 +2886,16 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-array-buffer@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz" - integrity sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-typed-array "^1.1.10" - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-builtin-module@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" - integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== - dependencies: - builtin-modules "^3.3.0" - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -4040,20 +2903,6 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.13.0: - version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== - dependencies: - hasown "^2.0.0" - -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -4068,13 +2917,6 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -4127,23 +2969,6 @@ is-glob@^4.0.3: dependencies: is-extglob "^2.1.1" -is-module@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz" - integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -4156,11 +2981,6 @@ is-number@^7.0.0: resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" - integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== - is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -4173,26 +2993,6 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" - integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -4203,43 +3003,11 @@ is-stream@^2.0.0: resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -4340,16 +3108,6 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" -jake@^10.8.5: - version "10.8.5" - resolved "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== - dependencies: - async "^3.2.3" - chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" - jest-changed-files@30.0.5: version "30.0.5" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-30.0.5.tgz#ec448f83bd9caa894dd7da8707f207c356a19924" @@ -4890,45 +3648,16 @@ jsesc@^3.0.2: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" - integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== - json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-schema@^0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - -json5@^2.2.0, json5@^2.2.3: +json5@^2.2.3: version "2.2.3" resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonpointer@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz" - integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -4970,17 +3699,7 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" - integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== - -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz" - integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== - -lodash@^4.17.20, lodash@^4.7.0: +lodash@^4.7.0: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -5004,13 +3723,6 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -magic-string@^0.25.0, magic-string@^0.25.7: - version "0.25.9" - resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz" - integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== - dependencies: - sourcemap-codec "^1.4.8" - make-dir@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -5089,13 +3801,6 @@ minimatch@^3.0.4, minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: - version "5.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.2.tgz" - integrity sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg== - dependencies: - brace-expansion "^2.0.1" - minimatch@^9.0.4: version "9.0.5" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" @@ -5205,11 +3910,6 @@ node-releases@^2.0.19: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== -node-releases@^2.0.6: - version "2.0.8" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz" - integrity sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A== - normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -5250,16 +3950,6 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -5267,16 +3957,6 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -5392,11 +4072,6 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - path-scurry@^1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" @@ -5415,7 +4090,7 @@ picocolors@^1.1.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== -picomatch@^2.0.4, picomatch@^2.2.2, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -5466,11 +4141,6 @@ prettier@^3.6.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393" integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== -pretty-bytes@^5.3.0: - version "5.6.0" - resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz" - integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== - pretty-format@30.0.0, pretty-format@^30.0.0: version "30.0.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-30.0.0.tgz#a3137bed442af87eadea2c427a1b201189e590a4" @@ -5502,11 +4172,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - punycode@^2.1.1: version "2.2.0" resolved "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz" @@ -5522,13 +4187,6 @@ pure-rand@^7.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-7.0.1.tgz#6f53a5a9e3e4a47445822af96821ca509ed37566" integrity sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ== -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - react-is@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" @@ -5548,30 +4206,6 @@ realistic-structured-clone@^3.0.0: typeson "^6.1.0" typeson-registry "^1.0.0-alpha.20" -regenerate-unicode-properties@^10.1.0: - version "10.1.0" - resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz" - integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== - dependencies: - regenerate "^1.4.2" - -regenerate@^1.4.2: - version "1.4.2" - resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -regenerator-transform@^0.15.1: - version "0.15.1" - resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz" - integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== - dependencies: - "@babel/runtime" "^7.8.4" - regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -5580,39 +4214,6 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - -regexpu-core@^5.2.1: - version "5.2.2" - resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz" - integrity sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw== - dependencies: - regenerate "^1.4.2" - regenerate-unicode-properties "^10.1.0" - regjsgen "^0.7.1" - regjsparser "^0.9.1" - unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.1.0" - -regjsgen@^0.7.1: - version "0.7.1" - resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz" - integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA== - -regjsparser@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz" - integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== - dependencies: - jsesc "~0.5.0" - remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -5633,11 +4234,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -5655,36 +4251,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== -resolve@^1.14.2: - version "1.22.1" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^1.22.1: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rollup@^2.43.1: - version "2.79.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.2.tgz#f150e4a5db4b121a21a747d762f701e5e9f49090" - integrity sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ== - optionalDependencies: - fsevents "~2.3.2" - rrweb-cssom@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz#3021d1b4352fbf3b614aaeed0bc0d5739abe0bc2" @@ -5695,20 +4266,6 @@ rsvp@^4.8.4: resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== -safe-buffer@^5.1.0: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -5764,7 +4321,7 @@ semver@^5.5.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1: +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -5781,13 +4338,6 @@ semver@^7.7.2: resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== -serialize-javascript@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" - integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== - dependencies: - randombytes "^2.1.0" - set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -5822,15 +4372,6 @@ shebang-regex@^3.0.0: resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" @@ -5846,11 +4387,6 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -smob@^1.0.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/smob/-/smob-1.5.0.tgz#85d79a1403abf128d24d3ebc1cdc5e1a9548d3ab" - integrity sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig== - snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -5905,14 +4441,6 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-url@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" @@ -5928,18 +4456,6 @@ source-map@^0.6.0, source-map@^0.6.1: resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.8.0-beta.0: - version "0.8.0-beta.0" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz" - integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== - dependencies: - whatwg-url "^7.0.0" - -sourcemap-codec@^1.4.8: - version "1.4.8" - resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== - split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -6010,47 +4526,6 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string.prototype.matchall@^4.0.6: - version "4.0.8" - resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz" - integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.4.3" - side-channel "^1.0.4" - -string.prototype.trimend@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz" - integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string.prototype.trimstart@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz" - integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -stringify-object@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" - integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== - dependencies: - get-own-enumerable-property-symbols "^3.0.0" - is-obj "^1.0.1" - is-regexp "^1.0.0" - "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -6077,11 +4552,6 @@ strip-bom@^4.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== -strip-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz" - integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== - strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -6118,11 +4588,6 @@ supports-color@^8.1.1: dependencies: has-flag "^4.0.0" -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -6135,31 +4600,6 @@ synckit@^0.11.8: dependencies: "@pkgr/core" "^0.2.4" -temp-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz" - integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== - -tempy@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz" - integrity sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw== - dependencies: - is-stream "^2.0.0" - temp-dir "^2.0.0" - type-fest "^0.16.0" - unique-string "^2.0.0" - -terser@^5.17.4: - version "5.31.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.0.tgz#06eef86f17007dbad4593f11a574c7f5eb02c6a1" - integrity sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" - commander "^2.20.0" - source-map-support "~0.5.20" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -6230,13 +4670,6 @@ tough-cookie@^5.1.1: dependencies: tldts "^6.1.32" -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz" - integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== - dependencies: - punycode "^2.1.0" - tr46@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" @@ -6266,25 +4699,11 @@ type-detect@4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.16.0: - version "0.16.0" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz" - integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== - type-fest@^0.21.3: version "0.21.3" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - is-typed-array "^1.1.9" - typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -6306,39 +4725,6 @@ typeson@^6.0.0, typeson@^6.1.0: resolved "https://registry.yarnpkg.com/typeson/-/typeson-6.1.0.tgz#5b2a53705a5f58ff4d6f82f965917cabd0d7448b" integrity sha512-6FTtyGr8ldU0pfbvW/eOZrEtEkczHRUtduBnA90Jh9kMPCiFNnXIon3vF41N0S4tV1HHQt4Hk1j4srpESziCaA== -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz" - integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== - -unicode-match-property-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz" - integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== - dependencies: - unicode-canonical-property-names-ecmascript "^2.0.0" - unicode-property-aliases-ecmascript "^2.0.0" - -unicode-match-property-value-ecmascript@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz" - integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== - -unicode-property-aliases-ecmascript@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz" - integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== - union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -6349,18 +4735,6 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" -unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== - dependencies: - crypto-random-string "^2.0.0" - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - unrs-resolver@^1.7.11: version "1.9.0" resolved "https://registry.yarnpkg.com/unrs-resolver/-/unrs-resolver-1.9.0.tgz#22877e2e0f1ba3f848f75f7be5ecb81b634066dc" @@ -6396,11 +4770,6 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -upath@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== - update-browserslist-db@^1.0.13: version "1.0.13" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" @@ -6409,14 +4778,6 @@ update-browserslist-db@^1.0.13: escalade "^3.1.1" picocolors "^1.0.0" -update-browserslist-db@^1.0.9: - version "1.0.10" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - update-browserslist-db@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" @@ -6425,13 +4786,6 @@ update-browserslist-db@^1.1.3: escalade "^3.2.0" picocolors "^1.1.1" -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" @@ -6513,15 +4867,6 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-url@^8.4.0: version "8.7.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" @@ -6531,29 +4876,6 @@ whatwg-url@^8.4.0: tr46 "^2.1.0" webidl-conversions "^6.1.0" -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" - which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -6568,164 +4890,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -workbox-background-sync@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz#b6340731a8d5b42b9e75a8a87c8806928e6e6303" - integrity sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg== - dependencies: - idb "^7.0.1" - workbox-core "7.3.0" - -workbox-broadcast-update@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-7.3.0.tgz#bff86b91795c4b9fa46a758d1a7a151828623280" - integrity sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA== - dependencies: - workbox-core "7.3.0" - -workbox-build@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-7.3.0.tgz#ab688f3241b32862236aeeb62b240195f1fe4b62" - integrity sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ== - dependencies: - "@apideck/better-ajv-errors" "^0.3.1" - "@babel/core" "^7.24.4" - "@babel/preset-env" "^7.11.0" - "@babel/runtime" "^7.11.2" - "@rollup/plugin-babel" "^5.2.0" - "@rollup/plugin-node-resolve" "^15.2.3" - "@rollup/plugin-replace" "^2.4.1" - "@rollup/plugin-terser" "^0.4.3" - "@surma/rollup-plugin-off-main-thread" "^2.2.3" - ajv "^8.6.0" - common-tags "^1.8.0" - fast-json-stable-stringify "^2.1.0" - fs-extra "^9.0.1" - glob "^7.1.6" - lodash "^4.17.20" - pretty-bytes "^5.3.0" - rollup "^2.43.1" - source-map "^0.8.0-beta.0" - stringify-object "^3.3.0" - strip-comments "^2.0.1" - tempy "^0.6.0" - upath "^1.2.0" - workbox-background-sync "7.3.0" - workbox-broadcast-update "7.3.0" - workbox-cacheable-response "7.3.0" - workbox-core "7.3.0" - workbox-expiration "7.3.0" - workbox-google-analytics "7.3.0" - workbox-navigation-preload "7.3.0" - workbox-precaching "7.3.0" - workbox-range-requests "7.3.0" - workbox-recipes "7.3.0" - workbox-routing "7.3.0" - workbox-strategies "7.3.0" - workbox-streams "7.3.0" - workbox-sw "7.3.0" - workbox-window "7.3.0" - -workbox-cacheable-response@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-7.3.0.tgz#557b0f5fdfceb22fe243e3f19807c76a0ae646e3" - integrity sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA== - dependencies: - workbox-core "7.3.0" - -workbox-core@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-7.3.0.tgz#f24fb92041a0b7482fe2dd856544aaa9fa105248" - integrity sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw== - -workbox-expiration@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-7.3.0.tgz#2c1ee1fdada34aa7e7474f706d5429c914bd10d2" - integrity sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ== - dependencies: - idb "^7.0.1" - workbox-core "7.3.0" - -workbox-google-analytics@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-7.3.0.tgz#3c4d4956c0a9800dfb587d82ec8bc0f9cf963791" - integrity sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg== - dependencies: - workbox-background-sync "7.3.0" - workbox-core "7.3.0" - workbox-routing "7.3.0" - workbox-strategies "7.3.0" - -workbox-navigation-preload@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-7.3.0.tgz#9d54693b9179d5175e66af5ef9a92d1b7cf3e605" - integrity sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg== - dependencies: - workbox-core "7.3.0" - -workbox-precaching@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-7.3.0.tgz#a84663d69efdb334f25c04dba0a72ed3391c4da8" - integrity sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw== - dependencies: - workbox-core "7.3.0" - workbox-routing "7.3.0" - workbox-strategies "7.3.0" - -workbox-range-requests@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-7.3.0.tgz#1b3d5c235a0ff5271418c3a7183281dc131ccd0d" - integrity sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ== - dependencies: - workbox-core "7.3.0" - -workbox-recipes@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-7.3.0.tgz#fa407101e8ce52850dfba8e17a5afccb733a3942" - integrity sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg== - dependencies: - workbox-cacheable-response "7.3.0" - workbox-core "7.3.0" - workbox-expiration "7.3.0" - workbox-precaching "7.3.0" - workbox-routing "7.3.0" - workbox-strategies "7.3.0" - -workbox-routing@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-7.3.0.tgz#fc86296bc1155c112ee2c16b3180853586c30208" - integrity sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A== - dependencies: - workbox-core "7.3.0" - -workbox-strategies@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-7.3.0.tgz#bb1530f205806895aacdea3639e6cf6bfb3a6cb0" - integrity sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg== - dependencies: - workbox-core "7.3.0" - -workbox-streams@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-7.3.0.tgz#a4c0ae51b66121a2aa6f89229e237aca6dc27eb5" - integrity sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw== - dependencies: - workbox-core "7.3.0" - workbox-routing "7.3.0" - -workbox-sw@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-7.3.0.tgz#39215017e868d7cfe6835b2961f55369d89b3e73" - integrity sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA== - -workbox-window@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-7.3.0.tgz#e71bb0b4d880d2295c96bf1ccadb6cea0df51c07" - integrity sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA== - dependencies: - "@types/trusted-types" "^2.0.2" - workbox-core "7.3.0" - "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" From b3f214c75621a4aa82b54f2b64f804877b4166f3 Mon Sep 17 00:00:00 2001 From: Paul Robert Lloyd Date: Tue, 26 Aug 2025 15:23:07 +0100 Subject: [PATCH 4/4] Remove architecture documents for unused service worker --- docs/architecture-future.adoc | 13 -- docs/diagrams/component-view-future.puml | 5 - .../failed-malicious-get-of-csrf.puml | 23 -- ...d-malicious-offline-post-without-csrf.puml | 33 --- .../failed-malicious-post-with-csrf.puml | 30 --- ...ailed-offline-post-with-outdated-csrf.puml | 39 ---- .../malicious-offline-post-without-csrf.puml | 29 --- ...nation-while-offline-sequence-diagram.puml | 30 --- ...rogramme-for-offline-sequence-diagram.puml | 14 -- docs/diagrams/service-worker.puml | 26 --- .../successful-offline-post-with-csrf.puml | 35 --- .../successful-offline-post-without-csrf.puml | 32 --- docs/diagrams/successful-post-with-csrf.puml | 22 -- .../working-online-sequence-diagram.puml | 20 -- docs/offline-csrf-security.adoc | 148 ------------ docs/offline-support.adoc | 221 ------------------ 16 files changed, 720 deletions(-) delete mode 100644 docs/diagrams/failed-malicious-get-of-csrf.puml delete mode 100644 docs/diagrams/failed-malicious-offline-post-without-csrf.puml delete mode 100644 docs/diagrams/failed-malicious-post-with-csrf.puml delete mode 100644 docs/diagrams/failed-offline-post-with-outdated-csrf.puml delete mode 100644 docs/diagrams/malicious-offline-post-without-csrf.puml delete mode 100644 docs/diagrams/recording-vaccination-while-offline-sequence-diagram.puml delete mode 100644 docs/diagrams/saving-programme-for-offline-sequence-diagram.puml delete mode 100644 docs/diagrams/service-worker.puml delete mode 100644 docs/diagrams/successful-offline-post-with-csrf.puml delete mode 100644 docs/diagrams/successful-offline-post-without-csrf.puml delete mode 100644 docs/diagrams/successful-post-with-csrf.puml delete mode 100644 docs/diagrams/working-online-sequence-diagram.puml delete mode 100644 docs/offline-csrf-security.adoc delete mode 100644 docs/offline-support.adoc diff --git a/docs/architecture-future.adoc b/docs/architecture-future.adoc index 8f1ebaeb9d..e90318b853 100644 --- a/docs/architecture-future.adoc +++ b/docs/architecture-future.adoc @@ -197,11 +197,6 @@ include::diagrams/component-view-future.puml[] ---- endif::[] -Browser Cache Storage:: -Data necessary for offline functionality is stored in the browser's cache -storage. This is managed by the service worker, see the offline documentation -for more information. - Database:: Relational storage used to store application data including programme data, consent responses and vaccination events. In the case of the vaccination events, @@ -219,17 +214,9 @@ service using a standard login page, and as is standard with Ruby on Rails apps, resources are exposed with REST-like paths using an MVC approach to separate concerns on the server. -There is a notable exception made to this pattern, though, to support offline -working. - -=== Offline support - -include::offline-support.adoc[leveloffset=+2,lines=24..-1] - == Components * Authentication * Programme management - creation, update, etc * Programme operations and vaccination recording -* Offline support - Browser-based component * FHIR server synchronisation diff --git a/docs/diagrams/component-view-future.puml b/docs/diagrams/component-view-future.puml index a88e87d020..2e0f0b05e5 100644 --- a/docs/diagrams/component-view-future.puml +++ b/docs/diagrams/component-view-future.puml @@ -15,8 +15,6 @@ Boundary(aws, "AWS") { System_Boundary(manage, "Manage vaccinations in schools", "") { Container_Boundary(browser, "Browser Application", "JavaScript") { Component(pages, "Web Pages", "HTML, CSS") - Component(serviceWorker, "Service Worker", "JavaScript") - ComponentDb_Ext(cacheStorage, "Browser Cache Storage", "On Disk") } Container_Boundary(server, "Server Application", "Ruby on Rails") { Component(webapp, "Web Application", "Ruby on Rails") @@ -37,9 +35,6 @@ AddRelTag("optional", $textColor="black", $lineColor="black", $lineStyle="dashed Rel(sais, pages, "Manage programmes") Rel(sais, pages, "Record Child Vaccination") Rel(parents, pages, "Consent response") -Rel(pages, serviceWorker, "Request Assets", "internal fetch") -Rel(serviceWorker, cacheStorage, "Cache Assets") -Rel(serviceWorker, webapp, "Request pages", "HTTPS") Rel(webapp, database, "Read and write data", "Postgres, TLS") Rel(webapp, govukNotify, "Send email and SMS") Rel(webapp, vaccineRecord, "Updates Child Vaccination History", $tags="optional") diff --git a/docs/diagrams/failed-malicious-get-of-csrf.puml b/docs/diagrams/failed-malicious-get-of-csrf.puml deleted file mode 100644 index 227f0f5c1f..0000000000 --- a/docs/diagrams/failed-malicious-get-of-csrf.puml +++ /dev/null @@ -1,23 +0,0 @@ -@startuml - -title Failed malicious GET of CSRF - -autoactivate on - -== User is still authenticated with manage.nhs.uk == - -group Malicious update to patient data - Browser -> evil.site: GET / - return 200 OK - note right - // Malicious script attempts to retrieve a csrf token - fetch("https://manage.nhs.uk/csrf") - end note - - Browser -[#red]>x manage.nhs.uk: GET /csrf - note right #FCC - Cross-Origin Request Blocked by browser - end note -end - -@enduml diff --git a/docs/diagrams/failed-malicious-offline-post-without-csrf.puml b/docs/diagrams/failed-malicious-offline-post-without-csrf.puml deleted file mode 100644 index e01011752c..0000000000 --- a/docs/diagrams/failed-malicious-offline-post-without-csrf.puml +++ /dev/null @@ -1,33 +0,0 @@ -@startuml - -title Failed malicious offline POST without CSRF - -autoactivate on - -== User is still authenticated with manage.nhs.uk == - -group Malicious update to patient data - Browser -> evil.site: GET / - return 200 OK - note right - // Malicious form that POSTs to manage.nhs.uk -
- - - ... - end note - - Browser -> manage.nhs.uk: POST /patients/1/vaccinations/ - note right - vaccination=mmr - vaccination_performed=false - end note - - Browser <-[#red]-x manage.nhs.uk: 422 Unprocessable entity - deactivate manage.nhs.uk - note right #FCC - Missing CSRF token - end note -end - -@enduml diff --git a/docs/diagrams/failed-malicious-post-with-csrf.puml b/docs/diagrams/failed-malicious-post-with-csrf.puml deleted file mode 100644 index 4413a7c649..0000000000 --- a/docs/diagrams/failed-malicious-post-with-csrf.puml +++ /dev/null @@ -1,30 +0,0 @@ -@startuml - -title Failed malicious POST with CSRF - -autoactivate on - -== User is still authenticated with manage.nhs.uk == - -Browser -> evil.site: GET / -return 200 OK -note right - // Malicious form that POSTs to manage.nhs.uk - - - - ... -end note - -Browser -> manage.nhs.uk: POST /patients/1/vaccinations -note right - vaccine=mmr - vaccination_given=false -end note -Browser <-[#red]-x manage.nhs.uk: 422 Unprocessable entity -deactivate manage.nhs.uk -note right #FCC - Missing CSRF token -end note - -@enduml diff --git a/docs/diagrams/failed-offline-post-with-outdated-csrf.puml b/docs/diagrams/failed-offline-post-with-outdated-csrf.puml deleted file mode 100644 index ca7d016ee8..0000000000 --- a/docs/diagrams/failed-offline-post-with-outdated-csrf.puml +++ /dev/null @@ -1,39 +0,0 @@ -@startuml - -title Failed offline POST with outdated CSRF - -autoactivate on - -group Prepare to work offline - Browser -> manage.nhs.uk: GET /patients/1/vaccinations/new - return 200 OK - note right - // Form including CSRF token - csrf_token="CSRF token" - end note -end - -== Browser goes offline == - -group Perform offline work - Browser --> Browser: Records vaccination -end - -== Browser comes back online == - -group Update patient data - Browser -> manage.nhs.uk: POST /patients/1/vaccinations/ - note right - vaccination=mmr - vaccination_given=false - // This token is now old - csrf_token="CSRF token" - end note - Browser <-[#red]-x manage.nhs.uk: 422 Unprocessable entity - deactivate manage.nhs.uk - note right #FCC - Invalid CSRF token - end note -end - -@enduml diff --git a/docs/diagrams/malicious-offline-post-without-csrf.puml b/docs/diagrams/malicious-offline-post-without-csrf.puml deleted file mode 100644 index af58d93ca7..0000000000 --- a/docs/diagrams/malicious-offline-post-without-csrf.puml +++ /dev/null @@ -1,29 +0,0 @@ -@startuml - -title Malicious offline POST without CSRF - -autoactivate on - -== User is still authenticated with manage.nhs.uk == - -group Malicious update to patient data - Browser -> evil.site: GET / - return 200 OK - note right - // Malicious form that POSTs to manage.nhs.uk - - - - ... - end note - - Browser -> manage.nhs.uk: POST /patients/1/vaccinations - note right - vaccine=mmr - vaccination_performed=false - // No CSRF token needed - end note - return 200 OK -end - -@enduml diff --git a/docs/diagrams/recording-vaccination-while-offline-sequence-diagram.puml b/docs/diagrams/recording-vaccination-while-offline-sequence-diagram.puml deleted file mode 100644 index 0f71f8a814..0000000000 --- a/docs/diagrams/recording-vaccination-while-offline-sequence-diagram.puml +++ /dev/null @@ -1,30 +0,0 @@ -@startuml - -participant "User" as user -participant "Front-End" as frontend -participant "Service Worker" as sw -participant "Server App" as server - -== Client is offline == -sw ->x server: ping -note left: Service worker checks if it can access the server -note right: No response -sw -> sw: set status to offline - -user -> frontend: View programme -frontend -> sw: get programme pages -frontend <-- sw: programme page - -user -> frontend: Record vaccination -frontend -> sw: post vaccination record -sw -> sw: save vaccination record -frontend <-- sw: ok - -== Client comes back online == -sw -> server: ping -sw <-- server: ok -sw -> sw: set status to online -sw -> server: post vaccination record -sw <-- server: ok - -@enduml diff --git a/docs/diagrams/saving-programme-for-offline-sequence-diagram.puml b/docs/diagrams/saving-programme-for-offline-sequence-diagram.puml deleted file mode 100644 index 7c22fdcf36..0000000000 --- a/docs/diagrams/saving-programme-for-offline-sequence-diagram.puml +++ /dev/null @@ -1,14 +0,0 @@ -@startuml - -participant "User" as user -participant "Front-End" as frontend -participant "Service Worker" as sw -participant "Server App" as server - -user -> frontend: Click "Save programme for offline use"\n on programme page -frontend -> sw: message("Save programme 1 for offline") -note over sw, server: The service worker requests resources it will need for offline use. -sw -> server: get programme pages and data -sw <-- server: requested resources - -@enduml diff --git a/docs/diagrams/service-worker.puml b/docs/diagrams/service-worker.puml deleted file mode 100644 index 8851338c3e..0000000000 --- a/docs/diagrams/service-worker.puml +++ /dev/null @@ -1,26 +0,0 @@ -@startuml - -title Manage vaccinations in schools service worker - -!include - -LAYOUT_TOP_DOWN() - -System_Boundary(manage, "Manage vaccinations in schools") { - Container_Boundary(browser, "Web Browser") { - Component(frontend, "Front-End", "HTML, Javascript") - Component(serviceWorker, "Service Worker", "Javascript") - ComponentDb(indexedDB, "Cache", "IndexedDB") - ComponentDb(cacheDB, "Cache", "Browser Cache") - } - - Container(server, "Server App", "Ruby on Rails") -} - -Lay_D(cacheDB, indexedDB) -Rel(frontend, serviceWorker, "Get Pages and Data") -Rel(serviceWorker, indexedDB, "Cache Data") -Rel_L(serviceWorker, cacheDB, "Cache Pages") -Rel(serviceWorker, server, "Get Pages and Data") - -@enduml diff --git a/docs/diagrams/successful-offline-post-with-csrf.puml b/docs/diagrams/successful-offline-post-with-csrf.puml deleted file mode 100644 index d7dc815307..0000000000 --- a/docs/diagrams/successful-offline-post-with-csrf.puml +++ /dev/null @@ -1,35 +0,0 @@ -@startuml -title Successful offline POST with CSRF - -autoactivate on - -group Prepare to work offline - Browser -> manage.nhs.uk: GET /patients/1/vaccinations/new - return 200 OK - note right - // HTML form without CSRF token - end note -end - -== Browser goes offline == - -group Perform offline work - Browser-->Browser: Records vaccination -end - -== Browser comes back online == - -Browser -> manage.nhs.uk: GET /csrf -return 200 OK -note right: "New CSRF token" - -group Update patient data - Browser -> manage.nhs.uk: POST /patients/1/vaccinations/ - note right - vaccination=mmr - vaccination_performed=false - csrf="New CSRF token" - end note - return 200 OK -end -@enduml diff --git a/docs/diagrams/successful-offline-post-without-csrf.puml b/docs/diagrams/successful-offline-post-without-csrf.puml deleted file mode 100644 index bcb369b207..0000000000 --- a/docs/diagrams/successful-offline-post-without-csrf.puml +++ /dev/null @@ -1,32 +0,0 @@ -@startuml - -title Successful offline POST without CSRF - -autoactivate on - -group Prepare to work offline - Browser -> manage.nhs.uk: GET /patients/1/vaccinations/new - return 200 OK - note right - // HTML form without CSRF token - end note -end - -== Browser goes offline == - -group Perform offline work - Browser --> Browser: Records vaccination -end - -== Browser comes back online == - -group Update patient data - Browser -> manage.nhs.uk: POST /patients/1/vaccinations/ - note right - vaccination=mmr - vaccination_performed=false - end note - return 200 OK -end - -@enduml diff --git a/docs/diagrams/successful-post-with-csrf.puml b/docs/diagrams/successful-post-with-csrf.puml deleted file mode 100644 index cce7547f4e..0000000000 --- a/docs/diagrams/successful-post-with-csrf.puml +++ /dev/null @@ -1,22 +0,0 @@ -@startuml - -title Successful POST with CSRF - -autoactivate on - -Browser -> manage.nhs.uk: GET /patients/1/vaccinations/new -return 200 OK - -note right - csrf="Unique CSRF Token" -end note - -Browser -> manage.nhs.uk: POST /patients/1/vaccinations -note right - vaccine=mmr - vaccination_given=true - csrf="Unique CSRF Token" -end note -return 200 OK - -@enduml diff --git a/docs/diagrams/working-online-sequence-diagram.puml b/docs/diagrams/working-online-sequence-diagram.puml deleted file mode 100644 index c5a500e353..0000000000 --- a/docs/diagrams/working-online-sequence-diagram.puml +++ /dev/null @@ -1,20 +0,0 @@ -@startuml - -participant "User" as user -participant "Front-End" as frontend -participant "Service Worker" as sw -participant "Server App" as server - -user -> frontend: View programme -frontend -> sw: get programme pages -sw -> server: get programme pages -sw <-- server: programme page -frontend <-- sw: programme page - -user -> frontend: Record vaccination -frontend -> sw: post vaccination record -sw -> server: post vaccination record -sw <-- server: ok -frontend <-- sw: ok - -@enduml diff --git a/docs/offline-csrf-security.adoc b/docs/offline-csrf-security.adoc deleted file mode 100644 index 01aa0fad33..0000000000 --- a/docs/offline-csrf-security.adoc +++ /dev/null @@ -1,148 +0,0 @@ -:imagesdir: images -:source-highlighter: pygments - -ifdef::env-github[] -// If on GitHub, define attributes so we can find our diagram files and render -// them. - -// The branch will be used to find the correct diagrams to render below. -// Change this when working on updates to the diagrams and want the new ones -// reflected on GitHub, e.g. on a PR. -:github-branch: main - -:github-repo: nhsuk/record-childrens-vaccinations - -// URL for PlantUML Proxy. Using an attribute mainly because it's just tidier. -:plantuml-proxy-url: http://www.plantuml.com/plantuml/proxy?cache=no&src= - -// Full path prefix we'll use for diagrams below. -:diagram-path-url: {plantuml-proxy-url}https://raw.githubusercontent.com/{github-repo}/{github-branch}/docs -endif::[] - -# Offline CSRF Security - -## CSRF Security - -Normally a CSRF token protects from cross-site attacks by ensuring that the data -being submitted is coming from a trusted source. See the -https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#how_to_block_cross-origin_access[MDN documentation] -for more info on the browser's cross-origin policy. This means that the -submitted form was generated by the trusted website, i.e. the same site that the -form is being submitted to, and not by a different site using a malicious -payload. - -To illustrate, a normal interaction with valid CSRF looks like this: - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/successful-post-with-csrf.puml[Successful POST with CSRF diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/successful-post-with-csrf.puml[] ----- -endif::[] - -Then if a malicious site tries to piggy-back on the browser's already-established -session, they would not have access to the unique CSRF token and would not be -able to submit a malicious payload: - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/failed-malicious-post-with-csrf.puml[Failed malicious POST with CSRF diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/failed-malicious-post-with-csrf.puml[] ----- -endif::[] - -## Offline Mode - -When working offline, however, the form used to submit the vaccinations data is -generated before going offline, and then submitted once the browser is back -online. This triggers CSRF protection because the CSRF token is, most likely, no -longer valid after the browser has been offline for some time: - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/failed-offline-post-with-outdated-csrf.puml[Failed offline POST with outdated CSRF diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/failed-offline-post-with-outdated-csrf.puml[] ----- -endif::[] - -The simplest way to make this work is to remove the need for a CSRF token altogether: - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/successful-offline-post-without-csrf.puml[Successful offline POST without CSRF diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/successful-offline-post-without-csrf.puml[] ----- -endif::[] - -But that opens us up to malicious actors: - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/malicious-offline-post-without-csrf.puml[Malicious offline POST without CSRF diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/malicious-offline-post-without-csrf.puml[] ----- -endif::[] - -To secure this, we need to re-introduce a way to get a CSRF token through a GET -request to record.nhs.uk. Doing a GET request from JS on a page from evil.site -will trigger cross-site scripting protection in modern browsers: - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/successful-offline-post-with-csrf.puml[Successful offline POST with CSRF diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/successful-offline-post-with-csrf.puml[] ----- -endif::[] - -And now when the attacker attempts to submit the form they are missing the required CSRF token: - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/failed-malicious-offline-post-without-csrf.puml[Failed malicious offline POST without CSRF diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/failed-malicious-offline-post-without-csrf.puml[] ----- -endif::[] - -The attacker is similarly blocked from retrieving the CSRF token by the -browser's -https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy[Same-origin -policy]: - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/failed-malicious-get-of-csrf.puml[Failed malicious GET of CSRF diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/failed-malicious-get-of-csrf.puml[] ----- -endif::[] diff --git a/docs/offline-support.adoc b/docs/offline-support.adoc deleted file mode 100644 index 33d7725e5b..0000000000 --- a/docs/offline-support.adoc +++ /dev/null @@ -1,221 +0,0 @@ -ifdef::env-github[] -// If on GitHub, define attributes so we can find our diagram files and render -// them. - -// The branch will be used to find the correct diagrams to render below. -// When PRing changes to the diagrams you can change this attributes -// temporarily to the name of the branch you're working on. But don't forget -// to change it back to main before merging!! -:github-branch: main - -:github-repo: nhsuk/record-childrens-vaccinations - -// URL for PlantUML Proxy. Using an attribute mainly because it's just tidier. -:plantuml-proxy-url: http://www.plantuml.com/plantuml/proxy?cache=no&src= - -// Full path prefix we'll use for diagrams below. -:diagram-path-url: {plantuml-proxy-url}https://raw.githubusercontent.com/{github-repo}/{github-branch}/docs -endif::[] - -:toc: - -= Offline support - -A key feature required for the Record children's vaccines service is to allow -clinical users to use parts of the system while not connected to the Internet. -There are certain clinical settings where Internet access isn't available, for -example in schools where there may be no mobile signal or WiFi that the SAIS -team can use. - -To accomplish this the standard patterns provided by server-rendered apps are -insufficient. Aggressive caching can help accommodate viewing data, but updating -records requires a more advanced approach. - -== Feature overview - -The service's current design is for SAIS team members to be able to select -specific programmes to be saved (after being encrypted) for offline use. The user -is then be able to retrieve and view saved patient information, including -consent status and other info (e.g. past vaccination history), before performing -the vaccination. When the vaccination is performed, the event will be recorded -to their local system in an encrypted form. Once reconnected to the Internet, -the records will be uploaded from the local system to the service. - -All data saved locally is encrypted using a user-supplied password, which is -only ever stored in memory. - -== Technical approach - -IMPORTANT: The design of this service feature is still being designed and tested - with users. The exact approach described here may change, e.g. the - user may need to manually initiate the synchronisation back to the - server, etc. - -=== Service Worker - -The service worker, a feature link:https://caniuse.com/serviceworkers[widely -available in modern browsers], is used to implement the majority of offline -functionality. This service worker sits between the website and the server and -is responsible for the offline functionality. It does this by detecting whether -the browser is online or offline, and implementing caching as appropriate. - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/service-worker.puml[Service worker diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/service-worker.puml[] ----- -endif::[] - -It contains the logic for preparing to work offline, caching pages and data, and -syncing data back to the server once back online. The following sequence -diagrams illustrate the functionality. - -.Using the service while online -Normally when online, requests, while intercepted by the Service worker, go -straight to the server. - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/working-online-sequence-diagram.puml[Working online sequence diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/working-online-sequence-diagram.puml[] ----- -endif::[] - - -.Saving a programme for offline -When the user is ready, they save a programme to be run while offline: - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/saving-programme-for-offline-sequence-diagram.puml[Saving programme for offline sequence diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/saving-programme-for-offline-sequence-diagram.puml[] ----- -endif::[] - -.Recording vaccinations while offline -When the client goes offline, the Service worker continues to respond to -front-end requests as if still online, but saves the vaccination record to be -synchronised later. - -ifdef::env-github[] -image::{diagram-path-url}/diagrams/recording-vaccination-while-offline-sequence-diagram.puml[Working online sequence diagram] -endif::[] - -ifndef::env-github[] -[plantuml,align="center"] ----- -include::diagrams/recording-vaccination-while-offline-sequence-diagram.puml[] ----- -endif::[] - -.Record Validation -**** -There will be a component of record validation performed in the above steps. In -typical server based apps this happens on the posting of the data; in offline -mode validation is still done by the server, and has to wait until the client is -back online and syncs the data. At this point any errors will be presented to -the user. -**** - -== Security - -Ruby on Rails comes with many security features built-in, such as encryption of -cookie-based session data, protection against CSRF, protection against SQL -injection, etc. These are documented in the -link:https://guides.rubyonrails.org/security.html[Securing Rails -Applications] Rails Guide and aren't covered here. - -However, by implementing offline working mode we potentially create new -vulnerabilities. These vulnerabilities, and how we might be able mitigate -against them, are discussed here. - -=== Attack scenarios - -==== JavaScript accessing cached data - -.Attack vectors -* User installs malicious browser extension -* JavaScript injection via unsafe HTTP (non-SSL) connection -* Resource loaded from CDN is compromised. -** We don't use CDN resources. -** We can enable sub-resource integrity. - -Our offline implementation doesn't increase our vulnerability because any -JavaScript running in the browser will require that the user visit the service's -website in order to be able to access the cached data (in IndexedDB). In this -situation it doesn't matter if the data is cached locally, as the malicious code -could simply download the data using the user's existing session. - -==== JavaScript stealing session - -.Attack vectors -* Malicious actor uses JavaScript to steal cookie and use it access the service - from another browser. -** We can use HttpOnly flag on cookies to disallow access to it from JavaScript. - -Our implementation of cached data in the browser does not increase our -vulnerability to this attack. If an attacker steals a session this will give -them access to the data on the server. - -==== Physical access to device - -.Attack vectors -* Malicious actor gains physical access to the device by a SAIS user, and the - built-in OS security is weakened (e.g. automatic login enabled or the disk - isn't encrypted). - -Because our implementation of offline working stores data in a local database -that is stored on-disk, if an attacker has physical access to the device they -will be able to access the data stored there. The database used, IndexedDb, does -not provide security measures to mitigate this kind of attack. - -As this attack requires physical access, we do consider it partially mitigated, -however there is still residual risk, as described above. We are designing the -service to mitigate the residual risk by implementing a user-provided password -which will be used to encrypt the data before writing it to disk. This approach -involves a non-insignificant burden on the user and the feature is still being -designed. Once we have this designed we will update this documentation. - -Additionally, we will remove the data from the database stored on disk once the -vaccination data has been sent (via POST) to the server. - -==== Remote root access to device - -.Attack vectors -* Malicious actor gains root access to the computer used by the SAIS user, - either through phishing or other attacks. - -If a malicious actor gains root access to a relevant device, there is already -the risk that they would be able to access the service website by piggy-backing -on the SAIS user's session. For example, they may be able to access data on the -server by hijacking the users session, similar to session stealing above. - -Additionally, however, and similar to the physical access attack above, a -malicious user with remote root access may be able to find and access the data -that has been stored on disk. We plan to mitigate this the same way as we -mitigate the physical attack vector above, using encryption and removing the -data after sending it to the server. - -==== CSRF attack - -.Attack vectors -* Malicious actor posts data through the endpoint provided to clients to post - their data after offline working. - -We protect against this attack by implementing a CSRF token that is used -specifically for the offline working mechanism. This ensures that any data -posted to the server after offline working has a valid CSRF token. This attack -and our approach to protecting against it is detailed in the -link:offline-csrf-security.adoc[Offline CSRF Security doc].