From 6108345f88c817a0c0a52bff2529eb84489afac4 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Mon, 28 Aug 2023 20:19:31 -0700 Subject: [PATCH 01/22] Get basic infra for service workers and notifications up --- web_patient/package.json | 7 +- .../service-worker/serviceWorkerWorkbox.ts | 69 + web_patient/src/index.tsx | 6 +- web_patient/src/serviceWorkerRegistration.ts | 130 ++ web_patient/tsconfig.json | 2 +- web_patient/webpack/paths.js | 1 + web_patient/webpack/webpack.common.js | 7 + web_patient/yarn.lock | 2051 ++++++++++++++++- 8 files changed, 2245 insertions(+), 28 deletions(-) create mode 100644 web_patient/service-worker/serviceWorkerWorkbox.ts create mode 100644 web_patient/src/serviceWorkerRegistration.ts diff --git a/web_patient/package.json b/web_patient/package.json index eb999e43..e99ab4bc 100644 --- a/web_patient/package.json +++ b/web_patient/package.json @@ -25,7 +25,9 @@ "react-router": "6.2.x", "react-router-dom": "6.2.x", "styled-components": "5.3.3", - "url": "^0.11.0" + "url": "^0.11.0", + "workbox-precaching": "*", + "workbox-routing": "*" }, "@comment devDependencies": [], "devDependencies": { @@ -52,7 +54,8 @@ "webpack-cli": "5.x", "webpack-dev-middleware": "6.x", "webpack-hot-middleware": "2.x", - "webpack-merge": "5.x" + "webpack-merge": "5.x", + "workbox-webpack-plugin": "*" }, "scripts": { "start": "npm run dev_serve", diff --git a/web_patient/service-worker/serviceWorkerWorkbox.ts b/web_patient/service-worker/serviceWorkerWorkbox.ts new file mode 100644 index 00000000..6990c972 --- /dev/null +++ b/web_patient/service-worker/serviceWorkerWorkbox.ts @@ -0,0 +1,69 @@ +/// +import { createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching'; +import { registerRoute, NavigationRoute } from 'workbox-routing'; + +import { skipWaiting, clientsClaim } from 'workbox-core'; + +// ServiceWorkerGlobalScope is a type from the workbox-precaching module +declare const self: Window & ServiceWorkerGlobalScope; + +// tells the Service Worker to skip the waiting state and become active. +skipWaiting(); +clientsClaim(); + +precacheAndRoute(self.__WB_MANIFEST); + +const handler = createHandlerBoundToURL('/index.html'); +const navigationRoute = new NavigationRoute(handler, { + denylist: [/^\/_/, /\/[^/?]+\.[^/]+$/], +}); +registerRoute(navigationRoute); + +// @link https://flaviocopes.com/push-api/ +// @link https://web.dev/push-notifications-handling-messages/ +self.addEventListener('push', function (event) { + if (!event.data) { + console.log('This push event has no data.'); + return; + } + if (!self.registration) { + console.log('Service worker does not control the page'); + return; + } + if (!self.registration || !self.registration.pushManager) { + console.log('Push is not supported'); + return; + } + + const eventText = event.data.text(); + // Specify default options + let options = {}; + let title = ''; + + // Support both plain text notification and json + if (eventText.substr(0, 1) === '{') { + const eventData = JSON.parse(eventText); + title = eventData.title; + + // Set specific options + // @link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification#parameters + if (eventData.options) { + options = Object.assign(options, eventData.options); + } + + // Check expiration if specified + if (eventData.expires && Date.now() > eventData.expires) { + console.log('Push notification has expired'); + return; + } + } else { + title = eventText; + } + + // Warning: this can fail silently if notifications are disabled at system level + // The promise itself resolve to undefined and is not helpful to see if it has been displayed properly + const promiseChain = self.registration.showNotification(title, options); + + // With this, the browser will keep the service worker running until the promise you passed in has settled. + event.waitUntil(promiseChain); +}); diff --git a/web_patient/src/index.tsx b/web_patient/src/index.tsx index 99290507..1cb63009 100644 --- a/web_patient/src/index.tsx +++ b/web_patient/src/index.tsx @@ -9,6 +9,8 @@ import App from 'src/App'; import createAppTheme from 'src/styles/theme'; import { isDev } from 'shared/env'; +import * as serviceWorkerRegistration from './serviceWorkerRegistration'; + declare module '@mui/styles/defaultTheme' { // eslint-disable-next-line @typescript-eslint/no-empty-interface interface DefaultTheme extends Theme {} @@ -38,9 +40,11 @@ ReactDOM.render( , - document.getElementById('root') + document.getElementById('root'), ); +serviceWorkerRegistration.register(); + // Enable hot reloading declare let module: any; diff --git a/web_patient/src/serviceWorkerRegistration.ts b/web_patient/src/serviceWorkerRegistration.ts new file mode 100644 index 00000000..e0648189 --- /dev/null +++ b/web_patient/src/serviceWorkerRegistration.ts @@ -0,0 +1,130 @@ +// This optional code is used to register a service worker. +// register() is not called by default. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on subsequent visits to a page, after all the +// existing tabs open on the page have been closed, since previously cached +// resources are updated in the background. + +// To learn more about the benefits of this model and instructions on how to +// opt-in, read https://cra.link/PWA + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/), +); + +type Config = { + onSuccess?: (registration: ServiceWorkerRegistration) => void; + onUpdate?: (registration: ServiceWorkerRegistration) => void; +}; + +export function register(config?: Config) { + window.addEventListener('load', () => { + const swUrl = '/service-worker.js'; + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + // eslint-disable-next-line + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://bit.ly/CRA-PWA', + ); + }); + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config); + } + }); +} + +function registerValidSW(swUrl: string, config?: Config) { + navigator.serviceWorker + .register(swUrl) + .then((registration) => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + //console.log(installingWorker); + if (installingWorker == null) { + return; + } + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See https://cra.link/PWA.', + ); + + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration); + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.AnantMittal'); + + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration); + } + } + } + }; + }; + }) + .catch((error) => { + console.error('Error during service worker registration:', error); + }); +} + +function checkValidServiceWorker(swUrl: string, config?: Config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl, { + headers: { 'Service-Worker': 'script' }, + }) + .then((response) => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get('content-type'); + if (response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1)) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then((registration) => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config); + } + }) + .catch(() => { + console.log('No internet connection found. App is running in offline mode.'); + }); +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready + .then((registration) => { + registration.unregister(); + }) + .catch((error) => { + console.error(error.message); + }); + } +} diff --git a/web_patient/tsconfig.json b/web_patient/tsconfig.json index a0ae31f5..de8456ef 100644 --- a/web_patient/tsconfig.json +++ b/web_patient/tsconfig.json @@ -8,7 +8,7 @@ "experimentalDecorators": true, "forceConsistentCasingInFileNames": true, "jsx": "react", - "lib": ["ES2020.Promise", "DOM"], // Necessary for accessing window, document, promise for service worker + "lib": ["ES2020.Promise", "DOM", "webworker"], // Necessary for accessing window, document, promise for service worker "moduleResolution": "node", "noImplicitAny": true, "noImplicitThis": true, diff --git a/web_patient/webpack/paths.js b/web_patient/webpack/paths.js index 42ef76be..18602ae7 100644 --- a/web_patient/webpack/paths.js +++ b/web_patient/webpack/paths.js @@ -9,6 +9,7 @@ module.exports = { appBuildProd: resolveProject('dist'), appIndex: resolveProject('src/index.tsx'), appIndexTemplate: resolveProject('public/index.html'), + serviceWorkerWorkbox: resolveProject('service-worker/serviceWorkerWorkbox.ts'), tsconfig: resolveProject('tsconfig.json'), webpackConfigDev: resolveProject('webpack/webpack.dev.js'), webpackConfigProd: resolveProject('webpack/webpack.prod.js'), diff --git a/web_patient/webpack/webpack.common.js b/web_patient/webpack/webpack.common.js index 65ede054..7926b8d1 100644 --- a/web_patient/webpack/webpack.common.js +++ b/web_patient/webpack/webpack.common.js @@ -3,6 +3,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); +const { InjectManifest } = require('workbox-webpack-plugin'); module.exports = { entry: { @@ -61,5 +62,11 @@ module.exports = { new CopyWebpackPlugin({ patterns: [{ from: 'src/assets/pwa', to: '' }], }), + new InjectManifest({ + swSrc: paths.serviceWorkerWorkbox, + // this is the output of the plugin, + // relative to webpack's output directory + swDest: 'service-worker.js', + }), ], }; diff --git a/web_patient/yarn.lock b/web_patient/yarn.lock index 816c3b3c..c501bd41 100644 --- a/web_patient/yarn.lock +++ b/web_patient/yarn.lock @@ -2,6 +2,31 @@ # yarn lockfile v1 +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@apideck/better-ajv-errors@^0.3.1": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz#957d4c28e886a64a8141f7522783be65733ff097" + integrity sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA== + dependencies: + json-schema "^0.4.0" + jsonpointer "^5.0.0" + leven "^3.1.0" + +"@babel/code-frame@^7.10.4", "@babel/code-frame@^7.22.10", "@babel/code-frame@^7.22.5": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.10.tgz#1c20e612b768fefa75f6e90d6ecb86329247f0a3" + integrity sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA== + dependencies: + "@babel/highlight" "^7.22.10" + chalk "^2.4.2" + "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" @@ -14,6 +39,11 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== +"@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== + "@babel/core@7.12.x": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.17.tgz#993c5e893333107a2815d8e0d73a2c3755e280b2" @@ -35,6 +65,27 @@ semver "^5.4.1" source-map "^0.5.0" +"@babel/core@^7.11.1": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.10.tgz#aad442c7bcd1582252cb4576747ace35bc122f35" + integrity sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.10" + "@babel/generator" "^7.22.10" + "@babel/helper-compilation-targets" "^7.22.10" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.10" + "@babel/parser" "^7.22.10" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.10" + "@babel/types" "^7.22.10" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.1" + "@babel/generator@^7.12.17", "@babel/generator@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" @@ -44,6 +95,16 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.10.tgz#c92254361f398e160645ac58831069707382b722" + integrity sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A== + dependencies: + "@babel/types" "^7.22.10" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.16.0", "@babel/helper-annotate-as-pure@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" @@ -51,6 +112,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" @@ -59,6 +127,13 @@ "@babel/helper-explode-assignable-expression" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.10.tgz#573e735937e99ea75ea30788b57eb52fab7468c9" + integrity sha512-Av0qubwDQxC56DoUReVDeLfMEjYYSN1nZrTUrWkXd7hpU73ymRANkbuDm3yni9npkn+RXy9nNbEJZEzXr7xrfQ== + dependencies: + "@babel/types" "^7.22.10" + "@babel/helper-compilation-targets@^7.12.17", "@babel/helper-compilation-targets@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" @@ -69,6 +144,17 @@ browserslist "^4.17.5" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.22.10", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz#01d648bbc25dd88f513d862ee0df27b7d4e67024" + integrity sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7": version "7.16.10" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz#8a6959b9cc818a88815ba3c5474619e9c0f2c21c" @@ -82,6 +168,21 @@ "@babel/helper-replace-supers" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" +"@babel/helper-create-class-features-plugin@^7.22.5": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.10.tgz#dd2612d59eac45588021ac3d6fa976d08f4e95a3" + integrity sha512-5IBb77txKYQPpOEdUdIhBx8VrZyDCQ+H82H0+5dX1TmuscP5vJKEE3cKurjtIw/vFwzbVH48VweE78kVDBrqjA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + "@babel/helper-create-regexp-features-plugin@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz#0cb82b9bac358eb73bfbd73985a776bfa6b14d48" @@ -90,6 +191,26 @@ "@babel/helper-annotate-as-pure" "^7.16.7" regexpu-core "^4.7.1" +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" + integrity sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz#82c825cadeeeee7aad237618ebbe8fa1710015d7" + integrity sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + "@babel/helper-environment-visitor@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" @@ -97,6 +218,11 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + "@babel/helper-explode-assignable-expression@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" @@ -113,6 +239,14 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + "@babel/helper-get-function-arity@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" @@ -127,6 +261,13 @@ dependencies: "@babel/types" "^7.16.7" +"@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" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-member-expression-to-functions@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" @@ -134,6 +275,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-member-expression-to-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz#0a7c56117cad3372fbf8d2fb4bf8f8d64a1e76b2" + integrity sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.0", "@babel/helper-module-imports@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" @@ -141,6 +289,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-module-transforms@^7.12.17", "@babel/helper-module-transforms@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" @@ -155,6 +310,17 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.5" + "@babel/helper-optimise-call-expression@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" @@ -162,11 +328,23 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + "@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.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== +"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + "@babel/helper-remap-async-to-generator@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" @@ -176,6 +354,15 @@ "@babel/helper-wrap-function" "^7.16.8" "@babel/types" "^7.16.8" +"@babel/helper-remap-async-to-generator@^7.22.5", "@babel/helper-remap-async-to-generator@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82" + integrity sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-wrap-function" "^7.22.9" + "@babel/helper-replace-supers@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" @@ -187,6 +374,15 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz#cbdc27d6d8d18cd22c81ae4293765a5d9afd0779" + integrity sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-simple-access@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" @@ -194,6 +390,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" @@ -201,6 +404,13 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-split-export-declaration@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" @@ -208,16 +418,38 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + "@babel/helper-validator-option@^7.12.17", "@babel/helper-validator-option@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + "@babel/helper-wrap-function@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" @@ -228,6 +460,15 @@ "@babel/traverse" "^7.16.8" "@babel/types" "^7.16.8" +"@babel/helper-wrap-function@^7.22.9": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz#d845e043880ed0b8c18bd194a12005cb16d2f614" + integrity sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.10" + "@babel/helpers@^7.12.17": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc" @@ -237,6 +478,15 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helpers@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.10.tgz#ae6005c539dfbcb5cd71fb51bfc8a52ba63bc37a" + integrity sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.10" + "@babel/types" "^7.22.10" + "@babel/highlight@^7.16.7": version "7.16.10" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" @@ -246,11 +496,41 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.10.tgz#02a3f6d8c1cb4521b2fd0ab0da8f4739936137d7" + integrity sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.4.2" + js-tokens "^4.0.0" + "@babel/parser@^7.12.17", "@babel/parser@^7.16.10", "@babel/parser@^7.16.7": version "7.16.12" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6" integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A== +"@babel/parser@^7.22.10", "@babel/parser@^7.22.5": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" + integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e" + integrity sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz#fef09f9499b1f1c930da8a0c419db42167d792ca" + integrity sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.5" + "@babel/plugin-proposal-async-generator-functions@^7.12.13": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" @@ -352,6 +632,11 @@ "@babel/helper-create-class-features-plugin" "^7.16.10" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + "@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" @@ -374,6 +659,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" @@ -388,6 +680,27 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" +"@babel/plugin-syntax-import-assertions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" + integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-attributes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" + integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings@^7.8.0", "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" @@ -444,13 +757,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.12.13": +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.12.13", "@babel/plugin-syntax-top-level-await@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-arrow-functions@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" @@ -458,6 +786,23 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-arrow-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" + integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-async-generator-functions@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.10.tgz#45946cd17f915b10e65c29b8ed18a0a50fc648c8" + integrity sha512-eueE8lvKVzq5wIObKK/7dvoeKJ+xc6TvRn6aysIjS6pSCeLy7S/eVi7pEQknZqyqvzaNKdDtem8nUNTBgDVR2g== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.9" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-transform-async-to-generator@^7.12.13": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" @@ -467,6 +812,15 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-remap-async-to-generator" "^7.16.8" +"@babel/plugin-transform-async-to-generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" + integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== + dependencies: + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" + "@babel/plugin-transform-block-scoped-functions@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" @@ -474,6 +828,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-block-scoped-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" + integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-block-scoping@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" @@ -481,6 +842,30 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-block-scoping@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.10.tgz#88a1dccc3383899eb5e660534a76a22ecee64faa" + integrity sha512-1+kVpGAOOI1Albt6Vse7c8pHzcZQdQKW+wJH+g8mCaszOdDVwRXa/slHPqIw+oJAJANTKDMuM2cBdV0Dg618Vg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" + integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-static-block@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz#3e40c46f048403472d6f4183116d5e46b1bff5ba" + integrity sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-transform-classes@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" @@ -495,6 +880,21 @@ "@babel/helper-split-export-declaration" "^7.16.7" globals "^11.1.0" +"@babel/plugin-transform-classes@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz#e04d7d804ed5b8501311293d1a0e6d43e94c3363" + integrity sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + globals "^11.1.0" + "@babel/plugin-transform-computed-properties@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" @@ -502,6 +902,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-computed-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" + integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/plugin-transform-destructuring@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz#ca9588ae2d63978a4c29d3f33282d8603f618e23" @@ -509,6 +917,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-destructuring@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.10.tgz#38e2273814a58c810b6c34ea293be4973c4eb5e2" + integrity sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" @@ -517,6 +932,14 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-dotall-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" + integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-duplicate-keys@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" @@ -524,6 +947,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-duplicate-keys@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" + integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-dynamic-import@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz#d6908a8916a810468c4edff73b5b75bda6ad393e" + integrity sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-exponentiation-operator@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" @@ -532,6 +970,22 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-exponentiation-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" + integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-export-namespace-from@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz#57c41cb1d0613d22f548fddd8b288eedb9973a5b" + integrity sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-transform-for-of@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" @@ -539,6 +993,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-for-of@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz#ab1b8a200a8f990137aff9a084f8de4099ab173f" + integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-function-name@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" @@ -548,6 +1009,23 @@ "@babel/helper-function-name" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" + integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== + dependencies: + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-json-strings@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz#14b64352fdf7e1f737eed68de1a1468bd2a77ec0" + integrity sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-transform-literals@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" @@ -555,6 +1033,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" + integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-logical-assignment-operators@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz#66ae5f068fd5a9a5dc570df16f56c2a8462a9d6c" + integrity sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-transform-member-expression-literals@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" @@ -562,6 +1055,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-member-expression-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" + integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-modules-amd@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" @@ -571,6 +1071,14 @@ "@babel/helper-plugin-utils" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-amd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz#4e045f55dcf98afd00f85691a68fc0780704f526" + integrity sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ== + dependencies: + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-modules-commonjs@^7.12.13": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe" @@ -581,6 +1089,15 @@ "@babel/helper-simple-access" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-commonjs@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz#7d9875908d19b8c0536085af7b053fd5bd651bfa" + integrity sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA== + dependencies: + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/plugin-transform-modules-systemjs@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7" @@ -592,6 +1109,16 @@ "@babel/helper-validator-identifier" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-systemjs@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz#18c31410b5e579a0092638f95c896c2a98a5d496" + integrity sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ== + dependencies: + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + "@babel/plugin-transform-modules-umd@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" @@ -600,6 +1127,14 @@ "@babel/helper-module-transforms" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-modules-umd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" + integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== + dependencies: + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" @@ -607,6 +1142,14 @@ dependencies: "@babel/helper-create-regexp-features-plugin" "^7.16.7" +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-new-target@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" @@ -614,6 +1157,40 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-new-target@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" + integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz#f8872c65776e0b552e0849d7596cddd416c3e381" + integrity sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz#57226a2ed9e512b9b446517ab6fa2d17abb83f58" + integrity sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-object-rest-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz#9686dc3447df4753b0b2a2fae7e8bc33cdc1f2e1" + integrity sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ== + dependencies: + "@babel/compat-data" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.22.5" + "@babel/plugin-transform-object-super@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" @@ -622,6 +1199,31 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-replace-supers" "^7.16.7" +"@babel/plugin-transform-object-super@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" + integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + +"@babel/plugin-transform-optional-catch-binding@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz#842080be3076703be0eaf32ead6ac8174edee333" + integrity sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.22.10", "@babel/plugin-transform-optional-chaining@^7.22.5": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.10.tgz#076d28a7e074392e840d4ae587d83445bac0372a" + integrity sha512-MMkQqZAZ+MGj+jGTG3OTuhKeBpNcO+0oCEbrGNEaOmiEn+1MzRyQlYsruGiU8RTK3zV6XwrVJTmwiDOyYK6J9g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-transform-parameters@^7.12.13", "@babel/plugin-transform-parameters@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" @@ -629,6 +1231,31 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-parameters@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz#c3542dd3c39b42c8069936e48717a8d179d63a18" + integrity sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-methods@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" + integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-property-in-object@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz#07a77f28cbb251546a43d175a1dda4cf3ef83e32" + integrity sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-transform-property-literals@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" @@ -636,6 +1263,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-property-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" + integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-react-display-name@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz#7b6d40d232f4c0f550ea348593db3b21e2404340" @@ -676,6 +1310,14 @@ dependencies: regenerator-transform "^0.14.2" +"@babel/plugin-transform-regenerator@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" + integrity sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.2" + "@babel/plugin-transform-reserved-words@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" @@ -683,6 +1325,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-reserved-words@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" + integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-shorthand-properties@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" @@ -690,6 +1339,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-shorthand-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" + integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-spread@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" @@ -698,6 +1354,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" +"@babel/plugin-transform-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" + integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-sticky-regex@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" @@ -705,6 +1369,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-sticky-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" + integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-template-literals@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" @@ -712,6 +1383,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-template-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" + integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-typeof-symbol@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" @@ -719,6 +1397,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-typeof-symbol@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" + integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-unicode-escapes@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" @@ -726,6 +1411,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-unicode-escapes@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9" + integrity sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-property-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" + integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-unicode-regex@^7.12.13": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" @@ -734,6 +1434,22 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-unicode-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" + integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-sets-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" + integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/polyfill@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.12.1.tgz#1f2d6371d1261bbd961f3c5d5909150e12d0bd96" @@ -814,6 +1530,101 @@ core-js-compat "^3.8.0" semver "^5.5.0" +"@babel/preset-env@^7.11.0": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.10.tgz#3263b9fe2c8823d191d28e61eac60a79f9ce8a0f" + integrity sha512-riHpLb1drNkpLlocmSyEg4oYJIQFeXAK/d7rI6mbD0XsvoTOOweXDmQPG/ErxsEhWk3rl3Q/3F6RFQlVFS8m0A== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.10" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.5" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.5" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@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.22.5" + "@babel/plugin-syntax-import-attributes" "^7.22.5" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@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-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.22.5" + "@babel/plugin-transform-async-generator-functions" "^7.22.10" + "@babel/plugin-transform-async-to-generator" "^7.22.5" + "@babel/plugin-transform-block-scoped-functions" "^7.22.5" + "@babel/plugin-transform-block-scoping" "^7.22.10" + "@babel/plugin-transform-class-properties" "^7.22.5" + "@babel/plugin-transform-class-static-block" "^7.22.5" + "@babel/plugin-transform-classes" "^7.22.6" + "@babel/plugin-transform-computed-properties" "^7.22.5" + "@babel/plugin-transform-destructuring" "^7.22.10" + "@babel/plugin-transform-dotall-regex" "^7.22.5" + "@babel/plugin-transform-duplicate-keys" "^7.22.5" + "@babel/plugin-transform-dynamic-import" "^7.22.5" + "@babel/plugin-transform-exponentiation-operator" "^7.22.5" + "@babel/plugin-transform-export-namespace-from" "^7.22.5" + "@babel/plugin-transform-for-of" "^7.22.5" + "@babel/plugin-transform-function-name" "^7.22.5" + "@babel/plugin-transform-json-strings" "^7.22.5" + "@babel/plugin-transform-literals" "^7.22.5" + "@babel/plugin-transform-logical-assignment-operators" "^7.22.5" + "@babel/plugin-transform-member-expression-literals" "^7.22.5" + "@babel/plugin-transform-modules-amd" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.5" + "@babel/plugin-transform-modules-systemjs" "^7.22.5" + "@babel/plugin-transform-modules-umd" "^7.22.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.22.5" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.5" + "@babel/plugin-transform-numeric-separator" "^7.22.5" + "@babel/plugin-transform-object-rest-spread" "^7.22.5" + "@babel/plugin-transform-object-super" "^7.22.5" + "@babel/plugin-transform-optional-catch-binding" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.10" + "@babel/plugin-transform-parameters" "^7.22.5" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/plugin-transform-private-property-in-object" "^7.22.5" + "@babel/plugin-transform-property-literals" "^7.22.5" + "@babel/plugin-transform-regenerator" "^7.22.10" + "@babel/plugin-transform-reserved-words" "^7.22.5" + "@babel/plugin-transform-shorthand-properties" "^7.22.5" + "@babel/plugin-transform-spread" "^7.22.5" + "@babel/plugin-transform-sticky-regex" "^7.22.5" + "@babel/plugin-transform-template-literals" "^7.22.5" + "@babel/plugin-transform-typeof-symbol" "^7.22.5" + "@babel/plugin-transform-unicode-escapes" "^7.22.10" + "@babel/plugin-transform-unicode-property-regex" "^7.22.5" + "@babel/plugin-transform-unicode-regex" "^7.22.5" + "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" + "@babel/preset-modules" "0.1.6-no-external-plugins" + "@babel/types" "^7.22.10" + babel-plugin-polyfill-corejs2 "^0.4.5" + babel-plugin-polyfill-corejs3 "^0.8.3" + babel-plugin-polyfill-regenerator "^0.5.2" + core-js-compat "^3.31.0" + semver "^6.3.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + "@babel/preset-modules@^0.1.3": version "0.1.5" resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" @@ -836,6 +1647,18 @@ "@babel/plugin-transform-react-jsx-development" "^7.12.12" "@babel/plugin-transform-react-pure-annotations" "^7.12.1" +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + +"@babel/runtime@^7.11.2": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682" + integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.16.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" @@ -852,6 +1675,15 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/template@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + "@babel/traverse@^7.12.17", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.4.5": version "7.16.10" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f" @@ -868,6 +1700,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.10.tgz#20252acb240e746d27c2e82b4484f199cf8141aa" + integrity sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig== + dependencies: + "@babel/code-frame" "^7.22.10" + "@babel/generator" "^7.22.10" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.10" + "@babel/types" "^7.22.10" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.12.17", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.4.4": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" @@ -876,6 +1724,15 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.22.10", "@babel/types@^7.22.5": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" + integrity sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + "@date-io/core@^1.3.13": version "1.3.13" resolved "https://registry.yarnpkg.com/@date-io/core/-/core-1.3.13.tgz#90c71da493f20204b7a972929cc5c482d078b3fa" @@ -965,7 +1822,7 @@ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== -"@jridgewell/gen-mapping@^0.3.0": +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== @@ -1163,6 +2020,53 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.2.tgz#830beaec4b4091a9e9398ac50f865ddea52186b9" integrity sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA== +"@rollup/plugin-babel@^5.2.0": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" + integrity sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@rollup/pluginutils" "^3.1.0" + +"@rollup/plugin-node-resolve@^11.2.1": + version "11.2.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60" + integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/plugin-replace@^2.4.1": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz#a2d539314fbc77c244858faa523012825068510a" + integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + magic-string "^0.25.7" + +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + +"@surma/rollup-plugin-off-main-thread@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz#ee34985952ca21558ab0d952f00298ad2190c053" + 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" + "@types/eslint-scope@^3.7.3": version "3.7.4" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" @@ -1184,6 +2088,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + "@types/estree@^1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" @@ -1305,6 +2214,13 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + "@types/scheduler@*": version "0.16.2" resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" @@ -1319,6 +2235,11 @@ "@types/react" "*" csstype "^3.0.2" +"@types/trusted-types@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311" + integrity sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g== + "@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": version "1.11.6" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" @@ -1512,7 +2433,7 @@ ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.6.0, ajv@^8.9.0: version "8.12.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== @@ -1557,6 +2478,14 @@ ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -1567,6 +2496,33 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +arraybuffer.prototype.slice@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" + integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + +async@^3.2.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + axios@0.25.x: version "0.25.0" resolved "https://registry.yarnpkg.com/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a" @@ -1591,6 +2547,30 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" +babel-plugin-polyfill-corejs2@^0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz#8097b4cb4af5b64a1d11332b6fb72ef5e64a054c" + integrity sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.2" + semver "^6.3.1" + +babel-plugin-polyfill-corejs3@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz#b4f719d0ad9bb8e0c23e3e630c0c8ec6dd7a1c52" + integrity sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.2" + core-js-compat "^3.31.0" + +babel-plugin-polyfill-regenerator@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz#80d0f3e1098c080c8b5a65f41e9427af692dc326" + integrity sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.2" + "babel-plugin-styled-components@>= 1.12.0": version "2.0.2" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.2.tgz#0fac11402dc9db73698b55847ab1dc73f5197c54" @@ -1650,8 +2630,15 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.1: - version "3.0.2" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.1: + version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: @@ -1668,6 +2655,16 @@ browserslist@^4.14.5, browserslist@^4.17.5, browserslist@^4.19.1: node-releases "^2.0.1" picocolors "^1.0.0" +browserslist@^4.21.10, browserslist@^4.21.9: + version "4.21.10" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" + integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== + dependencies: + caniuse-lite "^1.0.30001517" + electron-to-chromium "^1.4.477" + node-releases "^2.0.13" + update-browserslist-db "^1.0.11" + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -1682,12 +2679,17 @@ buffer@4.9.2: ieee754 "^1.1.4" isarray "^1.0.0" +builtin-modules@^3.1.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== + bytes@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== -call-bind@^1.0.0: +call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== @@ -1713,7 +2715,12 @@ caniuse-lite@^1.0.30001286: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001304.tgz#38af55ed3fc8220cb13e35e6e7309c8c65a05559" integrity sha512-bdsfZd6K6ap87AGqSHJP/s1V+U6Z5lyrcbBu3ovbCCf8cSYpwTtGrCBObMpJqwxfTbLW6YTIdbb1jEeTelcpYQ== -chalk@^2.0.0: +caniuse-lite@^1.0.30001517: + version "1.0.30001522" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz#44b87a406c901269adcdb834713e23582dd71856" + integrity sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg== + +chalk@^2.0.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1722,7 +2729,7 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0: +chalk@^4.0.2, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -1800,6 +2807,11 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +common-tags@^1.8.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1851,6 +2863,13 @@ copy-webpack-plugin@^9.0.1: schema-utils "^3.1.1" serialize-javascript "^6.0.0" +core-js-compat@^3.31.0: + version "3.32.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.1.tgz#55f9a7d297c0761a8eb1d31b593e0f5b6ffae964" + integrity sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA== + dependencies: + browserslist "^4.21.10" + core-js-compat@^3.8.0: version "3.20.3" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.3.tgz#d71f85f94eb5e4bea3407412e549daa083d23bd6" @@ -1883,6 +2902,11 @@ crypto-js@^4.1.1: resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + css-color-keywords@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" @@ -1945,6 +2969,18 @@ debug@^4.1.0: dependencies: ms "2.1.2" +debug@^4.1.1: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deepmerge@^4.2.2: + 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: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -1952,6 +2988,14 @@ define-properties@^1.1.3: dependencies: object-keys "^1.0.12" +define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -2027,11 +3071,23 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +ejs@^3.1.6: + version "3.1.9" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + dependencies: + jake "^10.8.5" + electron-to-chromium@^1.4.17: version "1.4.58" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.58.tgz#cd980b08338210b591c25492857a518fe286b1d4" integrity sha512-7LXwnKyqcEaMFVXOer+2JPfFs1D+ej7yRRrfZoIH1YlLQZ81OvBNwSCBBLtExVkoMQQgOWwO0FbZVge6U/8rhQ== +electron-to-chromium@^1.4.477: + version "1.4.499" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.499.tgz#dc36b67f4c8e273524e8d2080c5203a6a76987b6" + integrity sha512-0NmjlYBLKVHva4GABWAaHuPJolnDuL0AhV3h1hES6rcLCWEIbRL6/8TghfsVwkx6TEroQVdliX7+aLysUpKvjw== + emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" @@ -2084,11 +3140,74 @@ errno@^0.1.3: dependencies: prr "~1.0.1" +es-abstract@^1.19.0, es-abstract@^1.20.4: + version "1.22.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" + integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== + dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.1" + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.2.1" + 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.5" + is-array-buffer "^3.0.2" + 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.3" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.0" + safe-array-concat "^1.0.0" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.7" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.10" + es-module-lexer@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f" integrity sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA== +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + 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.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -2129,6 +3248,11 @@ estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -2201,7 +3325,7 @@ fast-glob@^3.2.7, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -2218,6 +3342,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -2260,6 +3391,13 @@ follow-redirects@^1.14.7: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -2270,6 +3408,16 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + 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-monkey@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.4.tgz#ee8c1b53d3fe8bb7e5d2c5c5dfc0168afdd2f747" @@ -2280,12 +3428,32 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@~2.3.2: + version "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.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -gensync@^1.0.0-beta.1: +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + 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, functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== @@ -2299,6 +3467,29 @@ get-intrinsic@^1.0.2: has "^1.0.3" has-symbols "^1.0.1" +get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-proto "^1.0.1" + has-symbols "^1.0.3" + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -2330,11 +3521,30 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + globby@^11.0.3: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -2347,11 +3557,28 @@ globby@^11.0.3: merge2 "^1.4.1" slash "^3.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.9" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + 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.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2362,11 +3589,35 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + has-symbols@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -2455,6 +3706,11 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +idb@^7.0.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" + integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== + ieee754@^1.1.4: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -2486,6 +3742,15 @@ inherits@2, inherits@2.0.4, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +internal-slot@^1.0.3, internal-slot@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + dependencies: + get-intrinsic "^1.2.0" + has "^1.0.3" + side-channel "^1.0.4" + interpret@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" @@ -2496,6 +3761,35 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + is-core-module@^2.11.0: version "2.12.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" @@ -2503,6 +3797,20 @@ is-core-module@^2.11.0: dependencies: has "^1.0.3" +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -2520,11 +3828,33 @@ is-in-browser@^1.0.2, is-in-browser@^1.1.3: resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" integrity sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU= +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== + 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" @@ -2532,11 +3862,69 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + 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.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + 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.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + 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.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2555,6 +3943,25 @@ isomorphic-unfetch@^3.0.0: node-fetch "^2.6.1" unfetch "^4.2.0" +jake@^10.8.5: + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + jest-worker@^27.4.5: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" @@ -2599,6 +4006,11 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== +json-schema@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + json5@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" @@ -2613,6 +4025,25 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +json5@^2.2.0, json5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + 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.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" + integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== + jss-plugin-camel-case@^10.8.2: version "10.9.0" resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.9.0.tgz#4921b568b38d893f39736ee8c4c5f1c64670aaf7" @@ -2688,6 +4119,11 @@ kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + loader-runner@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" @@ -2718,11 +4154,16 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash.debounce@4.0.8: +lodash.debounce@4.0.8, lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + lodash.throttle@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" @@ -2754,6 +4195,13 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -2761,6 +4209,13 @@ 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.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -2852,6 +4307,20 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -2919,6 +4388,11 @@ node-releases@^2.0.1: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + normalize-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -2936,6 +4410,11 @@ object-assign@^4.1.1: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= +object-inspect@^1.12.3, object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -2951,6 +4430,16 @@ object.assign@^4.1.0: has-symbols "^1.0.1" object-keys "^1.1.1" +object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + 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" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -3040,7 +4529,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.2.3: +picomatch@^2.2.2, picomatch@^2.2.3: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -3057,6 +4546,11 @@ postcss-value-parser@^4.0.2: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== +pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== + pretty-error@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" @@ -3211,6 +4705,13 @@ rechoir@^0.8.0: dependencies: resolve "^1.20.0" +regenerate-unicode-properties@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" + integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" @@ -3228,6 +4729,11 @@ regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + regenerator-transform@^0.14.2: version "0.14.5" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" @@ -3235,6 +4741,22 @@ regenerator-transform@^0.14.2: dependencies: "@babel/runtime" "^7.8.4" +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== + dependencies: + "@babel/runtime" "^7.8.4" + +regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" + integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + functions-have-names "^1.2.3" + regexpu-core@^4.7.1: version "4.8.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0" @@ -3247,6 +4769,18 @@ regexpu-core@^4.7.1: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== + dependencies: + "@babel/regjsgen" "^0.8.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + regjsgen@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" @@ -3259,6 +4793,13 @@ regjsparser@^0.7.0: dependencies: jsesc "~0.5.0" +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" @@ -3292,6 +4833,15 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve@^1.14.2, resolve@^1.19.0: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@^1.20.0: version "1.22.2" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" @@ -3318,6 +4868,23 @@ rimraf@3.0.x: dependencies: glob "^7.1.3" +rollup-plugin-terser@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" + integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== + dependencies: + "@babel/code-frame" "^7.10.4" + jest-worker "^26.2.1" + serialize-javascript "^4.0.0" + terser "^5.0.0" + +rollup@^2.43.1: + version "2.79.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== + optionalDependencies: + fsevents "~2.3.2" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -3325,6 +4892,16 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +safe-array-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" + integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@5.2.1, safe-buffer@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -3335,6 +4912,15 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -3400,6 +4986,11 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +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== + semver@^7.3.4: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" @@ -3426,6 +5017,13 @@ send@0.17.2: range-parser "~1.2.1" statuses "~1.5.0" +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + serialize-javascript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -3479,11 +5077,25 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -3497,21 +5109,74 @@ source-map@^0.5.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@~0.6.0: +source-map@^0.6.0, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@^0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + source-map@~0.7.2: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +string.prototype.matchall@^4.0.6: + version "4.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" + 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.trim@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string.prototype.trimend@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + 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.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -3519,6 +5184,15 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + 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@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -3531,6 +5205,11 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== + styled-components@5.3.3: version "5.3.3" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.3.tgz#312a3d9a549f4708f0fb0edc829eb34bde032743" @@ -3554,7 +5233,7 @@ supports-color@^5.3.0, supports-color@^5.5.0: dependencies: has-flag "^3.0.0" -supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -3583,6 +5262,21 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +temp-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" + integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== + +tempy@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.6.0.tgz#65e2c35abc06f1124a97f387b08303442bde59f3" + 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-webpack-plugin@^5.3.7: version "5.3.9" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" @@ -3594,16 +5288,7 @@ terser-webpack-plugin@^5.3.7: serialize-javascript "^6.0.1" terser "^5.16.8" -terser@^5.10.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" - integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== - dependencies: - commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.20" - -terser@^5.16.8: +terser@^5.0.0, terser@^5.16.8: version "5.19.2" resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.2.tgz#bdb8017a9a4a8de4663a7983f45c506534f9234e" integrity sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA== @@ -3613,6 +5298,15 @@ terser@^5.16.8: commander "^2.20.0" source-map-support "~0.5.20" +terser@^5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" + integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.20" + tiny-warning@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" @@ -3635,6 +5329,13 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== + dependencies: + punycode "^2.1.0" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -3675,6 +5376,11 @@ tslib@^2.0.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== +type-fest@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" + integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -3683,11 +5389,60 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + typescript@4.5.5: version "4.5.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + 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" + unfetch@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" @@ -3711,16 +5466,46 @@ unicode-match-property-value-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + unicode-property-aliases-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= +upath@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -3769,6 +5554,11 @@ webidl-conversions@^3.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + webpack-cli@5.x: version "5.1.4" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.4.tgz#c8e046ba7eaae4911d7e71e2b25b776fcc35759b" @@ -3816,6 +5606,14 @@ webpack-merge@5.x, webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" +webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" @@ -3859,6 +5657,37 @@ 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.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + 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.10, which-typed-array@^1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" + integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== + 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" + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -3871,11 +5700,185 @@ wildcard@^2.0.0: resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== +workbox-background-sync@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-7.0.0.tgz#2b84b96ca35fec976e3bd2794b70e4acec46b3a5" + integrity sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA== + dependencies: + idb "^7.0.1" + workbox-core "7.0.0" + +workbox-broadcast-update@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-7.0.0.tgz#7f611ca1a94ba8ac0aa40fa171c9713e0f937d22" + integrity sha512-oUuh4jzZrLySOo0tC0WoKiSg90bVAcnE98uW7F8GFiSOXnhogfNDGZelPJa+6KpGBO5+Qelv04Hqx2UD+BJqNQ== + dependencies: + workbox-core "7.0.0" + +workbox-build@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-7.0.0.tgz#02ab5ef2991b3369b8b9395703f08912212769b4" + integrity sha512-CttE7WCYW9sZC+nUYhQg3WzzGPr4IHmrPnjKiu3AMXsiNQKx+l4hHl63WTrnicLmKEKHScWDH8xsGBdrYgtBzg== + dependencies: + "@apideck/better-ajv-errors" "^0.3.1" + "@babel/core" "^7.11.1" + "@babel/preset-env" "^7.11.0" + "@babel/runtime" "^7.11.2" + "@rollup/plugin-babel" "^5.2.0" + "@rollup/plugin-node-resolve" "^11.2.1" + "@rollup/plugin-replace" "^2.4.1" + "@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" + rollup-plugin-terser "^7.0.0" + 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.0.0" + workbox-broadcast-update "7.0.0" + workbox-cacheable-response "7.0.0" + workbox-core "7.0.0" + workbox-expiration "7.0.0" + workbox-google-analytics "7.0.0" + workbox-navigation-preload "7.0.0" + workbox-precaching "7.0.0" + workbox-range-requests "7.0.0" + workbox-recipes "7.0.0" + workbox-routing "7.0.0" + workbox-strategies "7.0.0" + workbox-streams "7.0.0" + workbox-sw "7.0.0" + workbox-window "7.0.0" + +workbox-cacheable-response@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-7.0.0.tgz#ee27c036728189eed69d25a135013053277482d2" + integrity sha512-0lrtyGHn/LH8kKAJVOQfSu3/80WDc9Ma8ng0p2i/5HuUndGttH+mGMSvOskjOdFImLs2XZIimErp7tSOPmu/6g== + dependencies: + workbox-core "7.0.0" + +workbox-core@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-7.0.0.tgz#dec114ec923cc2adc967dd9be1b8a0bed50a3545" + integrity sha512-81JkAAZtfVP8darBpfRTovHg8DGAVrKFgHpOArZbdFd78VqHr5Iw65f2guwjE2NlCFbPFDoez3D3/6ZvhI/rwQ== + +workbox-expiration@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-7.0.0.tgz#3d90bcf2a7577241de950f89784f6546b66c2baa" + integrity sha512-MLK+fogW+pC3IWU9SFE+FRStvDVutwJMR5if1g7oBJx3qwmO69BNoJQVaMXq41R0gg3MzxVfwOGKx3i9P6sOLQ== + dependencies: + idb "^7.0.1" + workbox-core "7.0.0" + +workbox-google-analytics@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-7.0.0.tgz#603b2c4244af1e85de0fb26287d4e17d3293452a" + integrity sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg== + dependencies: + workbox-background-sync "7.0.0" + workbox-core "7.0.0" + workbox-routing "7.0.0" + workbox-strategies "7.0.0" + +workbox-navigation-preload@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-7.0.0.tgz#4913878dbbd97057181d57baa18d2bbdde085c6c" + integrity sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA== + dependencies: + workbox-core "7.0.0" + +workbox-precaching@*, workbox-precaching@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-7.0.0.tgz#3979ba8033aadf3144b70e9fe631d870d5fbaa03" + integrity sha512-EC0vol623LJqTJo1mkhD9DZmMP604vHqni3EohhQVwhJlTgyKyOkMrZNy5/QHfOby+39xqC01gv4LjOm4HSfnA== + dependencies: + workbox-core "7.0.0" + workbox-routing "7.0.0" + workbox-strategies "7.0.0" + +workbox-range-requests@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-7.0.0.tgz#97511901e043df27c1aa422adcc999a7751f52ed" + integrity sha512-SxAzoVl9j/zRU9OT5+IQs7pbJBOUOlriB8Gn9YMvi38BNZRbM+RvkujHMo8FOe9IWrqqwYgDFBfv6sk76I1yaQ== + dependencies: + workbox-core "7.0.0" + +workbox-recipes@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-7.0.0.tgz#1a6a01c8c2dfe5a41eef0fed3fe517e8a45c6514" + integrity sha512-DntcK9wuG3rYQOONWC0PejxYYIDHyWWZB/ueTbOUDQgefaeIj1kJ7pdP3LZV2lfrj8XXXBWt+JDRSw1lLLOnww== + dependencies: + workbox-cacheable-response "7.0.0" + workbox-core "7.0.0" + workbox-expiration "7.0.0" + workbox-precaching "7.0.0" + workbox-routing "7.0.0" + workbox-strategies "7.0.0" + +workbox-routing@*, workbox-routing@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-7.0.0.tgz#6668438a06554f60645aedc77244a4fe3a91e302" + integrity sha512-8YxLr3xvqidnbVeGyRGkaV4YdlKkn5qZ1LfEePW3dq+ydE73hUUJJuLmGEykW3fMX8x8mNdL0XrWgotcuZjIvA== + dependencies: + workbox-core "7.0.0" + +workbox-strategies@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-7.0.0.tgz#dcba32b3f3074476019049cc490fe1a60ea73382" + integrity sha512-dg3qJU7tR/Gcd/XXOOo7x9QoCI9nk74JopaJaYAQ+ugLi57gPsXycVdBnYbayVj34m6Y8ppPwIuecrzkpBVwbA== + dependencies: + workbox-core "7.0.0" + +workbox-streams@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-7.0.0.tgz#36722aecd04785f88b6f709e541c094fc658c0f9" + integrity sha512-moVsh+5to//l6IERWceYKGiftc+prNnqOp2sgALJJFbnNVpTXzKISlTIsrWY+ogMqt+x1oMazIdHj25kBSq/HQ== + dependencies: + workbox-core "7.0.0" + workbox-routing "7.0.0" + +workbox-sw@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-7.0.0.tgz#7350126411e3de1409f7ec243df8d06bb5b08b86" + integrity sha512-SWfEouQfjRiZ7GNABzHUKUyj8pCoe+RwjfOIajcx6J5mtgKkN+t8UToHnpaJL5UVVOf5YhJh+OHhbVNIHe+LVA== + +workbox-webpack-plugin@*: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-7.0.0.tgz#6c61661a2cacde1239192a5877a041a2943d1a55" + integrity sha512-R1ZzCHPfzeJjLK2/TpKUhxSQ3fFDCxlWxgRhhSjMQLz3G2MlBnyw/XeYb34e7SGgSv0qG22zEhMIzjMNqNeKbw== + dependencies: + fast-json-stable-stringify "^2.1.0" + pretty-bytes "^5.4.1" + upath "^1.2.0" + webpack-sources "^1.4.3" + workbox-build "7.0.0" + +workbox-window@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-7.0.0.tgz#a683ab33c896e4f16786794eac7978fc98a25d08" + integrity sha512-j7P/bsAWE/a7sxqTzXo3P2ALb1reTfZdvVp6OJ/uLr/C2kZAMvjeWGm8V4htQhor7DOvYg0sSbFN2+flT5U0qA== + dependencies: + "@types/trusted-types" "^2.0.2" + workbox-core "7.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" From 387dfa65b762c14d5c6815c9f59880044c46ba72 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Fri, 29 Sep 2023 12:28:35 -0700 Subject: [PATCH 02/22] Fixed documentdb string for mongodb compass --- tasks/documentdb.py | 93 ++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 40 deletions(-) diff --git a/tasks/documentdb.py b/tasks/documentdb.py index 8e1b06e0..731d6ea4 100644 --- a/tasks/documentdb.py +++ b/tasks/documentdb.py @@ -10,8 +10,8 @@ from invoke import task import urllib.parse -INSTANCE_SSH_CONFIG_PATH = './secrets/configuration/instance_ssh.yaml' -DOCUMENTDB_CONFIG_PATH = './secrets/configuration/documentdb.yaml' +INSTANCE_SSH_CONFIG_PATH = "./secrets/configuration/instance_ssh.yaml" +DOCUMENTDB_CONFIG_PATH = "./secrets/configuration/documentdb.yaml" @task @@ -23,66 +23,79 @@ def documentdb_forward(context): """ if aws_infrastructure.tasks.terminal.spawn_new_terminal(context): - ssh_config = aws_infrastructure.tasks.ssh.SSHConfig.load(INSTANCE_SSH_CONFIG_PATH) - documentdb_config = aws_infrastructure.tasks.library.documentdb.DocumentDBConfig.load(DOCUMENTDB_CONFIG_PATH) + ssh_config = aws_infrastructure.tasks.ssh.SSHConfig.load( + INSTANCE_SSH_CONFIG_PATH + ) + documentdb_config = ( + aws_infrastructure.tasks.library.documentdb.DocumentDBConfig.load( + DOCUMENTDB_CONFIG_PATH + ) + ) - with aws_infrastructure.tasks.ssh.SSHClientContextManager(ssh_config=ssh_config) as ssh_client: + with aws_infrastructure.tasks.ssh.SSHClientContextManager( + ssh_config=ssh_config + ) as ssh_client: with aws_infrastructure.tasks.ssh.SSHPortForwardContextManager( ssh_client=ssh_client, remote_host=documentdb_config.endpoint, remote_port=documentdb_config.port, local_port=5000, ) as ssh_port_forward: - mongodbcompass_connection_string = 'mongodb://{}:{}@{}:{}/?{}'.format( + mongodbcompass_connection_string = "mongodb://{}:{}@{}:{}/?{}".format( urllib.parse.quote_plus(documentdb_config.admin_user), urllib.parse.quote_plus(documentdb_config.admin_password), - 'localhost', + "localhost", ssh_port_forward.local_port, - '&'.join([ - 'ssl=true', - 'directConnection=true', - 'serverSelectionTimeoutMS=5000', - 'connectTimeoutMS=10000', - 'authSource=admin', - 'authMechanism=SCRAM-SHA-1', - ]), + "&".join( + [ + "tls=true", + "tlsInsecure=true", + "directConnection=true", + "serverSelectionTimeoutMS=5000", + "connectTimeoutMS=10000", + "authSource=admin", + "authMechanism=SCRAM-SHA-1", + ] + ), ) - studio3t_connection_string = 'mongodb://{}:{}@{}:{}/?{}'.format( + studio3t_connection_string = "mongodb://{}:{}@{}:{}/?{}".format( urllib.parse.quote_plus(documentdb_config.admin_user), urllib.parse.quote_plus(documentdb_config.admin_password), - 'localhost', + "localhost", ssh_port_forward.local_port, - '&'.join([ - 'ssl=true', - 'sslInvalidHostNameAllowed=true', - 'serverSelectionTimeoutMS=5000', - 'connectTimeoutMS=10000', - 'authSource=admin', - 'authMechanism=SCRAM-SHA-1', - '3t.uriVersion=3', - '3t.connection.name={}'.format( - urllib.parse.quote_plus('UWScope Production Cluster') - ), - '3t.alwaysShowAuthDB=true', - '3t.alwaysShowDBFromUserRole=true', - '3t.sslTlsVersion=TLS', - '3t.proxyType=none', - ]), + "&".join( + [ + "ssl=true", + "sslInvalidHostNameAllowed=true", + "serverSelectionTimeoutMS=5000", + "connectTimeoutMS=10000", + "authSource=admin", + "authMechanism=SCRAM-SHA-1", + "3t.uriVersion=3", + "3t.connection.name={}".format( + urllib.parse.quote_plus("UWScope Production Cluster") + ), + "3t.alwaysShowAuthDB=true", + "3t.alwaysShowDBFromUserRole=true", + "3t.sslTlsVersion=TLS", + "3t.proxyType=none", + ] + ), ) - print('') - print('MongoDB Compass Connection String:') + print("") + print("MongoDB Compass Connection String:") print(mongodbcompass_connection_string) - print('') - print('Studio 3T Connection String:') + print("") + print("Studio 3T Connection String:") print(studio3t_connection_string) - print('') + print("") ssh_port_forward.serve_forever() # Build task collection -ns = Collection('documentdb') +ns = Collection("documentdb") -ns.add_task(documentdb_forward, 'forward') +ns.add_task(documentdb_forward, "forward") From c24daada669adf0de09e918fc7a82a1dcc1be365 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Mon, 16 Oct 2023 08:46:32 -0700 Subject: [PATCH 03/22] Create notification permissions schema --- .../documents/notification-permissions.json | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 scope_shared/scope/schemas/documents/notification-permissions.json diff --git a/scope_shared/scope/schemas/documents/notification-permissions.json b/scope_shared/scope/schemas/documents/notification-permissions.json new file mode 100644 index 00000000..168b0114 --- /dev/null +++ b/scope_shared/scope/schemas/documents/notification-permissions.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://uwscope.org/schemas/documents/notification-permissions", + "title": "INotificationPermissions", + "description": "INotificationPermissions Type", + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "_type": { + "const": "notificationPermissions" + }, + "_rev": { + "type": "number" + }, + "enablePushNotification": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": ["_type", "enablePushNotification"] +} From 69dd9eda7db414cc51c576e99471058f820b761f Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Mon, 16 Oct 2023 09:48:57 -0700 Subject: [PATCH 04/22] Add notification-permissions to patient and document schema --- scope_shared/scope/schemas/api/patient.json | 175 ++++++++++---------- scope_shared/scope/schemas/document.json | 139 ++++++++-------- 2 files changed, 160 insertions(+), 154 deletions(-) diff --git a/scope_shared/scope/schemas/api/patient.json b/scope_shared/scope/schemas/api/patient.json index 68d791f5..df6a9e78 100644 --- a/scope_shared/scope/schemas/api/patient.json +++ b/scope_shared/scope/schemas/api/patient.json @@ -1,89 +1,92 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://uwscope.org/schemas/api/patient", - "title": "IPatient", - "description": "Holds all the patient data", - "type": "object", - "properties": { - "_type": { "const": "patient" }, + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://uwscope.org/schemas/api/patient", + "title": "IPatient", + "description": "Holds all the patient data", + "type": "object", + "properties": { + "_type": { "const": "patient" }, - "activities": { - "$ref": "/schemas/documents/activities" - }, - "activityLogs": { - "$ref": "/schemas/documents/activity-logs" - }, - "activitySchedules": { - "$ref": "/schemas/documents/activity-schedules" - }, - "assessments": { - "$ref": "/schemas/documents/assessments" - }, - "assessmentLogs": { - "$ref": "/schemas/documents/assessment-logs" - }, - "caseReviews": { - "$ref": "/schemas/documents/case-reviews" - }, - "clinicalHistory": { - "type": "object", - "description": "IClinicalHistory schema", - "$ref": "/schemas/documents/clinical-history" - }, - "identity": { - "type": "object", - "description": "IPatientIdentity schema", - "$ref": "/schemas/documents/patient-identity" - }, - "moodLogs": { - "$ref": "/schemas/documents/mood-logs" - }, - "profile": { - "type": "object", - "description": "IPatientProfile schema", - "$ref": "/schemas/documents/patient-profile" - }, - "safetyPlan": { - "type": "object", - "description": "ISafetyPlan schema", - "$ref": "/schemas/documents/safety-plan" - }, - "scheduledActivities": { - "$ref": "/schemas/documents/scheduled-activities" - }, - "scheduledAssessments": { - "$ref": "/schemas/documents/scheduled-assessments" - }, - "sessions": { - "$ref": "/schemas/documents/sessions" - }, - "values": { - "$ref": "/schemas/documents/values" - }, - "valuesInventory": { - "type": "object", - "description": "IValuesInventory schema", - "$ref": "/schemas/documents/values-inventory" - } - }, - "additionalProperties": false, - "required": [ - "_type", - "activities", - "activityLogs", - "activitySchedules", - "assessments", - "assessmentLogs", - "caseReviews", - "clinicalHistory", - "identity", - "moodLogs", - "profile", - "safetyPlan", - "scheduledActivities", - "scheduledAssessments", - "sessions", - "values", - "valuesInventory" - ] + "activities": { + "$ref": "/schemas/documents/activities" + }, + "activityLogs": { + "$ref": "/schemas/documents/activity-logs" + }, + "activitySchedules": { + "$ref": "/schemas/documents/activity-schedules" + }, + "assessments": { + "$ref": "/schemas/documents/assessments" + }, + "assessmentLogs": { + "$ref": "/schemas/documents/assessment-logs" + }, + "caseReviews": { + "$ref": "/schemas/documents/case-reviews" + }, + "clinicalHistory": { + "type": "object", + "description": "IClinicalHistory schema", + "$ref": "/schemas/documents/clinical-history" + }, + "identity": { + "type": "object", + "description": "IPatientIdentity schema", + "$ref": "/schemas/documents/patient-identity" + }, + "moodLogs": { + "$ref": "/schemas/documents/mood-logs" + }, + "notificationPermissions": { + "$ref": "/schemas/documents/notification-permissions" + }, + "profile": { + "type": "object", + "description": "IPatientProfile schema", + "$ref": "/schemas/documents/patient-profile" + }, + "safetyPlan": { + "type": "object", + "description": "ISafetyPlan schema", + "$ref": "/schemas/documents/safety-plan" + }, + "scheduledActivities": { + "$ref": "/schemas/documents/scheduled-activities" + }, + "scheduledAssessments": { + "$ref": "/schemas/documents/scheduled-assessments" + }, + "sessions": { + "$ref": "/schemas/documents/sessions" + }, + "values": { + "$ref": "/schemas/documents/values" + }, + "valuesInventory": { + "type": "object", + "description": "IValuesInventory schema", + "$ref": "/schemas/documents/values-inventory" + } + }, + "additionalProperties": false, + "required": [ + "_type", + "activities", + "activityLogs", + "activitySchedules", + "assessments", + "assessmentLogs", + "caseReviews", + "clinicalHistory", + "identity", + "moodLogs", + "profile", + "safetyPlan", + "scheduledActivities", + "scheduledAssessments", + "sessions", + "values", + "valuesInventory" + ] } diff --git a/scope_shared/scope/schemas/document.json b/scope_shared/scope/schemas/document.json index c2b2bac6..78c71959 100644 --- a/scope_shared/scope/schemas/document.json +++ b/scope_shared/scope/schemas/document.json @@ -1,70 +1,73 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://uwscope.org/schemas/document", - "title": "Document Schema", - "oneOf": [ - { - "$ref": "/schemas/documents/activity-log" - }, - { - "$ref": "/schemas/documents/activity" - }, - { - "$ref": "/schemas/documents/activity-schedule" - }, - { - "$ref": "/schemas/documents/assessment-log" - }, - { - "$ref": "/schemas/documents/assessment" - }, - { - "$ref": "/schemas/documents/case-review" - }, - { - "$ref": "/schemas/documents/clinical-history" - }, - { - "$ref": "/schemas/documents/mood-log" - }, - { - "$ref": "/schemas/documents/patient-identity" - }, - { - "$ref": "/schemas/documents/provider-identity" - }, - { - "$ref": "/schemas/documents/patient-profile" - }, - { - "$ref": "/schemas/documents/safety-plan" - }, - { - "$ref": "/schemas/documents/scheduled-activity" - }, - { - "$ref": "/schemas/documents/scheduled-assessment" - }, - { - "$ref": "/schemas/documents/sentinel" - }, - { - "$ref": "/schemas/documents/session" - }, - { - "$ref": "/schemas/documents/set-tombstone" - }, - { - "$ref": "/schemas/documents/value" - }, - { - "$ref": "/schemas/documents/values-inventory" - }, - { - "$ref": "/schemas/documents/utils/contact" - }, - { - "$ref": "/schemas/documents/utils/referral-status" - } - ] + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://uwscope.org/schemas/document", + "title": "Document Schema", + "oneOf": [ + { + "$ref": "/schemas/documents/activity-log" + }, + { + "$ref": "/schemas/documents/activity" + }, + { + "$ref": "/schemas/documents/activity-schedule" + }, + { + "$ref": "/schemas/documents/assessment-log" + }, + { + "$ref": "/schemas/documents/assessment" + }, + { + "$ref": "/schemas/documents/case-review" + }, + { + "$ref": "/schemas/documents/clinical-history" + }, + { + "$ref": "/schemas/documents/mood-log" + }, + { + "$ref": "/schemas/documents/notification-permissions" + }, + { + "$ref": "/schemas/documents/patient-identity" + }, + { + "$ref": "/schemas/documents/provider-identity" + }, + { + "$ref": "/schemas/documents/patient-profile" + }, + { + "$ref": "/schemas/documents/safety-plan" + }, + { + "$ref": "/schemas/documents/scheduled-activity" + }, + { + "$ref": "/schemas/documents/scheduled-assessment" + }, + { + "$ref": "/schemas/documents/sentinel" + }, + { + "$ref": "/schemas/documents/session" + }, + { + "$ref": "/schemas/documents/set-tombstone" + }, + { + "$ref": "/schemas/documents/value" + }, + { + "$ref": "/schemas/documents/values-inventory" + }, + { + "$ref": "/schemas/documents/utils/contact" + }, + { + "$ref": "/schemas/documents/utils/referral-status" + } + ] } From 284c384b2b0555ac7c7e528d46e6ddf7f54f3b11 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Mon, 16 Oct 2023 10:37:13 -0700 Subject: [PATCH 05/22] Add fixture for notification permissions --- scope_shared/scope/schema.py | 2 + .../fixtures_fake_notification_permissions.py | 54 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 scope_shared/scope/testing/fake_data/fixtures_fake_notification_permissions.py diff --git a/scope_shared/scope/schema.py b/scope_shared/scope/schema.py index 54778a83..ac0b0fdb 100644 --- a/scope_shared/scope/schema.py +++ b/scope_shared/scope/schema.py @@ -30,6 +30,7 @@ log_schema: Optional[jschon.JSONSchema] = None mood_log_schema: Optional[jschon.JSONSchema] = None mood_logs_schema: Optional[jschon.JSONSchema] = None +notification_permissions_schema: Optional[jschon.JSONSchema] = None patient_schema: Optional[jschon.JSONSchema] = None patients_schema: Optional[jschon.JSONSchema] = None patient_identity_schema: Optional[jschon.JSONSchema] = None @@ -95,6 +96,7 @@ "clinical_history_schema": "documents/clinical-history.json", "mood_log_schema": "documents/mood-log.json", "mood_logs_schema": "documents/mood-logs.json", + "notification_permissions_schema": "documents/notification-permissions.json", "patient_identity_schema": "documents/patient-identity.json", "patient_identities_schema": "documents/patient-identities.json", "patient_profile_schema": "documents/patient-profile.json", diff --git a/scope_shared/scope/testing/fake_data/fixtures_fake_notification_permissions.py b/scope_shared/scope/testing/fake_data/fixtures_fake_notification_permissions.py new file mode 100644 index 00000000..ad87b900 --- /dev/null +++ b/scope_shared/scope/testing/fake_data/fixtures_fake_notification_permissions.py @@ -0,0 +1,54 @@ +import faker +import pytest +import random +from typing import Callable + +import scope.database.patient.notification_permissions +import scope.enums +import scope.schema +import scope.schema_utils +import scope.testing.fake_data.fake_utils as fake_utils + + +def fake_notification_permissions_factory( + *, + faker_factory: faker.Faker, +) -> Callable[[], dict]: + """ + Obtain a factory that will generate fake notification permissions documents. + """ + + def factory() -> dict: + fake_notification_permissions = { + "_type": scope.database.patient.notification_permissions.DOCUMENT_TYPE, + "enablePushNotification": random.choice([True, False]), + } + + return fake_notification_permissions + + return factory + + +@pytest.fixture(name="data_fake_notification_permissions_factory") +def fixture_data_fake_notification_permissions_factory( + faker: faker.Faker, +) -> Callable[[], dict]: + """ + Fixture for data_fake_notification_permissions_factory. + """ + + unvalidated_factory = fake_notification_permissions_factory( + faker_factory=faker, + ) + + def factory() -> dict: + fake_notification_permissions = unvalidated_factory() + + scope.schema_utils.xfail_for_invalid_schema( + schema=scope.schema.notification_permissions_schema, + data=fake_notification_permissions, + ) + + return fake_notification_permissions + + return factory From f73902eec8d699b2c417d69ad89a00c0ae032bea Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Mon, 16 Oct 2023 10:39:22 -0700 Subject: [PATCH 06/22] Test notification permissions fixture --- scope_shared/scope/testing/__init__.py | 1 + .../testing/test_schemas/test_fake_data_schemas.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/scope_shared/scope/testing/__init__.py b/scope_shared/scope/testing/__init__.py index edc40c69..6b5299a4 100644 --- a/scope_shared/scope/testing/__init__.py +++ b/scope_shared/scope/testing/__init__.py @@ -17,6 +17,7 @@ "scope.testing.fake_data.fixtures_fake_life_area_contents", "scope.testing.fake_data.fixtures_fake_mood_log", "scope.testing.fake_data.fixtures_fake_mood_logs", + "scope.testing.fake_data.fixtures_fake_notification_permissions", "scope.testing.fake_data.fixtures_fake_patient_profile", "scope.testing.fake_data.fixtures_fake_provider_identity", "scope.testing.fake_data.fixtures_fake_referral_status", diff --git a/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py b/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py index adc483ae..39712006 100644 --- a/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py +++ b/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py @@ -36,6 +36,7 @@ import scope.testing.fake_data.fixtures_fake_life_area_contents import scope.testing.fake_data.fixtures_fake_mood_log import scope.testing.fake_data.fixtures_fake_mood_logs +import scope.testing.fake_data.fixtures_fake_notification_permissions import scope.testing.fake_data.fixtures_fake_patient_profile import scope.testing.fake_data.fixtures_fake_provider_identity import scope.testing.fake_data.fixtures_fake_referral_status @@ -244,6 +245,16 @@ class ConfigTestFakeDataSchema: expected_semantic_set_id=None, expected_set_ids=None, ), + ConfigTestFakeDataSchema( + name="notification-permissions", + schema=scope.schema.notification_permissions_schema, + data_factory_fixture="data_fake_notification_permissions_factory", + expected_document=True, + expected_singleton=True, + expected_set_element=False, + expected_semantic_set_id=None, + expected_set_ids=None, + ), # patient-identity is not faked because there would be no patient backing that identity. # Fake patient identities are instead obtained by generating entire fake patients. # ConfigTestFakeDataSchema( From cb1ad74af528a729748927e32498dfe0c08cd238 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Mon, 16 Oct 2023 10:47:22 -0700 Subject: [PATCH 07/22] Add database calls for notification persmissions --- .../scope/database/patient/__init__.py | 4 ++ .../patient/notification_permissions.py | 37 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 scope_shared/scope/database/patient/notification_permissions.py diff --git a/scope_shared/scope/database/patient/__init__.py b/scope_shared/scope/database/patient/__init__.py index 5f1afcdd..5c41c49b 100644 --- a/scope_shared/scope/database/patient/__init__.py +++ b/scope_shared/scope/database/patient/__init__.py @@ -31,6 +31,10 @@ post_mood_log, put_mood_log, ) +from scope.database.patient.notification_permissions import ( + get_notification_permissions, + put_notification_permissions, +) from scope.database.patient.patient_profile import ( get_patient_profile, put_patient_profile, diff --git a/scope_shared/scope/database/patient/notification_permissions.py b/scope_shared/scope/database/patient/notification_permissions.py new file mode 100644 index 00000000..5669066d --- /dev/null +++ b/scope_shared/scope/database/patient/notification_permissions.py @@ -0,0 +1,37 @@ +from typing import Optional + +import pymongo.collection +import scope.database.collection_utils +import scope.schema +import scope.schema_utils as schema_utils + +DOCUMENT_TYPE = "notificationPermissions" + + +def get_notification_permissions( + *, + collection: pymongo.collection.Collection, +) -> Optional[dict]: + return scope.database.collection_utils.get_singleton( + collection=collection, + document_type=DOCUMENT_TYPE, + ) + + +def put_notification_permissions( + *, + collection: pymongo.collection.Collection, + notification_permissions: dict, +) -> scope.database.collection_utils.PutResult: + # Enforce the schema + schema_utils.raise_for_invalid_schema( + schema=scope.schema.notification_permissions_schema, + data=notification_permissions, + ) + + # Put the document + return scope.database.collection_utils.put_singleton( + collection=collection, + document_type=DOCUMENT_TYPE, + document=notification_permissions, + ) From c122bf0bea83b17d0f405691c8e3e43620844f17 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Mon, 16 Oct 2023 10:49:05 -0700 Subject: [PATCH 08/22] Add notification permissions to flask --- server_flask/app.py | 5 + .../patient/notification_permissions.py | 92 +++++++++++++++++++ server_flask/blueprints/registry/patients.py | 31 +++++-- .../registry/test_patient_singleton.py | 13 +++ 4 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 server_flask/blueprints/patient/notification_permissions.py diff --git a/server_flask/app.py b/server_flask/app.py index 051d8590..222f5d03 100644 --- a/server_flask/app.py +++ b/server_flask/app.py @@ -8,6 +8,7 @@ import blueprints.identities import blueprints.app.config import blueprints.patient.summary +import blueprints.patient.notification_permissions import blueprints.registry.activities import blueprints.registry.activity_logs import blueprints.registry.activity_schedules @@ -133,6 +134,10 @@ def status(): blueprints.registry.mood_logs.mood_logs_blueprint, url_prefix="/patient/", ) + app.register_blueprint( + blueprints.patient.notification_permissions.notification_permissions_blueprint, + url_prefix="/patient/", + ) app.register_blueprint( blueprints.registry.assessments.assessments_blueprint, url_prefix="/patient/", diff --git a/server_flask/blueprints/patient/notification_permissions.py b/server_flask/blueprints/patient/notification_permissions.py new file mode 100644 index 00000000..7fe6ab80 --- /dev/null +++ b/server_flask/blueprints/patient/notification_permissions.py @@ -0,0 +1,92 @@ +import flask +import flask_json +import pymongo.errors + +import request_context +import request_utils +import scope.database +import scope.database.patient.notification_permissions +import scope.schema + +notification_permissions_blueprint = flask.Blueprint( + "notification_permissions_blueprint", __name__ +) + + +@notification_permissions_blueprint.route( + "//notificationpermissions", + methods=["GET"], +) +@flask_json.as_json +def get_notification_permissions(patient_id): + context = request_context.authorized_for_patient(patient_id=patient_id) + patient_collection = context.patient_collection(patient_id=patient_id) + + # Get the document + document = ( + scope.database.patient.notification_permissions.get_notification_permissions( + collection=patient_collection, + ) + ) + + # Validate and normalize the response + document = request_utils.singleton_get_response_validate( + document=document, + ) + + return { + "notificationpermissions": document, + } + + +@notification_permissions_blueprint.route( + "//notificationpermissions", + methods=["PUT"], +) +@request_utils.validate_schema( + schema=scope.schema.notification_permissions_schema, + key="notificationpermissions", +) +@flask_json.as_json +def put_notification_permissions(patient_id): + context = request_context.authorized_for_patient(patient_id=patient_id) + patient_collection = context.patient_collection(patient_id=patient_id) + + # Obtain the document being put + document = flask.request.json["notificationpermissions"] + + # Validate and normalize the request + document = request_utils.singleton_put_request_validate( + document=document, + ) + + # Store the document + try: + result = scope.database.patient.notification_permissions.put_notification_permissions( + collection=patient_collection, + notification_permissions=document, + ) + except pymongo.errors.DuplicateKeyError: + # Indicates a revision race condition, return error with current revision + document_conflict = scope.database.patient.notification_permissions.get_notification_permissions( + collection=patient_collection + ) + # Validate and normalize the response + document_conflict = request_utils.singleton_put_response_validate( + document=document_conflict + ) + + request_utils.abort_revision_conflict( + document={ + "notificationpermissions": document_conflict, + } + ) + else: + # Validate and normalize the response + document_response = request_utils.singleton_put_response_validate( + document=result.document, + ) + + return { + "notificationpermissions": document_response, + } diff --git a/server_flask/blueprints/registry/patients.py b/server_flask/blueprints/registry/patients.py index bdb8b843..caccbf8c 100644 --- a/server_flask/blueprints/registry/patients.py +++ b/server_flask/blueprints/registry/patients.py @@ -13,6 +13,7 @@ import scope.database.patient.case_reviews import scope.database.patient.clinical_history import scope.database.patient.mood_logs +import scope.database.patient.notification_permissions import scope.database.patient.patient_profile import scope.database.patient.safety_plan import scope.database.patient.scheduled_activities @@ -53,8 +54,10 @@ def _construct_patient_document( patient_document["activityLogs"] = activity_logs # Activity Schedules - activity_schedules = scope.database.patient.activity_schedules.get_activity_schedules( - collection=patient_collection + activity_schedules = ( + scope.database.patient.activity_schedules.get_activity_schedules( + collection=patient_collection + ) ) patient_document["activitySchedules"] = activity_schedules @@ -88,6 +91,14 @@ def _construct_patient_document( ) patient_document["moodLogs"] = mood_logs + # Notification Permissions + notification_permissions = ( + scope.database.patient.notification_permissions.get_notification_permissions( + collection=patient_collection + ) + ) + patient_document["notificationPermissions"] = notification_permissions + # Profile profile = scope.database.patient.patient_profile.get_patient_profile( collection=patient_collection @@ -101,14 +112,18 @@ def _construct_patient_document( patient_document["safetyPlan"] = safety_plan # Scheduled Assessments - scheduled_assessments = scope.database.patient.scheduled_assessments.get_scheduled_assessments( - collection=patient_collection + scheduled_assessments = ( + scope.database.patient.scheduled_assessments.get_scheduled_assessments( + collection=patient_collection + ) ) patient_document["scheduledAssessments"] = scheduled_assessments # Scheduled Activities - scheduled_activities = scope.database.patient.scheduled_activities.get_scheduled_activities( - collection=patient_collection + scheduled_activities = ( + scope.database.patient.scheduled_activities.get_scheduled_activities( + collection=patient_collection + ) ) patient_document["scheduledActivities"] = scheduled_activities @@ -119,9 +134,7 @@ def _construct_patient_document( patient_document["sessions"] = sessions # Values - values = scope.database.patient.values.get_values( - collection=patient_collection - ) + values = scope.database.patient.values.get_values(collection=patient_collection) patient_document["values"] = values # Values Inventory diff --git a/server_flask/tests/test_flask/registry/test_patient_singleton.py b/server_flask/tests/test_flask/registry/test_patient_singleton.py index ab009031..b565065f 100644 --- a/server_flask/tests/test_flask/registry/test_patient_singleton.py +++ b/server_flask/tests/test_flask/registry/test_patient_singleton.py @@ -54,6 +54,19 @@ class ConfigTestPatientSingleton: singleton_will_already_exist=True, ), ), + # NOTE: Confirm w/ James where to test this because it should be in patient folder. + ConfigTestPatientSingleton( + name="notificationpermissions", + document_factory_fixture="data_fake_notification_permissions_factory", + database_get_function=scope.database.patient.get_notification_permissions, + database_unsafe_update_function=scope.database.patient_unsafe_utils.unsafe_update_notification_permissions, + database_unsafe_update_document_parameter="notification_permissions", + flask_query_type="notificationpermissions", + flask_document_key="notificationpermissions", + options=ConfigTestPatientSingletonOptions( + singleton_will_already_exist=False, + ), + ), ConfigTestPatientSingleton( name="profile", document_factory_fixture="data_fake_patient_profile_factory", From bb3b78326b52c8bc9403f2fb99f683f574e15d1d Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Mon, 16 Oct 2023 21:58:00 -0700 Subject: [PATCH 09/22] Add database, fixtures, schema, flask, tests for push subscriptions --- .../scope/database/patient/__init__.py | 6 + .../database/patient/push_subscriptions.py | 73 ++++ scope_shared/scope/schema.py | 4 + scope_shared/scope/schemas/api/patient.json | 3 + scope_shared/scope/schemas/document.json | 3 + .../schemas/documents/push-subscription.json | 45 +++ .../schemas/documents/push-subscriptions.json | 9 + scope_shared/scope/testing/__init__.py | 2 + .../test_schemas/test_fake_data_schemas.py | 20 + server_flask/app.py | 5 + .../blueprints/patient/push_subscriptions.py | 158 ++++++++ .../test_flask/registry/test_patient_set.py | 374 +++++++++--------- 12 files changed, 523 insertions(+), 179 deletions(-) create mode 100644 scope_shared/scope/database/patient/push_subscriptions.py create mode 100644 scope_shared/scope/schemas/documents/push-subscription.json create mode 100644 scope_shared/scope/schemas/documents/push-subscriptions.json create mode 100644 server_flask/blueprints/patient/push_subscriptions.py diff --git a/scope_shared/scope/database/patient/__init__.py b/scope_shared/scope/database/patient/__init__.py index 5c41c49b..0454922c 100644 --- a/scope_shared/scope/database/patient/__init__.py +++ b/scope_shared/scope/database/patient/__init__.py @@ -39,6 +39,12 @@ get_patient_profile, put_patient_profile, ) +from scope.database.patient.push_subscriptions import ( + get_push_subscriptions, + get_push_subscription, + post_push_subscription, + put_push_subscription, +) from scope.database.patient.scheduled_activities import ( get_scheduled_activities, get_scheduled_activity, diff --git a/scope_shared/scope/database/patient/push_subscriptions.py b/scope_shared/scope/database/patient/push_subscriptions.py new file mode 100644 index 00000000..5aa94713 --- /dev/null +++ b/scope_shared/scope/database/patient/push_subscriptions.py @@ -0,0 +1,73 @@ +from typing import List, Optional + +import pymongo.collection +import scope.database.collection_utils + +DOCUMENT_TYPE = "pushSubscription" +SEMANTIC_SET_ID = "pushSubscriptionId" + + +def get_push_subscriptions( + *, + collection: pymongo.collection.Collection, +) -> Optional[List[dict]]: + """ + Get list of "pushSubscription" documents. + """ + + return scope.database.collection_utils.get_set( + collection=collection, + document_type=DOCUMENT_TYPE, + ) + + +def get_push_subscription( + *, + collection: pymongo.collection.Collection, + set_id: str, +) -> Optional[dict]: + """ + Get "pushSubscription" document. + """ + + return scope.database.collection_utils.get_set_element( + collection=collection, + document_type=DOCUMENT_TYPE, + set_id=set_id, + ) + + +def post_push_subscription( + *, + collection: pymongo.collection.Collection, + push_subscription: dict, +) -> scope.database.collection_utils.SetPostResult: + """ + Post "pushSubscription" document. + """ + + return scope.database.collection_utils.post_set_element( + collection=collection, + document_type=DOCUMENT_TYPE, + semantic_set_id=SEMANTIC_SET_ID, + document=push_subscription, + ) + + +def put_push_subscription( + *, + collection: pymongo.collection.Collection, + push_subscription: dict, + set_id: str, +) -> scope.database.collection_utils.SetPutResult: + """ + Put "pushSubscription" document. + """ + + return scope.database.collection_utils.put_set_element( + collection=collection, + document_type=DOCUMENT_TYPE, + semantic_set_id=SEMANTIC_SET_ID, + set_id=set_id, + document=push_subscription, + ) diff --git a/scope_shared/scope/schema.py b/scope_shared/scope/schema.py index ac0b0fdb..1f010ead 100644 --- a/scope_shared/scope/schema.py +++ b/scope_shared/scope/schema.py @@ -41,6 +41,8 @@ populate_config_account_schema: Optional[jschon.JSONSchema] = None provider_identity_schema: Optional[jschon.JSONSchema] = None provider_identities_schema: Optional[jschon.JSONSchema] = None +push_subscription_schema: Optional[jschon.JSONSchema] = None +push_subscriptions_schema: Optional[jschon.JSONSchema] = None referral_status_schema: Optional[jschon.JSONSchema] = None regexes: Optional[jschon.JSONSchema] = None resource_content_schema: Optional[jschon.JSONSchema] = None @@ -102,6 +104,8 @@ "patient_profile_schema": "documents/patient-profile.json", "provider_identity_schema": "documents/provider-identity.json", "provider_identities_schema": "documents/provider-identities.json", + "push_subscription_schema": "documents/push-subscription.json", + "push_subscriptions_schema": "documents/push-subscriptions.json", "safety_plan_schema": "documents/safety-plan.json", "scheduled_activity_schema": "documents/scheduled-activity.json", "scheduled_activities_schema": "documents/scheduled-activities.json", diff --git a/scope_shared/scope/schemas/api/patient.json b/scope_shared/scope/schemas/api/patient.json index df6a9e78..b18ce376 100644 --- a/scope_shared/scope/schemas/api/patient.json +++ b/scope_shared/scope/schemas/api/patient.json @@ -46,6 +46,9 @@ "description": "IPatientProfile schema", "$ref": "/schemas/documents/patient-profile" }, + "pushSubscriptions": { + "$ref": "/schemas/documents/push-subscriptions" + }, "safetyPlan": { "type": "object", "description": "ISafetyPlan schema", diff --git a/scope_shared/scope/schemas/document.json b/scope_shared/scope/schemas/document.json index 78c71959..5cc42059 100644 --- a/scope_shared/scope/schemas/document.json +++ b/scope_shared/scope/schemas/document.json @@ -39,6 +39,9 @@ { "$ref": "/schemas/documents/patient-profile" }, + { + "$ref": "/schemas/documents/push-subscription" + }, { "$ref": "/schemas/documents/safety-plan" }, diff --git a/scope_shared/scope/schemas/documents/push-subscription.json b/scope_shared/scope/schemas/documents/push-subscription.json new file mode 100644 index 00000000..e1d7bdf6 --- /dev/null +++ b/scope_shared/scope/schemas/documents/push-subscription.json @@ -0,0 +1,45 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://uwscope.org/schemas/documents/push-subscription", + "title": "IPushSubscription", + "description": "IPushSubscription Type", + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "_type": { + "const": "pushSubscription" + }, + "_set_id": { + "type": "string" + }, + "_rev": { + "type": "number" + }, + "pushSubscriptionId": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "expirationTime": { + "type": ["number", "null"] + }, + "keys": { + "type": "object", + "properties": { + "p256dh": { + "type": "string" + }, + "auth": { + "type": "string" + } + }, + "additionalProperties": false, + "required": ["p256dh", "auth"] + } + }, + "additionalProperties": false, + "required": ["_type", "endpoint", "expirationTime", "keys"] +} diff --git a/scope_shared/scope/schemas/documents/push-subscriptions.json b/scope_shared/scope/schemas/documents/push-subscriptions.json new file mode 100644 index 00000000..fe51508f --- /dev/null +++ b/scope_shared/scope/schemas/documents/push-subscriptions.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://uwscope.org/schemas/documents/push-subscriptions", + "title": "IPushSubscription[]", + "type": "array", + "items": { + "$ref": "/schemas/documents/push-subscription" + } +} diff --git a/scope_shared/scope/testing/__init__.py b/scope_shared/scope/testing/__init__.py index 6b5299a4..43a730da 100644 --- a/scope_shared/scope/testing/__init__.py +++ b/scope_shared/scope/testing/__init__.py @@ -20,6 +20,8 @@ "scope.testing.fake_data.fixtures_fake_notification_permissions", "scope.testing.fake_data.fixtures_fake_patient_profile", "scope.testing.fake_data.fixtures_fake_provider_identity", + "scope.testing.fake_data.fixtures_fake_push_subscription", + "scope.testing.fake_data.fixtures_fake_push_subscriptions", "scope.testing.fake_data.fixtures_fake_referral_status", "scope.testing.fake_data.fixtures_fake_safety_plan", "scope.testing.fake_data.fixtures_fake_session", diff --git a/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py b/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py index 39712006..5c00d375 100644 --- a/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py +++ b/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py @@ -281,6 +281,26 @@ class ConfigTestFakeDataSchema: expected_semantic_set_id=scope.database.providers.PROVIDER_IDENTITY_SEMANTIC_SET_ID, expected_set_ids=None, ), + ConfigTestFakeDataSchema( + name="push-subscription", + schema=scope.schema.push_subscription_schema, + data_factory_fixture="data_fake_push_subscription_factory", + expected_document=True, + expected_singleton=False, + expected_set_element=True, + expected_semantic_set_id=scope.database.patient.push_subscriptions.SEMANTIC_SET_ID, + expected_set_ids=None, + ), + ConfigTestFakeDataSchema( + name="push-subscriptions", + schema=scope.schema.push_subscriptions_schema, + data_factory_fixture="data_fake_push_subscriptions_factory", + expected_document=False, + expected_singleton=False, + expected_set_element=False, + expected_semantic_set_id=None, + expected_set_ids=None, + ), ConfigTestFakeDataSchema( name="referral-status", schema=scope.schema.referral_status_schema, diff --git a/server_flask/app.py b/server_flask/app.py index 222f5d03..d03ac562 100644 --- a/server_flask/app.py +++ b/server_flask/app.py @@ -9,6 +9,7 @@ import blueprints.app.config import blueprints.patient.summary import blueprints.patient.notification_permissions +import blueprints.patient.push_subscriptions import blueprints.registry.activities import blueprints.registry.activity_logs import blueprints.registry.activity_schedules @@ -142,6 +143,10 @@ def status(): blueprints.registry.assessments.assessments_blueprint, url_prefix="/patient/", ) + app.register_blueprint( + blueprints.patient.push_subscriptions.push_subscriptions_blueprint, + url_prefix="/patient/", + ) app.register_blueprint( blueprints.registry.scheduled_assessments.scheduled_assessments_blueprint, url_prefix="/patient/", diff --git a/server_flask/blueprints/patient/push_subscriptions.py b/server_flask/blueprints/patient/push_subscriptions.py new file mode 100644 index 00000000..7363a5ec --- /dev/null +++ b/server_flask/blueprints/patient/push_subscriptions.py @@ -0,0 +1,158 @@ +import flask +import flask_json +import pymongo.errors + +import request_context +import request_utils +import scope.database +import scope.database.patient.push_subscriptions +import scope.schema + +push_subscriptions_blueprint = flask.Blueprint( + "push_subscriptions_blueprint", + __name__, +) + + +@push_subscriptions_blueprint.route( + "//pushsubscriptions", + methods=["GET"], +) +@flask_json.as_json +def get_push_subscriptions(patient_id): + context = request_context.authorized_for_patient(patient_id=patient_id) + patient_collection = context.patient_collection(patient_id=patient_id) + + documents = scope.database.patient.push_subscriptions.get_push_subscriptions( + collection=patient_collection, + ) + + # Validate and normalize the response + documents = request_utils.set_get_response_validate( + documents=documents, + ) + + return { + "pushsubscriptions": documents, + } + + +@push_subscriptions_blueprint.route( + "//pushsubscriptions", + methods=["POST"], +) +@request_utils.validate_schema( + schema=scope.schema.push_subscription_schema, + key="pushsubscription", +) +@flask_json.as_json +def post_push_subscriptions(patient_id): + context = request_context.authorized_for_patient(patient_id=patient_id) + patient_collection = context.patient_collection(patient_id=patient_id) + + # Obtain the document being put + document = flask.request.json["pushsubscription"] + + # Validate and normalize the request + document = request_utils.set_post_request_validate( + semantic_set_id=scope.database.patient.push_subscriptions.SEMANTIC_SET_ID, + document=document, + ) + + # Store the document + result = scope.database.patient.push_subscriptions.post_push_subscription( + collection=patient_collection, + push_subscription=document, + ) + + # Validate and normalize the response + document_response = request_utils.set_post_response_validate( + document=result.document, + ) + + return { + "pushsubscription": document_response, + } + + +@push_subscriptions_blueprint.route( + "//pushsubscription/", + methods=["GET"], +) +@flask_json.as_json +def get_push_subscription(patient_id, pushsubscription_id): + context = request_context.authorized_for_patient(patient_id=patient_id) + patient_collection = context.patient_collection(patient_id=patient_id) + + # Get the document + document = scope.database.patient.push_subscriptions.get_push_subscription( + collection=patient_collection, + set_id=pushsubscription_id, + ) + + # Validate and normalize the response + document = request_utils.singleton_get_response_validate( + document=document, + ) + + return { + "pushsubscription": document, + } + + +@push_subscriptions_blueprint.route( + "//pushsubscription/", + methods=["PUT"], +) +@request_utils.validate_schema( + schema=scope.schema.push_subscription_schema, + key="pushsubscription", +) +@flask_json.as_json +def put_push_subscription(patient_id, pushsubscription_id): + context = request_context.authorized_for_patient(patient_id=patient_id) + patient_collection = context.patient_collection(patient_id=patient_id) + + # Obtain the document being put + document = flask.request.json["pushsubscription"] + + # Validate and normalize the request + document = request_utils.set_element_put_request_validate( + semantic_set_id=scope.database.patient.push_subscriptions.SEMANTIC_SET_ID, + document=document, + set_id=pushsubscription_id, + ) + + # Store the document + try: + result = scope.database.patient.push_subscriptions.put_push_subscription( + collection=patient_collection, + push_subscription=document, + set_id=pushsubscription_id, + ) + except pymongo.errors.DuplicateKeyError: + # Indicates a revision race condition, return error with current revision + document_conflict = ( + scope.database.patient.push_subscriptions.get_push_subscription( + collection=patient_collection, set_id=pushsubscription_id + ) + ) + # Validate and normalize the response + document_conflict = request_utils.singleton_put_response_validate( + document=document_conflict + ) + + request_utils.abort_revision_conflict( + document={ + "pushsubscription": document_conflict, + } + ) + else: + # Validate and normalize the response + document_response = request_utils.singleton_put_response_validate( + document=result.document, + ) + + return { + "pushsubscription": document_response, + } diff --git a/server_flask/tests/test_flask/registry/test_patient_set.py b/server_flask/tests/test_flask/registry/test_patient_set.py index c03f94d0..76f1e3ea 100644 --- a/server_flask/tests/test_flask/registry/test_patient_set.py +++ b/server_flask/tests/test_flask/registry/test_patient_set.py @@ -16,6 +16,7 @@ import scope.database.patient.assessment_logs import scope.database.patient.case_reviews import scope.database.patient.mood_logs +import scope.database.patient.push_subscriptions import scope.database.patient.sessions import scope.database.patient.scheduled_activities import scope.database.patient.scheduled_assessments @@ -76,188 +77,203 @@ class ConfigTestPatientSet: TEST_CONFIGS = [ + # ConfigTestPatientSet( + # name="activities", + # semantic_set_id=scope.database.patient.activities.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_activity_factory", + # document_factory_fixture_set="data_fake_activities_factory", + # database_get_set_function=scope.database.patient.activities.get_activities, + # database_get_function=scope.database.patient.activities.get_activity, + # database_post_function=scope.database.patient.activities.post_activity, + # database_unsafe_update_function=None, + # database_document_parameter_name="activity", + # flask_query_set_type="activities", + # flask_document_set_key="activities", + # flask_query_set_element_type="activity", + # flask_document_set_element_key="activity", + # options=ConfigTestPatientSetOptions( + # set_supports_deletion=True, + # ), + # ), + # ConfigTestPatientSet( + # name="activitylogs", + # semantic_set_id=scope.database.patient.activity_logs.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_activity_log_factory", + # document_factory_fixture_set="data_fake_activity_logs_factory", + # database_get_set_function=scope.database.patient.activity_logs.get_activity_logs, + # database_get_function=scope.database.patient.activity_logs.get_activity_log, + # database_post_function=scope.database.patient.activity_logs.post_activity_log, + # database_unsafe_update_function=None, + # database_document_parameter_name="activity_log", + # flask_query_set_type="activitylogs", + # flask_document_set_key="activitylogs", + # flask_query_set_element_type="activitylog", + # flask_document_set_element_key="activitylog", + # ), + # ConfigTestPatientSet( + # name="activityschedules", + # semantic_set_id=scope.database.patient.activity_schedules.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_activity_schedule_factory", + # document_factory_fixture_set="data_fake_activity_schedules_factory", + # database_get_set_function=scope.database.patient.activity_schedules.get_activity_schedules, + # database_get_function=scope.database.patient.activity_schedules.get_activity_schedule, + # database_post_function=scope.database.patient.activity_schedules.post_activity_schedule, + # database_unsafe_update_function=None, + # database_document_parameter_name="activity_schedule", + # flask_query_set_type="activityschedules", + # flask_document_set_key="activityschedules", + # flask_query_set_element_type="activityschedule", + # flask_document_set_element_key="activityschedule", + # options=ConfigTestPatientSetOptions( + # set_supports_deletion=True, + # ), + # ), + # ConfigTestPatientSet( + # name="assessments", + # semantic_set_id=scope.database.patient.assessments.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_assessment_factory", + # document_factory_fixture_set="data_fake_assessments_factory", + # database_get_set_function=scope.database.patient.assessments.get_assessments, + # database_get_function=scope.database.patient.assessments.get_assessment, + # database_post_function=None, # Assessments have fixed set IDs + # database_unsafe_update_function=scope.database.patient_unsafe_utils.unsafe_update_assessment, + # database_document_parameter_name="assessment", + # flask_query_set_type="assessments", + # flask_document_set_key="assessments", + # flask_query_set_element_type="assessment", + # flask_document_set_element_key="assessment", + # options=ConfigTestPatientSetOptions( + # set_id_will_already_exist=True, + # set_element_will_already_exist=True, + # ), + # ), + # ConfigTestPatientSet( + # name="assessmentlogs", + # semantic_set_id=scope.database.patient.assessment_logs.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_assessment_log_factory", + # document_factory_fixture_set="data_fake_assessment_logs_factory", + # database_get_set_function=scope.database.patient.assessment_logs.get_assessment_logs, + # database_get_function=scope.database.patient.assessment_logs.get_assessment_log, + # database_post_function=scope.database.patient.assessment_logs.post_assessment_log, + # database_unsafe_update_function=None, + # database_document_parameter_name="assessment_log", + # flask_query_set_type="assessmentlogs", + # flask_document_set_key="assessmentlogs", + # flask_query_set_element_type="assessmentlog", + # flask_document_set_element_key="assessmentlog", + # ), + # ConfigTestPatientSet( + # name="casereviews", + # semantic_set_id=scope.database.patient.case_reviews.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_case_review_factory", + # document_factory_fixture_set="data_fake_case_reviews_factory", + # database_get_set_function=scope.database.patient.case_reviews.get_case_reviews, + # database_get_function=scope.database.patient.case_reviews.get_case_review, + # database_post_function=scope.database.patient.case_reviews.post_case_review, + # database_unsafe_update_function=None, + # database_document_parameter_name="case_review", + # flask_query_set_type="casereviews", + # flask_document_set_key="casereviews", + # flask_query_set_element_type="casereview", + # flask_document_set_element_key="casereview", + # ), + # ConfigTestPatientSet( + # name="moodlogs", + # semantic_set_id=scope.database.patient.mood_logs.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_mood_log_factory", + # document_factory_fixture_set="data_fake_mood_logs_factory", + # database_get_set_function=scope.database.patient.mood_logs.get_mood_logs, + # database_get_function=scope.database.patient.mood_logs.get_mood_log, + # database_post_function=scope.database.patient.mood_logs.post_mood_log, + # database_unsafe_update_function=None, + # database_document_parameter_name="mood_log", + # flask_query_set_type="moodlogs", + # flask_document_set_key="moodlogs", + # flask_query_set_element_type="moodlog", + # flask_document_set_element_key="moodlog", + # ), ConfigTestPatientSet( - name="activities", - semantic_set_id=scope.database.patient.activities.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_activity_factory", - document_factory_fixture_set="data_fake_activities_factory", - database_get_set_function=scope.database.patient.activities.get_activities, - database_get_function=scope.database.patient.activities.get_activity, - database_post_function=scope.database.patient.activities.post_activity, + name="pushsubscriptions", + semantic_set_id=scope.database.patient.push_subscriptions.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_push_subscription_factory", + document_factory_fixture_set="data_fake_push_subscriptions_factory", + database_get_set_function=scope.database.patient.push_subscriptions.get_push_subscriptions, + database_get_function=scope.database.patient.push_subscriptions.get_push_subscription, + database_post_function=scope.database.patient.push_subscriptions.post_push_subscription, database_unsafe_update_function=None, - database_document_parameter_name="activity", - flask_query_set_type="activities", - flask_document_set_key="activities", - flask_query_set_element_type="activity", - flask_document_set_element_key="activity", - options=ConfigTestPatientSetOptions( - set_supports_deletion=True, - ), - ), - ConfigTestPatientSet( - name="activitylogs", - semantic_set_id=scope.database.patient.activity_logs.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_activity_log_factory", - document_factory_fixture_set="data_fake_activity_logs_factory", - database_get_set_function=scope.database.patient.activity_logs.get_activity_logs, - database_get_function=scope.database.patient.activity_logs.get_activity_log, - database_post_function=scope.database.patient.activity_logs.post_activity_log, - database_unsafe_update_function=None, - database_document_parameter_name="activity_log", - flask_query_set_type="activitylogs", - flask_document_set_key="activitylogs", - flask_query_set_element_type="activitylog", - flask_document_set_element_key="activitylog", - ), - ConfigTestPatientSet( - name="activityschedules", - semantic_set_id=scope.database.patient.activity_schedules.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_activity_schedule_factory", - document_factory_fixture_set="data_fake_activity_schedules_factory", - database_get_set_function=scope.database.patient.activity_schedules.get_activity_schedules, - database_get_function=scope.database.patient.activity_schedules.get_activity_schedule, - database_post_function=scope.database.patient.activity_schedules.post_activity_schedule, - database_unsafe_update_function=None, - database_document_parameter_name="activity_schedule", - flask_query_set_type="activityschedules", - flask_document_set_key="activityschedules", - flask_query_set_element_type="activityschedule", - flask_document_set_element_key="activityschedule", - options=ConfigTestPatientSetOptions( - set_supports_deletion=True, - ), - ), - ConfigTestPatientSet( - name="assessments", - semantic_set_id=scope.database.patient.assessments.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_assessment_factory", - document_factory_fixture_set="data_fake_assessments_factory", - database_get_set_function=scope.database.patient.assessments.get_assessments, - database_get_function=scope.database.patient.assessments.get_assessment, - database_post_function=None, # Assessments have fixed set IDs - database_unsafe_update_function=scope.database.patient_unsafe_utils.unsafe_update_assessment, - database_document_parameter_name="assessment", - flask_query_set_type="assessments", - flask_document_set_key="assessments", - flask_query_set_element_type="assessment", - flask_document_set_element_key="assessment", - options=ConfigTestPatientSetOptions( - set_id_will_already_exist=True, - set_element_will_already_exist=True, - ), - ), - ConfigTestPatientSet( - name="assessmentlogs", - semantic_set_id=scope.database.patient.assessment_logs.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_assessment_log_factory", - document_factory_fixture_set="data_fake_assessment_logs_factory", - database_get_set_function=scope.database.patient.assessment_logs.get_assessment_logs, - database_get_function=scope.database.patient.assessment_logs.get_assessment_log, - database_post_function=scope.database.patient.assessment_logs.post_assessment_log, - database_unsafe_update_function=None, - database_document_parameter_name="assessment_log", - flask_query_set_type="assessmentlogs", - flask_document_set_key="assessmentlogs", - flask_query_set_element_type="assessmentlog", - flask_document_set_element_key="assessmentlog", - ), - ConfigTestPatientSet( - name="casereviews", - semantic_set_id=scope.database.patient.case_reviews.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_case_review_factory", - document_factory_fixture_set="data_fake_case_reviews_factory", - database_get_set_function=scope.database.patient.case_reviews.get_case_reviews, - database_get_function=scope.database.patient.case_reviews.get_case_review, - database_post_function=scope.database.patient.case_reviews.post_case_review, - database_unsafe_update_function=None, - database_document_parameter_name="case_review", - flask_query_set_type="casereviews", - flask_document_set_key="casereviews", - flask_query_set_element_type="casereview", - flask_document_set_element_key="casereview", - ), - ConfigTestPatientSet( - name="moodlogs", - semantic_set_id=scope.database.patient.mood_logs.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_mood_log_factory", - document_factory_fixture_set="data_fake_mood_logs_factory", - database_get_set_function=scope.database.patient.mood_logs.get_mood_logs, - database_get_function=scope.database.patient.mood_logs.get_mood_log, - database_post_function=scope.database.patient.mood_logs.post_mood_log, - database_unsafe_update_function=None, - database_document_parameter_name="mood_log", - flask_query_set_type="moodlogs", - flask_document_set_key="moodlogs", - flask_query_set_element_type="moodlog", - flask_document_set_element_key="moodlog", - ), - ConfigTestPatientSet( - name="sessions", - semantic_set_id=scope.database.patient.sessions.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_session_factory", - document_factory_fixture_set="data_fake_sessions_factory", - database_get_set_function=scope.database.patient.sessions.get_sessions, - database_get_function=scope.database.patient.sessions.get_session, - database_post_function=scope.database.patient.sessions.post_session, - database_unsafe_update_function=None, - database_document_parameter_name="session", - flask_query_set_type="sessions", - flask_document_set_key="sessions", - flask_query_set_element_type="session", - flask_document_set_element_key="session", - ), - ConfigTestPatientSet( - name="scheduledactivities", - semantic_set_id=scope.database.patient.scheduled_activities.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_scheduled_activity_factory", - document_factory_fixture_set="data_fake_scheduled_activities_factory", - database_get_set_function=scope.database.patient.scheduled_activities.get_scheduled_activities, - database_get_function=scope.database.patient.scheduled_activities.get_scheduled_activity, - database_post_function=scope.database.patient.scheduled_activities.post_scheduled_activity, - database_unsafe_update_function=None, - database_document_parameter_name="scheduled_activity", - flask_query_set_type="scheduledactivities", - flask_document_set_key="scheduledactivities", - flask_query_set_element_type="scheduledactivity", - flask_document_set_element_key="scheduledactivity", - ), - ConfigTestPatientSet( - name="scheduledassessments", - semantic_set_id=scope.database.patient.scheduled_assessments.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_scheduled_assessment_factory", - document_factory_fixture_set="data_fake_scheduled_assessments_factory", - database_get_set_function=scope.database.patient.scheduled_assessments.get_scheduled_assessments, - database_get_function=scope.database.patient.scheduled_assessments.get_scheduled_assessment, - database_post_function=scope.database.patient.scheduled_assessments.post_scheduled_assessment, - database_unsafe_update_function=None, - database_document_parameter_name="scheduled_assessment", - flask_query_set_type="scheduledassessments", - flask_document_set_key="scheduledassessments", - flask_query_set_element_type="scheduledassessment", - flask_document_set_element_key="scheduledassessment", - options=ConfigTestPatientSetOptions( - set_id_will_already_exist=False, - set_element_will_already_exist=True, - ), - ), - ConfigTestPatientSet( - name="values", - semantic_set_id=scope.database.patient.values.SEMANTIC_SET_ID, - document_factory_fixture_set_element="data_fake_value_factory", - document_factory_fixture_set="data_fake_values_factory", - database_get_set_function=scope.database.patient.values.get_values, - database_get_function=scope.database.patient.values.get_value, - database_post_function=scope.database.patient.values.post_value, - database_unsafe_update_function=None, - database_document_parameter_name="value", - flask_query_set_type="values", - flask_document_set_key="values", - flask_query_set_element_type="value", - flask_document_set_element_key="value", - options=ConfigTestPatientSetOptions( - set_supports_deletion=True, - ), + database_document_parameter_name="push_subscription", + flask_query_set_type="pushsubscriptions", + flask_document_set_key="pushsubscriptions", + flask_query_set_element_type="pushsubscription", + flask_document_set_element_key="pushsubscription", ), + # ConfigTestPatientSet( + # name="sessions", + # semantic_set_id=scope.database.patient.sessions.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_session_factory", + # document_factory_fixture_set="data_fake_sessions_factory", + # database_get_set_function=scope.database.patient.sessions.get_sessions, + # database_get_function=scope.database.patient.sessions.get_session, + # database_post_function=scope.database.patient.sessions.post_session, + # database_unsafe_update_function=None, + # database_document_parameter_name="session", + # flask_query_set_type="sessions", + # flask_document_set_key="sessions", + # flask_query_set_element_type="session", + # flask_document_set_element_key="session", + # ), + # ConfigTestPatientSet( + # name="scheduledactivities", + # semantic_set_id=scope.database.patient.scheduled_activities.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_scheduled_activity_factory", + # document_factory_fixture_set="data_fake_scheduled_activities_factory", + # database_get_set_function=scope.database.patient.scheduled_activities.get_scheduled_activities, + # database_get_function=scope.database.patient.scheduled_activities.get_scheduled_activity, + # database_post_function=scope.database.patient.scheduled_activities.post_scheduled_activity, + # database_unsafe_update_function=None, + # database_document_parameter_name="scheduled_activity", + # flask_query_set_type="scheduledactivities", + # flask_document_set_key="scheduledactivities", + # flask_query_set_element_type="scheduledactivity", + # flask_document_set_element_key="scheduledactivity", + # ), + # ConfigTestPatientSet( + # name="scheduledassessments", + # semantic_set_id=scope.database.patient.scheduled_assessments.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_scheduled_assessment_factory", + # document_factory_fixture_set="data_fake_scheduled_assessments_factory", + # database_get_set_function=scope.database.patient.scheduled_assessments.get_scheduled_assessments, + # database_get_function=scope.database.patient.scheduled_assessments.get_scheduled_assessment, + # database_post_function=scope.database.patient.scheduled_assessments.post_scheduled_assessment, + # database_unsafe_update_function=None, + # database_document_parameter_name="scheduled_assessment", + # flask_query_set_type="scheduledassessments", + # flask_document_set_key="scheduledassessments", + # flask_query_set_element_type="scheduledassessment", + # flask_document_set_element_key="scheduledassessment", + # options=ConfigTestPatientSetOptions( + # set_id_will_already_exist=False, + # set_element_will_already_exist=True, + # ), + # ), + # ConfigTestPatientSet( + # name="values", + # semantic_set_id=scope.database.patient.values.SEMANTIC_SET_ID, + # document_factory_fixture_set_element="data_fake_value_factory", + # document_factory_fixture_set="data_fake_values_factory", + # database_get_set_function=scope.database.patient.values.get_values, + # database_get_function=scope.database.patient.values.get_value, + # database_post_function=scope.database.patient.values.post_value, + # database_unsafe_update_function=None, + # database_document_parameter_name="value", + # flask_query_set_type="values", + # flask_document_set_key="values", + # flask_query_set_element_type="value", + # flask_document_set_element_key="value", + # options=ConfigTestPatientSetOptions( + # set_supports_deletion=True, + # ), + # ), ] QUERY_SET = "patient/{patient_id}/{query_type}" From fcf6dc0bd85fa1e6e34e5642ec589a73fc455efd Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 17:58:45 -0800 Subject: [PATCH 10/22] Add pywebpush to setup.py --- scope_shared/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scope_shared/setup.py b/scope_shared/setup.py index 85185e95..033acbf4 100644 --- a/scope_shared/setup.py +++ b/scope_shared/setup.py @@ -18,6 +18,7 @@ "pyjwt", "pymongo", "pytz", + "pywebpush", # pyzipper is used in populate scripts "pyzipper", "requests", From a37af094e63554a640c782a68c5eacc2a9a5827c Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 18:05:18 -0800 Subject: [PATCH 11/22] Remove old notification permissions related code --- .../patient/notification_permissions.py | 37 -------- scope_shared/scope/schema.py | 2 - scope_shared/scope/schemas/api/patient.json | 3 - scope_shared/scope/schemas/document.json | 3 - .../documents/notification-permissions.json | 23 ----- .../fixtures_fake_notification_permissions.py | 54 ----------- .../test_schemas/test_fake_data_schemas.py | 14 +-- .../patient/notification_permissions.py | 92 ------------------- server_flask/blueprints/registry/patients.py | 18 ++-- .../registry/test_patient_singleton.py | 13 --- 10 files changed, 11 insertions(+), 248 deletions(-) delete mode 100644 scope_shared/scope/database/patient/notification_permissions.py delete mode 100644 scope_shared/scope/schemas/documents/notification-permissions.json delete mode 100644 scope_shared/scope/testing/fake_data/fixtures_fake_notification_permissions.py delete mode 100644 server_flask/blueprints/patient/notification_permissions.py diff --git a/scope_shared/scope/database/patient/notification_permissions.py b/scope_shared/scope/database/patient/notification_permissions.py deleted file mode 100644 index 5669066d..00000000 --- a/scope_shared/scope/database/patient/notification_permissions.py +++ /dev/null @@ -1,37 +0,0 @@ -from typing import Optional - -import pymongo.collection -import scope.database.collection_utils -import scope.schema -import scope.schema_utils as schema_utils - -DOCUMENT_TYPE = "notificationPermissions" - - -def get_notification_permissions( - *, - collection: pymongo.collection.Collection, -) -> Optional[dict]: - return scope.database.collection_utils.get_singleton( - collection=collection, - document_type=DOCUMENT_TYPE, - ) - - -def put_notification_permissions( - *, - collection: pymongo.collection.Collection, - notification_permissions: dict, -) -> scope.database.collection_utils.PutResult: - # Enforce the schema - schema_utils.raise_for_invalid_schema( - schema=scope.schema.notification_permissions_schema, - data=notification_permissions, - ) - - # Put the document - return scope.database.collection_utils.put_singleton( - collection=collection, - document_type=DOCUMENT_TYPE, - document=notification_permissions, - ) diff --git a/scope_shared/scope/schema.py b/scope_shared/scope/schema.py index 1f010ead..cee6f689 100644 --- a/scope_shared/scope/schema.py +++ b/scope_shared/scope/schema.py @@ -30,7 +30,6 @@ log_schema: Optional[jschon.JSONSchema] = None mood_log_schema: Optional[jschon.JSONSchema] = None mood_logs_schema: Optional[jschon.JSONSchema] = None -notification_permissions_schema: Optional[jschon.JSONSchema] = None patient_schema: Optional[jschon.JSONSchema] = None patients_schema: Optional[jschon.JSONSchema] = None patient_identity_schema: Optional[jschon.JSONSchema] = None @@ -98,7 +97,6 @@ "clinical_history_schema": "documents/clinical-history.json", "mood_log_schema": "documents/mood-log.json", "mood_logs_schema": "documents/mood-logs.json", - "notification_permissions_schema": "documents/notification-permissions.json", "patient_identity_schema": "documents/patient-identity.json", "patient_identities_schema": "documents/patient-identities.json", "patient_profile_schema": "documents/patient-profile.json", diff --git a/scope_shared/scope/schemas/api/patient.json b/scope_shared/scope/schemas/api/patient.json index b18ce376..3e47020d 100644 --- a/scope_shared/scope/schemas/api/patient.json +++ b/scope_shared/scope/schemas/api/patient.json @@ -38,9 +38,6 @@ "moodLogs": { "$ref": "/schemas/documents/mood-logs" }, - "notificationPermissions": { - "$ref": "/schemas/documents/notification-permissions" - }, "profile": { "type": "object", "description": "IPatientProfile schema", diff --git a/scope_shared/scope/schemas/document.json b/scope_shared/scope/schemas/document.json index 5cc42059..a15748ff 100644 --- a/scope_shared/scope/schemas/document.json +++ b/scope_shared/scope/schemas/document.json @@ -27,9 +27,6 @@ { "$ref": "/schemas/documents/mood-log" }, - { - "$ref": "/schemas/documents/notification-permissions" - }, { "$ref": "/schemas/documents/patient-identity" }, diff --git a/scope_shared/scope/schemas/documents/notification-permissions.json b/scope_shared/scope/schemas/documents/notification-permissions.json deleted file mode 100644 index 168b0114..00000000 --- a/scope_shared/scope/schemas/documents/notification-permissions.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://uwscope.org/schemas/documents/notification-permissions", - "title": "INotificationPermissions", - "description": "INotificationPermissions Type", - "type": "object", - "properties": { - "_id": { - "type": "string" - }, - "_type": { - "const": "notificationPermissions" - }, - "_rev": { - "type": "number" - }, - "enablePushNotification": { - "type": "boolean" - } - }, - "additionalProperties": false, - "required": ["_type", "enablePushNotification"] -} diff --git a/scope_shared/scope/testing/fake_data/fixtures_fake_notification_permissions.py b/scope_shared/scope/testing/fake_data/fixtures_fake_notification_permissions.py deleted file mode 100644 index ad87b900..00000000 --- a/scope_shared/scope/testing/fake_data/fixtures_fake_notification_permissions.py +++ /dev/null @@ -1,54 +0,0 @@ -import faker -import pytest -import random -from typing import Callable - -import scope.database.patient.notification_permissions -import scope.enums -import scope.schema -import scope.schema_utils -import scope.testing.fake_data.fake_utils as fake_utils - - -def fake_notification_permissions_factory( - *, - faker_factory: faker.Faker, -) -> Callable[[], dict]: - """ - Obtain a factory that will generate fake notification permissions documents. - """ - - def factory() -> dict: - fake_notification_permissions = { - "_type": scope.database.patient.notification_permissions.DOCUMENT_TYPE, - "enablePushNotification": random.choice([True, False]), - } - - return fake_notification_permissions - - return factory - - -@pytest.fixture(name="data_fake_notification_permissions_factory") -def fixture_data_fake_notification_permissions_factory( - faker: faker.Faker, -) -> Callable[[], dict]: - """ - Fixture for data_fake_notification_permissions_factory. - """ - - unvalidated_factory = fake_notification_permissions_factory( - faker_factory=faker, - ) - - def factory() -> dict: - fake_notification_permissions = unvalidated_factory() - - scope.schema_utils.xfail_for_invalid_schema( - schema=scope.schema.notification_permissions_schema, - data=fake_notification_permissions, - ) - - return fake_notification_permissions - - return factory diff --git a/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py b/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py index 5c00d375..dbf09770 100644 --- a/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py +++ b/scope_shared/scope/testing/test_schemas/test_fake_data_schemas.py @@ -13,7 +13,6 @@ import scope.database.patient.assessments import scope.database.patient.case_reviews import scope.database.patient.mood_logs -import scope.database.patient.sessions import scope.database.patient.scheduled_activities import scope.database.patient.scheduled_assessments import scope.database.patient.sessions @@ -36,10 +35,11 @@ import scope.testing.fake_data.fixtures_fake_life_area_contents import scope.testing.fake_data.fixtures_fake_mood_log import scope.testing.fake_data.fixtures_fake_mood_logs -import scope.testing.fake_data.fixtures_fake_notification_permissions import scope.testing.fake_data.fixtures_fake_patient_profile import scope.testing.fake_data.fixtures_fake_provider_identity import scope.testing.fake_data.fixtures_fake_referral_status +import scope.testing.fake_data.fixtures_fake_push_subscription +import scope.testing.fake_data.fixtures_fake_push_subscriptions import scope.testing.fake_data.fixtures_fake_safety_plan import scope.testing.fake_data.fixtures_fake_session import scope.testing.fake_data.fixtures_fake_sessions @@ -245,16 +245,6 @@ class ConfigTestFakeDataSchema: expected_semantic_set_id=None, expected_set_ids=None, ), - ConfigTestFakeDataSchema( - name="notification-permissions", - schema=scope.schema.notification_permissions_schema, - data_factory_fixture="data_fake_notification_permissions_factory", - expected_document=True, - expected_singleton=True, - expected_set_element=False, - expected_semantic_set_id=None, - expected_set_ids=None, - ), # patient-identity is not faked because there would be no patient backing that identity. # Fake patient identities are instead obtained by generating entire fake patients. # ConfigTestFakeDataSchema( diff --git a/server_flask/blueprints/patient/notification_permissions.py b/server_flask/blueprints/patient/notification_permissions.py deleted file mode 100644 index 7fe6ab80..00000000 --- a/server_flask/blueprints/patient/notification_permissions.py +++ /dev/null @@ -1,92 +0,0 @@ -import flask -import flask_json -import pymongo.errors - -import request_context -import request_utils -import scope.database -import scope.database.patient.notification_permissions -import scope.schema - -notification_permissions_blueprint = flask.Blueprint( - "notification_permissions_blueprint", __name__ -) - - -@notification_permissions_blueprint.route( - "//notificationpermissions", - methods=["GET"], -) -@flask_json.as_json -def get_notification_permissions(patient_id): - context = request_context.authorized_for_patient(patient_id=patient_id) - patient_collection = context.patient_collection(patient_id=patient_id) - - # Get the document - document = ( - scope.database.patient.notification_permissions.get_notification_permissions( - collection=patient_collection, - ) - ) - - # Validate and normalize the response - document = request_utils.singleton_get_response_validate( - document=document, - ) - - return { - "notificationpermissions": document, - } - - -@notification_permissions_blueprint.route( - "//notificationpermissions", - methods=["PUT"], -) -@request_utils.validate_schema( - schema=scope.schema.notification_permissions_schema, - key="notificationpermissions", -) -@flask_json.as_json -def put_notification_permissions(patient_id): - context = request_context.authorized_for_patient(patient_id=patient_id) - patient_collection = context.patient_collection(patient_id=patient_id) - - # Obtain the document being put - document = flask.request.json["notificationpermissions"] - - # Validate and normalize the request - document = request_utils.singleton_put_request_validate( - document=document, - ) - - # Store the document - try: - result = scope.database.patient.notification_permissions.put_notification_permissions( - collection=patient_collection, - notification_permissions=document, - ) - except pymongo.errors.DuplicateKeyError: - # Indicates a revision race condition, return error with current revision - document_conflict = scope.database.patient.notification_permissions.get_notification_permissions( - collection=patient_collection - ) - # Validate and normalize the response - document_conflict = request_utils.singleton_put_response_validate( - document=document_conflict - ) - - request_utils.abort_revision_conflict( - document={ - "notificationpermissions": document_conflict, - } - ) - else: - # Validate and normalize the response - document_response = request_utils.singleton_put_response_validate( - document=result.document, - ) - - return { - "notificationpermissions": document_response, - } diff --git a/server_flask/blueprints/registry/patients.py b/server_flask/blueprints/registry/patients.py index caccbf8c..b17238e7 100644 --- a/server_flask/blueprints/registry/patients.py +++ b/server_flask/blueprints/registry/patients.py @@ -13,8 +13,8 @@ import scope.database.patient.case_reviews import scope.database.patient.clinical_history import scope.database.patient.mood_logs -import scope.database.patient.notification_permissions import scope.database.patient.patient_profile +import scope.database.patient.push_subscriptions import scope.database.patient.safety_plan import scope.database.patient.scheduled_activities import scope.database.patient.scheduled_assessments @@ -91,20 +91,20 @@ def _construct_patient_document( ) patient_document["moodLogs"] = mood_logs - # Notification Permissions - notification_permissions = ( - scope.database.patient.notification_permissions.get_notification_permissions( - collection=patient_collection - ) - ) - patient_document["notificationPermissions"] = notification_permissions - # Profile profile = scope.database.patient.patient_profile.get_patient_profile( collection=patient_collection ) patient_document["profile"] = profile + # Push Subscriptions + push_subscriptions = ( + scope.database.patient.push_subscriptions.get_push_subscriptions( + collection=patient_collection + ) + ) + patient_document["pushSubscriptions"] = push_subscriptions + # Safety Plan safety_plan = scope.database.patient.safety_plan.get_safety_plan( collection=patient_collection diff --git a/server_flask/tests/test_flask/registry/test_patient_singleton.py b/server_flask/tests/test_flask/registry/test_patient_singleton.py index b565065f..ab009031 100644 --- a/server_flask/tests/test_flask/registry/test_patient_singleton.py +++ b/server_flask/tests/test_flask/registry/test_patient_singleton.py @@ -54,19 +54,6 @@ class ConfigTestPatientSingleton: singleton_will_already_exist=True, ), ), - # NOTE: Confirm w/ James where to test this because it should be in patient folder. - ConfigTestPatientSingleton( - name="notificationpermissions", - document_factory_fixture="data_fake_notification_permissions_factory", - database_get_function=scope.database.patient.get_notification_permissions, - database_unsafe_update_function=scope.database.patient_unsafe_utils.unsafe_update_notification_permissions, - database_unsafe_update_document_parameter="notification_permissions", - flask_query_type="notificationpermissions", - flask_document_key="notificationpermissions", - options=ConfigTestPatientSingletonOptions( - singleton_will_already_exist=False, - ), - ), ConfigTestPatientSingleton( name="profile", document_factory_fixture="data_fake_patient_profile_factory", From 6ab28d4751b2c92bcea2a9a94e99bbda95cc9137 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 21:53:10 -0800 Subject: [PATCH 12/22] web_shared: Add push subscription types and service --- web_shared/patientService.ts | 49 ++++++++++++++++++++++++++++++++++++ web_shared/serviceTypes.ts | 15 +++++++++++ web_shared/types.ts | 19 +++++++++++++- 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/web_shared/patientService.ts b/web_shared/patientService.ts index dbc5d435..032fac77 100644 --- a/web_shared/patientService.ts +++ b/web_shared/patientService.ts @@ -40,6 +40,9 @@ import { IValueRequest, IValueResponse, IValueListResponse, + IPushSubscriptionListResponse, + IPushSubscriptionResponse, + IPushSubscriptionRequest, } from 'shared/serviceTypes'; import { IActivity, @@ -53,6 +56,7 @@ import { IPatient, IPatientConfig, IPatientProfile, + IPushSubscription, ISafetyPlan, IScheduledActivity, IScheduledAssessment, @@ -116,6 +120,11 @@ export interface IPatientService extends IServiceBase { getMoodLogs(): Promise; addMoodLog(moodLog: IMoodLog): Promise; + getPushSubscriptions(): Promise; + addPushSubscription(pushSubscription: IPushSubscription): Promise; + deletePushSubscription(pushSubscription: IPushSubscription): Promise; + updatePushSubscription(pushSubscription: IPushSubscription): Promise; + getValues(): Promise; addValue(value: IValue): Promise; deleteValue(value: IValue): Promise; @@ -432,6 +441,46 @@ class PatientService extends ServiceBase implements IPatientService { return response.data?.moodlog; } + public async addPushSubscription(pushSubscription: IPushSubscription): Promise { + (pushSubscription as any)._type = 'pushSubscription'; + + const response = await this.axiosInstance.post(`/pushsubscriptions`, { + pushsubscription: pushSubscription, + } as IPushSubscriptionRequest); + return response.data?.pushsubscription; + } + + public async getPushSubscriptions(): Promise { + const response = await this.axiosInstance.get(`/pushsubscriptions`); + return response.data?.pushsubscriptions; + } + + public async deletePushSubscription(pushSubscription: IPushSubscription): Promise { + logger.assert((pushSubscription as any)._rev != undefined, '_rev should be in the request data'); + const response = await this.axiosInstance.delete( + `/pushsubscription/${pushSubscription.pushSubscriptionId}`, + { + headers: { + 'If-Match': (pushSubscription as any)._rev, + }, + }, + ); + return response.data?.pushsubscription; + } + + public async updatePushSubscription(pushSubscription: IPushSubscription): Promise { + (pushSubscription as any)._type = 'pushSubscription'; + logger.assert((pushSubscription as any)._rev != undefined, '_rev should be in the request data'); + logger.assert((pushSubscription as any)._set_id != undefined, '_set_id should be in the request data'); + const response = await this.axiosInstance.put( + `/pushsubscription/${pushSubscription.pushSubscriptionId}`, + { + pushsubscription: pushSubscription, + } as IPushSubscriptionRequest, + ); + return response.data?.pushsubscription; + } + public async getValues(): Promise { const response = await this.axiosInstance.get(`/values`); return response.data?.values; diff --git a/web_shared/serviceTypes.ts b/web_shared/serviceTypes.ts index 3a8f5658..ee4e7380 100644 --- a/web_shared/serviceTypes.ts +++ b/web_shared/serviceTypes.ts @@ -11,6 +11,7 @@ import { IPatientIdentity, IPatientProfile, IProviderIdentity, + IPushSubscription, ISafetyPlan, IScheduledActivity, IScheduledAssessment, @@ -96,6 +97,20 @@ export interface IMoodLogRequest { moodlog: IMoodLog; } + +export interface IPushSubscriptionListResponse extends IServiceResponse { + pushsubscriptions: IPushSubscription[]; +} + +export interface IPushSubscriptionResponse extends IServiceResponse { + pushsubscription: IPushSubscription; +} + +export interface IPushSubscriptionRequest { + pushsubscription: IPushSubscription; +} + + export interface IActivityListResponse extends IServiceResponse { activities: IActivity[]; } diff --git a/web_shared/types.ts b/web_shared/types.ts index 71d07430..a71a8c61 100644 --- a/web_shared/types.ts +++ b/web_shared/types.ts @@ -316,6 +316,9 @@ export interface IPatient { // Mood logs moodLogs: IMoodLog[]; + + // Push Subscriptions + pushSubscriptions: IPushSubscription[]; } export interface IPatientList { @@ -352,7 +355,11 @@ export interface IAssessmentContent { questions: { question: string; id: string }[]; options: { text: string; value: number }[]; interpretationName: string; - interpretationTable: { score: string; max: number; interpretation: string }[]; + interpretationTable: { + score: string; + max: number; + interpretation: string; + }[]; } export interface ILifeAreaContent { @@ -372,6 +379,16 @@ export interface IResourceItem { filename: string; } +export interface IPushSubscription { + pushSubscriptionId?: string; + endpoint: string; + expirationTime: any; + keys: { + p256dh: string; + auth: string; + }; +} + export const isSession = (session: ISession | ICaseReview): session is ISession => { return (session as ISession)?.sessionId !== undefined; }; From c9c460e8b77a853083c43d34d9caed3ca67b205e Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 21:57:35 -0800 Subject: [PATCH 13/22] PatientStore: Add push subscription to store --- web_patient/src/stores/PatientStore.ts | 120 ++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/web_patient/src/stores/PatientStore.ts b/web_patient/src/stores/PatientStore.ts index 8ba8a174..6fff36ce 100644 --- a/web_patient/src/stores/PatientStore.ts +++ b/web_patient/src/stores/PatientStore.ts @@ -1,10 +1,12 @@ import { compareAsc, compareDesc, differenceInWeeks, endOfYesterday, isAfter, isBefore, startOfToday } from 'date-fns'; +import { get } from 'idb-keyval'; import _ from 'lodash'; import { action, computed, makeAutoObservable, toJS } from 'mobx'; import { getLogger } from 'shared/logger'; import { IPatientService } from 'shared/patientService'; import { IPromiseQueryState, PromiseQuery } from 'shared/promiseQuery'; import { getLoadAndLogQuery, onArrayConflict, onSingletonConflict } from 'shared/stores'; + import { IActivity, IActivityLog, @@ -13,6 +15,7 @@ import { IMoodLog, IPatient, IPatientConfig, + IPushSubscription, ISafetyPlan, IScheduledActivity, IScheduledAssessment, @@ -30,6 +33,7 @@ export interface IPatientStore { readonly assessmentLogs: IAssessmentLog[]; readonly config: IPatientConfig; readonly moodLogs: IMoodLog[]; + readonly pushSubscriptions: IPushSubscription[]; readonly safetyPlan: ISafetyPlan; readonly taskItems: IScheduledActivity[]; readonly todayItems: IScheduledActivity[]; @@ -46,12 +50,14 @@ export interface IPatientStore { readonly loadAssessmentLogsState: IPromiseQueryState; readonly loadConfigState: IPromiseQueryState; readonly loadMoodLogsState: IPromiseQueryState; + readonly loadPushSubscriptionsState: IPromiseQueryState; readonly loadSafetyPlanState: IPromiseQueryState; readonly loadScheduledActivitiesState: IPromiseQueryState; readonly loadValuesState: IPromiseQueryState; readonly loadValuesInventoryState: IPromiseQueryState; // Helpers + checkDevicePushSubscription: () => Promise; getActivityById: (activityId: string) => IActivity | undefined; getActivitiesByLifeAreaId: (lifeAreaId: string) => IActivity[]; getActivitiesByValueId: (valueId: string) => IActivity[]; @@ -92,6 +98,12 @@ export interface IPatientStore { loadMoodLogs: () => Promise; saveMoodLog: (moodLog: IMoodLog) => Promise; + // Push Subscription + addPushSubscription: (pushSubscription: IPushSubscription) => Promise; + deletePushSubscription: (pushSubscription: IPushSubscription) => Promise; + // NOTE: Call updatePushSubscription when the endpoint changes. + updatePushSubscription(pushSubscription: IPushSubscription): void; + // Safety Plan updateSafetyPlan: (safetyPlan: ISafetyPlan) => Promise; @@ -115,6 +127,7 @@ export class PatientStore implements IPatientStore { private readonly loadAssessmentLogsQuery: PromiseQuery; private readonly loadConfigQuery: PromiseQuery; private readonly loadMoodLogsQuery: PromiseQuery; + private readonly loadPushSubscriptionsQuery: PromiseQuery; private readonly loadSafetyPlanQuery: PromiseQuery; private readonly loadScheduledActivitiesQuery: PromiseQuery; private readonly loadScheduledAssessmentsQuery: PromiseQuery; @@ -142,6 +155,10 @@ export class PatientStore implements IPatientStore { this.loadAssessmentLogsQuery = new PromiseQuery([], 'loadAssessmentLogsQuery'); this.loadConfigQuery = new PromiseQuery(undefined, 'loadConfigQuery'); this.loadMoodLogsQuery = new PromiseQuery([], 'loadMoodLogsQuery'); + this.loadPushSubscriptionsQuery = new PromiseQuery( + undefined, + 'loadPushSubscriptionsQuery', + ); this.loadSafetyPlanQuery = new PromiseQuery(undefined, 'loadSafetyPlan'); this.loadScheduledActivitiesQuery = new PromiseQuery([], 'loadScheduledActivitiesQuery'); this.loadScheduledAssessmentsQuery = new PromiseQuery( @@ -215,6 +232,10 @@ export class PatientStore implements IPatientStore { return this.loadMoodLogsQuery.value || []; } + @computed public get pushSubscriptions() { + return this.loadPushSubscriptionsQuery.value || []; + } + @computed public get safetyPlan() { return this.loadSafetyPlanQuery.value || { assigned: false }; } @@ -272,6 +293,10 @@ export class PatientStore implements IPatientStore { return this.loadMoodLogsQuery; } + @computed public get loadPushSubscriptionsState() { + return this.loadPushSubscriptionsQuery; + } + @computed public get loadSafetyPlanState() { return this.loadSafetyPlanQuery; } @@ -289,6 +314,13 @@ export class PatientStore implements IPatientStore { } // Helpers + @action.bound + public async checkDevicePushSubscription() { + const subscription = await get('subscription'); + const foundIdx = this.pushSubscriptions.findIndex((ps) => ps.endpoint == subscription?.endpoint); + return foundIdx >= 0; + } + @action.bound public getActivityById(activityId: string) { return this.activities.find((a) => a.activityId == activityId); @@ -354,7 +386,9 @@ export class PatientStore implements IPatientStore { .filter( (i) => isBefore(i.dueDateTime, endOfYesterday()) && - differenceInWeeks(new Date(), i.dueDateTime, { roundingMethod: 'ceil' }) <= week, + differenceInWeeks(new Date(), i.dueDateTime, { + roundingMethod: 'ceil' + }) <= week, ) .sort((a, b) => compareDesc(a.dueDateTime, b.dueDateTime)); } @@ -394,6 +428,7 @@ export class PatientStore implements IPatientStore { this.loadActivitySchedulesQuery.fromPromise(Promise.resolve(patient.activitySchedules)); this.loadAssessmentLogsQuery.fromPromise(Promise.resolve(patient.assessmentLogs)); this.loadMoodLogsQuery.fromPromise(Promise.resolve(patient.moodLogs)); + this.loadPushSubscriptionsQuery.fromPromise(Promise.resolve(patient.pushSubscriptions)); this.loadSafetyPlanQuery.fromPromise(Promise.resolve(patient.safetyPlan)); this.loadScheduledActivitiesQuery.fromPromise(Promise.resolve(patient.scheduledActivities)); this.loadScheduledAssessmentsQuery.fromPromise(Promise.resolve(patient.scheduledAssessments)); @@ -656,6 +691,89 @@ export class PatientStore implements IPatientStore { ); } + // Push Subscriptions + @action.bound + public async addPushSubscription(pushSubscription: IPushSubscription): Promise { + let returnAddedPushSubscription = null; + + const promise = this.patientService.addPushSubscription(pushSubscription).then((addedPushSubscription) => { + returnAddedPushSubscription = addedPushSubscription; + + const newPushSubscriptions = this.pushSubscriptions.slice() || []; + newPushSubscriptions.push(addedPushSubscription); + return newPushSubscriptions; + }); + + await this.loadAndLogQuery( + () => promise, + this.loadPushSubscriptionsQuery, + onArrayConflict('pushSubscription', 'pushSubscriptionId', () => this.pushSubscriptions, logger), + ); + + return returnAddedPushSubscription; + } + + @action.bound + public async deletePushSubscription(pushSubscription: IPushSubscription) { + const prevPushSubscriptions = this.pushSubscriptions.slice() || []; + const foundIdx = prevPushSubscriptions.findIndex( + (ps) => ps.pushSubscriptionId == pushSubscription.pushSubscriptionId, + ); + + console.assert(foundIdx >= 0, `PushSubscription to delete not found: ${pushSubscription.pushSubscriptionId}`); + + if (foundIdx >= 0) { + const promise = this.patientService + .deletePushSubscription(pushSubscription) + .then((_deletedPushSubscription) => { + prevPushSubscriptions.splice(foundIdx, 1); + return prevPushSubscriptions; + }); + + await this.loadAndLogQuery( + () => promise, + this.loadPushSubscriptionsQuery, + onArrayConflict('pushSubscription', 'pushSubscriptionId', () => this.pushSubscriptions, logger), + ); + + await this.loadAndLogQuery( + this.patientService.getPushSubscriptions, + this.loadPushSubscriptionsQuery, + ); + } + } + + @action.bound + public async updatePushSubscription(pushSubscription: IPushSubscription) { + const prevPushSubscriptions = this.pushSubscriptions.slice() || []; + const foundIdx = prevPushSubscriptions.findIndex( + (v) => v.pushSubscriptionId == pushSubscription.pushSubscriptionId, + ); + + console.assert(foundIdx >= 0, `PushSubscription to update not found: ${pushSubscription.pushSubscriptionId}`); + + if (foundIdx >= 0) { + const promise = this.patientService + .updatePushSubscription(pushSubscription) + .then((updatedPushSubscription: IPushSubscription) => { + prevPushSubscriptions[foundIdx] = updatedPushSubscription; + + return prevPushSubscriptions; + }); + + await this.loadAndLogQuery( + () => promise, + this.loadPushSubscriptionsQuery, + onArrayConflict('pushSubscription', 'pushSubscriptionId', () => this.pushSubscriptions, logger), + ); + + await this.loadAndLogQuery( + this.patientService.getPushSubscriptions, + this.loadPushSubscriptionsQuery, + ); + } + } + // Safety plan @action.bound public async updateSafetyPlan(safetyPlan: ISafetyPlan) { From 14f8e0586eea290c003746a3a3e52fec635f631e Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 22:13:33 -0800 Subject: [PATCH 14/22] web_patient: Update service worker code and add notification settings --- web_patient/config/clientConfig.js | 3 +- web_patient/package.json | 1 + .../service-worker/serviceWorkerWorkbox.ts | 42 +++++ web_patient/src/@types/custom.d.ts | 1 + web_patient/src/App.tsx | 2 + web_patient/src/assets/notifications_icon.png | Bin 0 -> 1998 bytes .../Resources/NotificationsPage.tsx | 169 ++++++++++++++++++ .../components/Resources/ResourcesPage.tsx | 145 ++++++++------- web_patient/src/serviceWorkerRegistration.ts | 90 +++++----- web_patient/src/services/images.ts | 2 + web_patient/src/services/routes.ts | 1 + web_patient/src/services/strings.ts | 2 + web_patient/src/utils/notifications.ts | 14 ++ 13 files changed, 356 insertions(+), 116 deletions(-) create mode 100644 web_patient/src/assets/notifications_icon.png create mode 100644 web_patient/src/components/Resources/NotificationsPage.tsx create mode 100644 web_patient/src/utils/notifications.ts diff --git a/web_patient/config/clientConfig.js b/web_patient/config/clientConfig.js index e803972d..633cce22 100644 --- a/web_patient/config/clientConfig.js +++ b/web_patient/config/clientConfig.js @@ -4,5 +4,6 @@ * Designed for script to be replaced in deployed containers. */ const CLIENT_CONFIG = { - flaskBaseUrl: 'http://127.0.0.1:4000/', + flaskBaseUrl: 'http://127.0.0.1:4000/', + vapidPublicKey: 'Insert your VAPID public key here', }; diff --git a/web_patient/package.json b/web_patient/package.json index e99ab4bc..4d96b1f9 100644 --- a/web_patient/package.json +++ b/web_patient/package.json @@ -14,6 +14,7 @@ "amazon-cognito-identity-js": "^5.2.6", "axios": "0.25.x", "date-fns": "2.28.0", + "idb-keyval": "^6.2.1", "lodash": "4.17.21", "lodash.debounce": "4.0.8", "lodash.throttle": "4.1.1", diff --git a/web_patient/service-worker/serviceWorkerWorkbox.ts b/web_patient/service-worker/serviceWorkerWorkbox.ts index 6990c972..c46dcaba 100644 --- a/web_patient/service-worker/serviceWorkerWorkbox.ts +++ b/web_patient/service-worker/serviceWorkerWorkbox.ts @@ -19,9 +19,18 @@ const navigationRoute = new NavigationRoute(handler, { }); registerRoute(navigationRoute); +self.addEventListener('install', function (event) { + console.info('Service Worker installing.'); +}); + +self.addEventListener('activate', function (event) { + console.info('Service Worker activating.'); +}); + // @link https://flaviocopes.com/push-api/ // @link https://web.dev/push-notifications-handling-messages/ self.addEventListener('push', function (event) { + console.info('Push event called.'); if (!event.data) { console.log('This push event has no data.'); return; @@ -67,3 +76,36 @@ self.addEventListener('push', function (event) { // With this, the browser will keep the service worker running until the promise you passed in has settled. event.waitUntil(promiseChain); }); + +self.addEventListener('pushsubscriptionchange', (event) => { + // TODO: Renew your subscription here. + // Implementation Idea: postMessage with new subscription information to NotificationsPage componenent and updateSubscription. + // TODO: Unclear how to test this logic. + console.log('pushsubscriptionchange'); + console.log(event); +}); + +// TODO: Investigate if app can be opened when clicked on notification. +// self.addEventListener('notificationclick', (event) => { +// console.log('This is custom service worker notificationclick method.'); +// console.log('Notification details: ', event.notification); +// // Write the code to open +// if (event.notification.data.url) { +// event.waitUntil(self.clients.openWindow(event.notification.data.url)); +// } +// }); + +// self.addEventListener('pushsubscriptionchange', function (event) { +// event.waitUntil( +// fetch('https://pushpad.xyz/pushsubscriptionchange', { +// method: 'POST', +// headers: { 'Content-Type': 'application/json' }, +// body: JSON.stringify({ +// old_endpoint: event.oldSubscription ? event.oldSubscription.endpoint : null, +// new_endpoint: event.newSubscription ? event.newSubscription.endpoint : null, +// new_p256dh: event.newSubscription ? event.newSubscription.toJSON().keys.p256dh : null, +// new_auth: event.newSubscription ? event.newSubscription.toJSON().keys.auth : null, +// }), +// }), +// ); +// }); diff --git a/web_patient/src/@types/custom.d.ts b/web_patient/src/@types/custom.d.ts index 3bdb0cc3..2f01a2dc 100644 --- a/web_patient/src/@types/custom.d.ts +++ b/web_patient/src/@types/custom.d.ts @@ -15,4 +15,5 @@ declare function clearTimeout(timeoutId: number): void; // Expected client configuration declare var CLIENT_CONFIG: { flaskBaseUrl: string; + vapidPublicKey: string; }; diff --git a/web_patient/src/App.tsx b/web_patient/src/App.tsx index c76b7d43..ae2124e2 100644 --- a/web_patient/src/App.tsx +++ b/web_patient/src/App.tsx @@ -10,6 +10,7 @@ import MoodTrackingHome from 'src/components/Progress/MoodTrackingHome'; import ProgressPage from 'src/components/Progress/ProgressPage'; import AboutUsPage from 'src/components/Resources/AboutUsPage'; import CrisisResourcesPage from 'src/components/Resources/CrisisResourcesPage'; +import NotificationsPage from 'src/components/Resources/NotificationsPage'; import ResourcesPage from 'src/components/Resources/ResourcesPage'; import LifeAreaDetail from 'src/components/ValuesInventory/LifeAreaDetail'; import ValuesInventoryHome from 'src/components/ValuesInventory/ValuesInventoryHome'; @@ -34,6 +35,7 @@ export const App: FunctionComponent = () => { } /> } /> } /> + } /> } /> } diff --git a/web_patient/src/assets/notifications_icon.png b/web_patient/src/assets/notifications_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d1f23f8b0eea4674c42ad8404248886173c23513 GIT binary patch literal 1998 zcmZ{ldpOgJAIHDj%xrT@P7}gLvXPM7HkZXPb7#gXxp#3%?&W^zMrkf{%RMXUV5yDP zDNE%}G(On|IhQeyr0kWyq@&8T>pure7QS7$}!wYg=qKc z2GP^Z+zw;-61Llw5p+DzH;`X%Jl+h~J1eVtdlwv?uXfgzL9(|qvT25E8P@N*-9eI* z6|z@`h9#cK35z!Aj}Lb~Y2mGG7H3o(?!3S4lgMk~@mi3|B(MMI0r~JYs72!eBbCLX zt<(dn+MZ(9qGF41{(HV^J?ONo`a1t?5Qdc+8diqP=Hwx*Kl($yCZc_>)iqS$o{jaK zvq}Qnt1nVR=F)`c=z$Wqz9b=7+`<(2yC=*}&HvM_E+|?^rnKJo3z^lO1Ghpnz__X( zTyRC{R$apA>Bt>Yay6EyA>B3sc(PZE)4dw_N0?wK_={M z2}DS9-Hn+v$PeWK?OMsg4>t0UcF01&XV-zDfC~3_F~x@@!Uviuh>3FNgJ&{C=l8Cn zFLjReW!Gi9J^oYcjv~k^r0Qk{pT*azcgq(21D-CS9DDFGmyaGzD~|yMN;!^q;5mq{ zT@~=CgF>smtb3&IP0DtbtE!vG+Zz6PSiXhci|bMuRTTUTXMr*P8LZh1-c#HSl!0hE z%?;B2=cVNe;^|D4doO<}y*BujE|f30*ju#y)0%e&zCWVIL>T>LX8rxX#TIG5`SBw+ z6Oucg2CI%&64W}QW1vQ~vB?C&k~`f@1zLS{bo$iv0OGTHM{fyVPCk)URp?-w^K{me zrrfUdL+|(J4Q;2o~)to!3g(1;3JP!?2sZ(|N?#%G{%8zYLq6_x9cW z%oOC^E-@G5iW_!G?AfVaPd1eR?}#W)8^%)Sq$yBUvnvaQP7in)Ux1IJ4hv3St+T74Zla6`%kd zD!aMkzJTBw>;MI3Aj`obh_E>t4UcnXlR34CX);-D{Yb1h3Q1NRD8~^NVG>2aTI!hf z{KG>5!R8Tdp^B&iy2pzv07I9&jDEicbXpOi*aLNpwu`?5 znGjX+9{5|(TWjAyHd0x>kT7Gw3~n}%e1FH6hBOn!knw8Jcho6riX&=HuKF@hnW+e2 z&=9Qe_9d_4^k-cy0rOXd^cjduj9}LtM1>A-ue?xJmkgVi=3!RanHWvjoW|VR6_$ zv_C~zv!3o38_lgC+T*Y|`0oHr25^Mzm#WQr=SVPR5k^4c&C~F*iHw z)n-;?c(%x2FAe4D7znHH+wN00v2lu(jrdqDzP_;}xK5zpypC`5Y=xTnUX4_!!RFa^ z8EFav!+6&4*Sg^! zf<86PgseCje_4z4{b)0X(+yrLevtNPN zkgc_9Tbtk|7gxeiB`h#0M7n7Ty&~F8i11&x!&U{nGwfOG6ADnL|x^Pa2FI85*G1b3-T1Bx(Dlz{N dd!-c;)Sdk8SK2Qiyq$ms$Ru}%wxdBg{{v4Ak4FFi literal 0 HcmV?d00001 diff --git a/web_patient/src/components/Resources/NotificationsPage.tsx b/web_patient/src/components/Resources/NotificationsPage.tsx new file mode 100644 index 00000000..cae79cc4 --- /dev/null +++ b/web_patient/src/components/Resources/NotificationsPage.tsx @@ -0,0 +1,169 @@ +import { Grid, Switch } from "@mui/material"; +import { sub } from "date-fns"; +import { del, get, set } from "idb-keyval"; +import { action } from "mobx"; +import { observer } from "mobx-react"; +import React, { FunctionComponent, useEffect, useState } from "react"; +import { useNavigate } from "react-router"; +import { IPushSubscription } from "shared/types"; +import { DetailPage } from "src/components/common/DetailPage"; +import { getString } from "src/services/strings"; +import { useStores } from "src/stores/stores"; +import { urlB64ToUint8Array } from "src/utils/notifications"; + +export const NotificationsPage: FunctionComponent = observer(() => { + const rootStore = useStores(); + const { patientStore } = rootStore; + + const navigate = useNavigate(); + + const [enablePushNotification, setEnablePushNotification] = useState(false); + + const handleGoBack = action(() => { + navigate(-1); + }); + + const switchHandler = (event: React.ChangeEvent) => { + if (!!event.target.checked) { + subscribePushNotification(); + } else { + unsubscribePushNotification(); + } + }; + + // Verify if push notification is supported by the browser and disable or enable the toggle accordingly. + const verifyDevicePushNotificationSupport = (): boolean => { + if (!("serviceWorker" in navigator)) { + console.info("Service Worker isn't supported on this browser."); + // TODO: Show message in the UI. + return true; + } + + if (!("PushManager" in window)) { + console.info("Push isn't supported on this browser."); + // TODO: Show message in the UI. + return true; + } + return false; + }; + + const subscribePushNotification = action(async () => { + const result = await Notification.requestPermission(); + if (result === "denied") { + // TODO: Figure out a neat way for the person to enable notifications in case they deny access during the first time the popup comes up. + // Maybe show text in DOM asking them to allow notifications. + // @link https://stackoverflow.com/questions/77209026/turning-on-notification-permission-on-pwa-after-permission-was-denied-in-app-set + console.error("The user explicitly denied the permission request."); + return; + } + if (result === "granted") { + console.info("The user accepted the permission request."); + } + const registration = await navigator.serviceWorker.getRegistration(); + // TODO: What happens if registration is undefined. The push notification toggle can be disabled if service worker couldn't get regsitered. + if (registration) { + const subscribed = await registration.pushManager.getSubscription(); + if (subscribed) { + // NOTE: We should never reach here as we unsubscribe the user when they toggle the switch to off. + console.info("User is already subscribed."); + // Check if the subscription is the same as the one in the IndexedDB. + // TODO: Ensure idbSubscription is defined + const idbSubscription = await get("subscription"); + console.assert( + idbSubscription.endpoint === subscribed.toJSON().endpoint, + "Subscription endpoint in IndexedDB and browser are different." + ); + + setEnablePushNotification(true); + return subscribed; + } + + const subscription = await registration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlB64ToUint8Array( + CLIENT_CONFIG.vapidPublicKey + ), + }); + console.info("Successfully subscribed to push notifications."); + // Add subscription to database. + const addedPushSubscription = + await patientStore.addPushSubscription( + subscription.toJSON() as IPushSubscription + ); + // Save subscription in IndexedDB. + await set("subscription", addedPushSubscription); + // Toggle the switch to on. + setEnablePushNotification(true); + return subscription; + } + }); + + const unsubscribePushNotification = action(async () => { + const registration = await navigator.serviceWorker.getRegistration(); + // TODO: What happens if registration is undefined. The push notification toggle can be disabled if service worker couldn't get registered. + if (registration) { + const subscribed = await registration.pushManager.getSubscription(); + if (subscribed) { + // TODO: Ensure idbSubscription is defined + const idbSubscription = await get("subscription"); + console.assert( + idbSubscription.endpoint === subscribed.toJSON().endpoint, + "Subscription endpoint in IndexedDB and browser are different." + ); + + const unsubscribed = await subscribed.unsubscribe(); + if (unsubscribed) { + console.info( + "Successfully unsubscribed from push notifications." + ); + // Remove subscription from database. + patientStore.deletePushSubscription( + idbSubscription as IPushSubscription + ); + // Remove subscription from IndexedDB. + del("subscription"); + // Toggle the switch to off. + setEnablePushNotification(false); + } + } + } + }); + + // Gets called on page load to get initial state of the push notification toggle. + useEffect(() => { + const checkDevicePushSubscription = action(async () => { + const devicePushSubscription = + await patientStore.checkDevicePushSubscription(); + + setEnablePushNotification(!!devicePushSubscription); + }); + checkDevicePushSubscription(); + }, []); + + return ( + + + Allow Push Notification + + + + + + ); +}); + +export default NotificationsPage; diff --git a/web_patient/src/components/Resources/ResourcesPage.tsx b/web_patient/src/components/Resources/ResourcesPage.tsx index 4e881853..7fc82390 100644 --- a/web_patient/src/components/Resources/ResourcesPage.tsx +++ b/web_patient/src/components/Resources/ResourcesPage.tsx @@ -11,76 +11,83 @@ import { getString } from 'src/services/strings'; import { useStores } from 'src/stores/stores'; export const ResourcesPage: FunctionComponent = () => { - const { authStore } = useStores(); - const navigate = useNavigate(); + const { authStore } = useStores(); + const navigate = useNavigate(); - const onLogout = () => { - authStore.logout(); - navigate(-1); - }; - return ( - -
- - - - - - - - - - - - - - - - - - - - - -
-
- ); + const onLogout = () => { + authStore.logout(); + navigate(-1); + }; + return ( + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+ ); }; export default ResourcesPage; diff --git a/web_patient/src/serviceWorkerRegistration.ts b/web_patient/src/serviceWorkerRegistration.ts index e0648189..a4d838a9 100644 --- a/web_patient/src/serviceWorkerRegistration.ts +++ b/web_patient/src/serviceWorkerRegistration.ts @@ -12,10 +12,10 @@ const isLocalhost = Boolean( window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.0/8 are considered localhost for IPv4. - window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/), + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/), ); type Config = { @@ -37,60 +37,58 @@ export function register(config?: Config) { // eslint-disable-next-line console.log( 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://bit.ly/CRA-PWA', + 'worker. To learn more, visit https://bit.ly/CRA-PWA', ); }); } else { // Is not localhost. Just register service worker - registerValidSW(swUrl, config); + registerValidSWAsync(swUrl, config); } }); } -function registerValidSW(swUrl: string, config?: Config) { - navigator.serviceWorker - .register(swUrl) - .then((registration) => { - registration.onupdatefound = () => { - const installingWorker = registration.installing; - //console.log(installingWorker); - if (installingWorker == null) { - return; - } - installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { - // At this point, the updated precached content has been fetched, - // but the previous service worker will still serve the older - // content until all client tabs are closed. - console.log( - 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://cra.link/PWA.', - ); +const registerValidSWAsync = async (swUrl: string, config?: Config) => { + try { + const registration = await navigator.serviceWorker.register(swUrl); + registration.onupdatefound = () => { + const installingWorker = registration.installing; + //console.log(installingWorker); + if (installingWorker == null) { + return; + } + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See https://cra.link/PWA.', + ); - // Execute callback - if (config && config.onUpdate) { - config.onUpdate(registration); - } - } else { - // At this point, everything has been precached. - // It's the perfect time to display a - // "Content is cached for offline use." message. - console.log('Content is cached for offline use.AnantMittal'); + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration); + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); - // Execute callback - if (config && config.onSuccess) { - config.onSuccess(registration); - } + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration); } } - }; + } }; - }) - .catch((error) => { - console.error('Error during service worker registration:', error); - }); -} + }; + } catch (error) { + console.error('Error during service worker registration:', error); + } +}; function checkValidServiceWorker(swUrl: string, config?: Config) { // Check if the service worker can be found. If it can't reload the page. @@ -109,7 +107,7 @@ function checkValidServiceWorker(swUrl: string, config?: Config) { }); } else { // Service worker found. Proceed as normal. - registerValidSW(swUrl, config); + registerValidSWAsync(swUrl, config); } }) .catch(() => { diff --git a/web_patient/src/services/images.ts b/web_patient/src/services/images.ts index fde31a9a..537491c0 100644 --- a/web_patient/src/services/images.ts +++ b/web_patient/src/services/images.ts @@ -4,6 +4,7 @@ import MoodLoggingImageSrc from 'src/assets/mood_smiley.png'; import MySafetyPlanImageSrc from 'src/assets/safety_plan_icon.png'; import MyValuesInventoryImageSrc from 'src/assets/value_diamond.png'; import MyWorksheetsImageSrc from 'src/assets/resources_folder.png'; +import NotificationsImageSrc from 'src/assets/notifications_icon.png'; import AboutUsImageSrc from 'src/assets/about_us_icon.png'; import CrisisResourcesImageSrc from 'src/assets/crisis_resources_icon.png'; import PhqAssessmentImageSrc from 'src/assets/assessment_phq9_depression.png'; @@ -20,6 +21,7 @@ const _images = { Resources_about_us_button_image: AboutUsImageSrc, Resources_crisis_resources_button_image: CrisisResourcesImageSrc, Resources_logout_button_image: LogoutImageSrc, + Resources_notifications_button_image: NotificationsImageSrc, Progress_activity_button_image: ActivityProgressImageSrc, Progress_assessment_phq_button_image: PhqAssessmentImageSrc, Progress_assessment_gad_button_image: GadAssessmentImageSrc, diff --git a/web_patient/src/services/routes.ts b/web_patient/src/services/routes.ts index cf5143cf..72893dfb 100644 --- a/web_patient/src/services/routes.ts +++ b/web_patient/src/services/routes.ts @@ -9,6 +9,7 @@ export const Routes = { worksheets: 'worksheets', aboutus: 'aboutus', crisisresources: 'crisisresources', + notifications: 'notifications', phqProgress: 'phq', gadProgress: 'gad', activityProgress: 'activities', diff --git a/web_patient/src/services/strings.ts b/web_patient/src/services/strings.ts index f9673cce..005f42c7 100644 --- a/web_patient/src/services/strings.ts +++ b/web_patient/src/services/strings.ts @@ -279,6 +279,8 @@ const _strings = { Resources_crisis_resources_subtitle: 'Crisis resources and hotlines', Resources_logout_title: 'Log out', Resources_logout_subtitle: 'Log out of the app', + Resources_notifications_title: 'Notification Preferences', + Resources_notifications_subtitle: 'Enable or disable app nofications', Safetyplan_title: 'Safety Plan', Safetyplan_reasons_for_living_title: 'Reasons for living', diff --git a/web_patient/src/utils/notifications.ts b/web_patient/src/utils/notifications.ts new file mode 100644 index 00000000..c98026b3 --- /dev/null +++ b/web_patient/src/utils/notifications.ts @@ -0,0 +1,14 @@ +// Convert a base64 string to Uint8Array. +// Must do this so the server can understand the VAPID_PUBLIC_KEY. +export const urlB64ToUint8Array = (base64String: string) => { + const padding = '='.repeat((4 - (base64String.length % 4)) % 4); + const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/'); + + const rawData = window.atob(base64); + const outputArray = new Uint8Array(rawData.length); + + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i); + } + return outputArray; +}; From b53869b789b3be067e91a2591b750d59fcf652ea Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 22:19:54 -0800 Subject: [PATCH 15/22] Add invoke task to trigger push notification --- scope_shared/scope/notifications/__init__.py | 0 scope_shared/scope/notifications/messages.py | 7 ++ .../scope/notifications/webpush_handler.py | 34 +++++++++ .../scope/tasks/webpush_notifications.py | 75 +++++++++++++++++++ tasks/__init__.py | 12 ++- tasks/notifications.py | 30 ++++++++ 6 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 scope_shared/scope/notifications/__init__.py create mode 100644 scope_shared/scope/notifications/messages.py create mode 100644 scope_shared/scope/notifications/webpush_handler.py create mode 100644 scope_shared/scope/tasks/webpush_notifications.py create mode 100644 tasks/notifications.py diff --git a/scope_shared/scope/notifications/__init__.py b/scope_shared/scope/notifications/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/scope_shared/scope/notifications/messages.py b/scope_shared/scope/notifications/messages.py new file mode 100644 index 00000000..87b8d209 --- /dev/null +++ b/scope_shared/scope/notifications/messages.py @@ -0,0 +1,7 @@ +import pymongo.collection + + +def compute_daily_summary( + collection: pymongo.collection.Collection, +): + return "" diff --git a/scope_shared/scope/notifications/webpush_handler.py b/scope_shared/scope/notifications/webpush_handler.py new file mode 100644 index 00000000..90cc50c7 --- /dev/null +++ b/scope_shared/scope/notifications/webpush_handler.py @@ -0,0 +1,34 @@ +"""Module provides a function to trigger a push notification to a web browser.""" +import json +import requests +from pywebpush import webpush, WebPushException +import scope.config +from typing import Union + + +def trigger_push_notification( + vapid_config: scope.config.VapidKeysConfig, + push_subscription: dict, + title: str, + options: dict, +) -> str: + """Function to trigger a push notification to a web browser.""" + try: + subscription_info = { + "endpoint": push_subscription["endpoint"], + "keys": { + "auth": push_subscription["keys"]["auth"], + "p256dh": push_subscription["keys"]["p256dh"], + }, + } + + response = webpush( + subscription_info=subscription_info, + data=json.dumps({"title": title, "options": options}), + vapid_private_key=vapid_config.private_key, + vapid_claims={"sub": f"mailto:{vapid_config.claim_email}"}, + ) + + return repr(response) + except WebPushException as ex: + return str(ex) diff --git a/scope_shared/scope/tasks/webpush_notifications.py b/scope_shared/scope/tasks/webpush_notifications.py new file mode 100644 index 00000000..a7969d7c --- /dev/null +++ b/scope_shared/scope/tasks/webpush_notifications.py @@ -0,0 +1,75 @@ +import aws_infrastructure.tasks.ssh +import contextlib +from invoke import task +from pathlib import Path +from typing import Union + +import scope.config +import scope.database.initialize +import scope.database.database_utils +import scope.database.patient +import scope.documentdb.client +import scope.notifications.messages +import scope.notifications.webpush_handler +import scope.populate +import scope.schema +import scope.schema_utils + + +def task_webpush_notifications( + *, + instance_ssh_config_path: Union[Path, str], + documentdb_config_path: Union[Path, str], + database_config_path: Union[Path, str], + vapid_config_path: Union[Path, str], +): + instance_ssh_config = aws_infrastructure.tasks.ssh.SSHConfig.load( + instance_ssh_config_path + ) + documentdb_config = scope.config.DocumentDBClientConfig.load(documentdb_config_path) + database_config = scope.config.DatabaseClientConfig.load(database_config_path) + vapid_config = scope.config.VapidKeysConfig.load(vapid_config_path) + + @task + def webpush_notifications(context): + """ + Push the notifications. + """ + + # Obtain a database client + with contextlib.ExitStack() as context_manager: + database = scope.documentdb.client.documentdb_client_database( + context_manager=context_manager, + instance_ssh_config=instance_ssh_config, + host=documentdb_config.endpoint, + port=documentdb_config.port, + direct_connection=True, + tls_insecure=True, + database_name=database_config.name, + user=database_config.user, + password=database_config.password, + ) + + patient_collections = scope.database.database_utils.get_patient_collections( + database=database + ) + + for patient_collection in patient_collections: + push_subscriptions = scope.database.patient.get_push_subscriptions( + collection=patient_collection + ) + daily_summary = scope.notifications.messages.compute_daily_summary( + collection=patient_collection + ) + if push_subscriptions: + for push_subscription in push_subscriptions: + webpush_response = scope.notifications.webpush_handler.trigger_push_notification( + vapid_config=vapid_config, + push_subscription=push_subscription, + title="SCOPE Daily Summary", + options={"body": daily_summary}, + ) + print(webpush_response) + # TODO: Store webpush_response in database + + return webpush_notifications diff --git a/tasks/__init__.py b/tasks/__init__.py index a087f707..1fd3f535 100644 --- a/tasks/__init__.py +++ b/tasks/__init__.py @@ -9,6 +9,7 @@ import tasks.documentdb import tasks.dependencies import tasks.notebooks +import tasks.notifications import tasks.server_flask import tasks.web_patient import tasks.web_registry @@ -39,6 +40,9 @@ # Compose from notebooks.py compose_collection(ns, tasks.notebooks.ns, name="notebooks") +# Compose from notifications.py +compose_collection(ns, tasks.notifications.ns, name="notifications") + # Compose from test.py compose_collection(ns, tasks.test.ns, name="test") @@ -59,8 +63,12 @@ # compose_collection(ns_prod_server, tasks.celery.ns.collections["prod"], name="celery") # Compose from server_flask.py -compose_collection(ns_dev_server, tasks.server_flask.ns.collections["dev"], name="flask") -compose_collection(ns_prod_server, tasks.server_flask.ns.collections["prod"], name="flask") +compose_collection( + ns_dev_server, tasks.server_flask.ns.collections["dev"], name="flask" +) +compose_collection( + ns_prod_server, tasks.server_flask.ns.collections["prod"], name="flask" +) compose_collection(ns_dev, ns_dev_server, name="server") compose_collection(ns_prod, ns_prod_server, name="server") diff --git a/tasks/notifications.py b/tasks/notifications.py new file mode 100644 index 00000000..93fe77aa --- /dev/null +++ b/tasks/notifications.py @@ -0,0 +1,30 @@ +""" +Task for executing a webpush notification. +""" + +from pathlib import Path +from invoke import Collection, task + +import aws_infrastructure.tasks.terminal + +import scope.tasks.webpush_notifications + +INSTANCE_SSH_CONFIG_PATH = "./secrets/configuration/instance_ssh.yaml" +DOCUMENTDB_CONFIG_PATH = "./secrets/configuration/documentdb.yaml" +DATABASE_DEV_CONFIG_PATH = "./secrets/configuration/database_dev.yaml" +VAPID_KEYS_CONFIG_PATH = "./secrets/configuration/vapid_keys_local.yaml" + +# Build task collection +ns = Collection("notifications") + + +if Path(DATABASE_DEV_CONFIG_PATH).exists() and Path(VAPID_KEYS_CONFIG_PATH).exists(): + ns.add_task( + scope.tasks.webpush_notifications.task_webpush_notifications( + instance_ssh_config_path=INSTANCE_SSH_CONFIG_PATH, + documentdb_config_path=DOCUMENTDB_CONFIG_PATH, + database_config_path=DATABASE_DEV_CONFIG_PATH, + vapid_config_path=VAPID_KEYS_CONFIG_PATH, + ), + "trigger-push-notification", + ) From bdf3b59e5768aaa973e2f009fd175053eb6cc57b Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 22:25:13 -0800 Subject: [PATCH 16/22] Flask: add/update push subscription --- server_flask/app.py | 8 +- .../blueprints/patient/push_subscriptions.py | 46 +++ .../test_flask/registry/test_patient_set.py | 367 +++++++++--------- 3 files changed, 233 insertions(+), 188 deletions(-) diff --git a/server_flask/app.py b/server_flask/app.py index d03ac562..5946f76a 100644 --- a/server_flask/app.py +++ b/server_flask/app.py @@ -8,8 +8,7 @@ import blueprints.identities import blueprints.app.config import blueprints.patient.summary -import blueprints.patient.notification_permissions -import blueprints.patient.push_subscriptions + import blueprints.registry.activities import blueprints.registry.activity_logs import blueprints.registry.activity_schedules @@ -21,6 +20,7 @@ import blueprints.registry.patient_profile import blueprints.registry.patients import blueprints.registry.providers +import blueprints.patient.push_subscriptions import blueprints.registry.safety_plan import blueprints.registry.sessions import blueprints.registry.scheduled_activities @@ -135,10 +135,6 @@ def status(): blueprints.registry.mood_logs.mood_logs_blueprint, url_prefix="/patient/", ) - app.register_blueprint( - blueprints.patient.notification_permissions.notification_permissions_blueprint, - url_prefix="/patient/", - ) app.register_blueprint( blueprints.registry.assessments.assessments_blueprint, url_prefix="/patient/", diff --git a/server_flask/blueprints/patient/push_subscriptions.py b/server_flask/blueprints/patient/push_subscriptions.py index 7363a5ec..c7854b41 100644 --- a/server_flask/blueprints/patient/push_subscriptions.py +++ b/server_flask/blueprints/patient/push_subscriptions.py @@ -5,6 +5,7 @@ import request_context import request_utils import scope.database +from scope.database import collection_utils import scope.database.patient.push_subscriptions import scope.schema @@ -156,3 +157,48 @@ def put_push_subscription(patient_id, pushsubscription_id): return { "pushsubscription": document_response, } + + +@push_subscriptions_blueprint.route( + "//pushsubscription/", + methods=["DELETE"], +) +@flask_json.as_json +def delete_push_subscription(patient_id, pushsubscription_id): + context = request_context.authorized_for_patient(patient_id=patient_id) + patient_collection = context.patient_collection(patient_id=patient_id) + + # Obtain the _rev being deleted + if_match_header = flask.request.headers.get("If-Match") + if if_match_header is None: + request_utils.abort_delete_without_if_match_header() + rev = int(if_match_header) + + # Delete the document + try: + result = scope.database.patient.push_subscriptions.delete_push_subscription( + collection=patient_collection, + set_id=pushsubscription_id, + rev=rev, + ) + except collection_utils.DocumentNotFoundException: + # The document may have never existed or may have already been deleted + request_utils.abort_document_not_found() + except collection_utils.DocumentModifiedException as e: + # Indicates a revision race condition, return error with current revision + document_existing = e.document_existing + + request_utils.abort_revision_conflict( + document={ + "pushsubscription": document_existing, + } + ) + else: + # Validate and normalize the response + document_response = request_utils.singleton_put_response_validate( + document=result.document, + ) + + return { + "pushsubscription": document_response, + } diff --git a/server_flask/tests/test_flask/registry/test_patient_set.py b/server_flask/tests/test_flask/registry/test_patient_set.py index 76f1e3ea..404fd705 100644 --- a/server_flask/tests/test_flask/registry/test_patient_set.py +++ b/server_flask/tests/test_flask/registry/test_patient_set.py @@ -77,121 +77,121 @@ class ConfigTestPatientSet: TEST_CONFIGS = [ - # ConfigTestPatientSet( - # name="activities", - # semantic_set_id=scope.database.patient.activities.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_activity_factory", - # document_factory_fixture_set="data_fake_activities_factory", - # database_get_set_function=scope.database.patient.activities.get_activities, - # database_get_function=scope.database.patient.activities.get_activity, - # database_post_function=scope.database.patient.activities.post_activity, - # database_unsafe_update_function=None, - # database_document_parameter_name="activity", - # flask_query_set_type="activities", - # flask_document_set_key="activities", - # flask_query_set_element_type="activity", - # flask_document_set_element_key="activity", - # options=ConfigTestPatientSetOptions( - # set_supports_deletion=True, - # ), - # ), - # ConfigTestPatientSet( - # name="activitylogs", - # semantic_set_id=scope.database.patient.activity_logs.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_activity_log_factory", - # document_factory_fixture_set="data_fake_activity_logs_factory", - # database_get_set_function=scope.database.patient.activity_logs.get_activity_logs, - # database_get_function=scope.database.patient.activity_logs.get_activity_log, - # database_post_function=scope.database.patient.activity_logs.post_activity_log, - # database_unsafe_update_function=None, - # database_document_parameter_name="activity_log", - # flask_query_set_type="activitylogs", - # flask_document_set_key="activitylogs", - # flask_query_set_element_type="activitylog", - # flask_document_set_element_key="activitylog", - # ), - # ConfigTestPatientSet( - # name="activityschedules", - # semantic_set_id=scope.database.patient.activity_schedules.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_activity_schedule_factory", - # document_factory_fixture_set="data_fake_activity_schedules_factory", - # database_get_set_function=scope.database.patient.activity_schedules.get_activity_schedules, - # database_get_function=scope.database.patient.activity_schedules.get_activity_schedule, - # database_post_function=scope.database.patient.activity_schedules.post_activity_schedule, - # database_unsafe_update_function=None, - # database_document_parameter_name="activity_schedule", - # flask_query_set_type="activityschedules", - # flask_document_set_key="activityschedules", - # flask_query_set_element_type="activityschedule", - # flask_document_set_element_key="activityschedule", - # options=ConfigTestPatientSetOptions( - # set_supports_deletion=True, - # ), - # ), - # ConfigTestPatientSet( - # name="assessments", - # semantic_set_id=scope.database.patient.assessments.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_assessment_factory", - # document_factory_fixture_set="data_fake_assessments_factory", - # database_get_set_function=scope.database.patient.assessments.get_assessments, - # database_get_function=scope.database.patient.assessments.get_assessment, - # database_post_function=None, # Assessments have fixed set IDs - # database_unsafe_update_function=scope.database.patient_unsafe_utils.unsafe_update_assessment, - # database_document_parameter_name="assessment", - # flask_query_set_type="assessments", - # flask_document_set_key="assessments", - # flask_query_set_element_type="assessment", - # flask_document_set_element_key="assessment", - # options=ConfigTestPatientSetOptions( - # set_id_will_already_exist=True, - # set_element_will_already_exist=True, - # ), - # ), - # ConfigTestPatientSet( - # name="assessmentlogs", - # semantic_set_id=scope.database.patient.assessment_logs.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_assessment_log_factory", - # document_factory_fixture_set="data_fake_assessment_logs_factory", - # database_get_set_function=scope.database.patient.assessment_logs.get_assessment_logs, - # database_get_function=scope.database.patient.assessment_logs.get_assessment_log, - # database_post_function=scope.database.patient.assessment_logs.post_assessment_log, - # database_unsafe_update_function=None, - # database_document_parameter_name="assessment_log", - # flask_query_set_type="assessmentlogs", - # flask_document_set_key="assessmentlogs", - # flask_query_set_element_type="assessmentlog", - # flask_document_set_element_key="assessmentlog", - # ), - # ConfigTestPatientSet( - # name="casereviews", - # semantic_set_id=scope.database.patient.case_reviews.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_case_review_factory", - # document_factory_fixture_set="data_fake_case_reviews_factory", - # database_get_set_function=scope.database.patient.case_reviews.get_case_reviews, - # database_get_function=scope.database.patient.case_reviews.get_case_review, - # database_post_function=scope.database.patient.case_reviews.post_case_review, - # database_unsafe_update_function=None, - # database_document_parameter_name="case_review", - # flask_query_set_type="casereviews", - # flask_document_set_key="casereviews", - # flask_query_set_element_type="casereview", - # flask_document_set_element_key="casereview", - # ), - # ConfigTestPatientSet( - # name="moodlogs", - # semantic_set_id=scope.database.patient.mood_logs.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_mood_log_factory", - # document_factory_fixture_set="data_fake_mood_logs_factory", - # database_get_set_function=scope.database.patient.mood_logs.get_mood_logs, - # database_get_function=scope.database.patient.mood_logs.get_mood_log, - # database_post_function=scope.database.patient.mood_logs.post_mood_log, - # database_unsafe_update_function=None, - # database_document_parameter_name="mood_log", - # flask_query_set_type="moodlogs", - # flask_document_set_key="moodlogs", - # flask_query_set_element_type="moodlog", - # flask_document_set_element_key="moodlog", - # ), + ConfigTestPatientSet( + name="activities", + semantic_set_id=scope.database.patient.activities.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_activity_factory", + document_factory_fixture_set="data_fake_activities_factory", + database_get_set_function=scope.database.patient.activities.get_activities, + database_get_function=scope.database.patient.activities.get_activity, + database_post_function=scope.database.patient.activities.post_activity, + database_unsafe_update_function=None, + database_document_parameter_name="activity", + flask_query_set_type="activities", + flask_document_set_key="activities", + flask_query_set_element_type="activity", + flask_document_set_element_key="activity", + options=ConfigTestPatientSetOptions( + set_supports_deletion=True, + ), + ), + ConfigTestPatientSet( + name="activitylogs", + semantic_set_id=scope.database.patient.activity_logs.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_activity_log_factory", + document_factory_fixture_set="data_fake_activity_logs_factory", + database_get_set_function=scope.database.patient.activity_logs.get_activity_logs, + database_get_function=scope.database.patient.activity_logs.get_activity_log, + database_post_function=scope.database.patient.activity_logs.post_activity_log, + database_unsafe_update_function=None, + database_document_parameter_name="activity_log", + flask_query_set_type="activitylogs", + flask_document_set_key="activitylogs", + flask_query_set_element_type="activitylog", + flask_document_set_element_key="activitylog", + ), + ConfigTestPatientSet( + name="activityschedules", + semantic_set_id=scope.database.patient.activity_schedules.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_activity_schedule_factory", + document_factory_fixture_set="data_fake_activity_schedules_factory", + database_get_set_function=scope.database.patient.activity_schedules.get_activity_schedules, + database_get_function=scope.database.patient.activity_schedules.get_activity_schedule, + database_post_function=scope.database.patient.activity_schedules.post_activity_schedule, + database_unsafe_update_function=None, + database_document_parameter_name="activity_schedule", + flask_query_set_type="activityschedules", + flask_document_set_key="activityschedules", + flask_query_set_element_type="activityschedule", + flask_document_set_element_key="activityschedule", + options=ConfigTestPatientSetOptions( + set_supports_deletion=True, + ), + ), + ConfigTestPatientSet( + name="assessments", + semantic_set_id=scope.database.patient.assessments.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_assessment_factory", + document_factory_fixture_set="data_fake_assessments_factory", + database_get_set_function=scope.database.patient.assessments.get_assessments, + database_get_function=scope.database.patient.assessments.get_assessment, + database_post_function=None, # Assessments have fixed set IDs + database_unsafe_update_function=scope.database.patient_unsafe_utils.unsafe_update_assessment, + database_document_parameter_name="assessment", + flask_query_set_type="assessments", + flask_document_set_key="assessments", + flask_query_set_element_type="assessment", + flask_document_set_element_key="assessment", + options=ConfigTestPatientSetOptions( + set_id_will_already_exist=True, + set_element_will_already_exist=True, + ), + ), + ConfigTestPatientSet( + name="assessmentlogs", + semantic_set_id=scope.database.patient.assessment_logs.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_assessment_log_factory", + document_factory_fixture_set="data_fake_assessment_logs_factory", + database_get_set_function=scope.database.patient.assessment_logs.get_assessment_logs, + database_get_function=scope.database.patient.assessment_logs.get_assessment_log, + database_post_function=scope.database.patient.assessment_logs.post_assessment_log, + database_unsafe_update_function=None, + database_document_parameter_name="assessment_log", + flask_query_set_type="assessmentlogs", + flask_document_set_key="assessmentlogs", + flask_query_set_element_type="assessmentlog", + flask_document_set_element_key="assessmentlog", + ), + ConfigTestPatientSet( + name="casereviews", + semantic_set_id=scope.database.patient.case_reviews.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_case_review_factory", + document_factory_fixture_set="data_fake_case_reviews_factory", + database_get_set_function=scope.database.patient.case_reviews.get_case_reviews, + database_get_function=scope.database.patient.case_reviews.get_case_review, + database_post_function=scope.database.patient.case_reviews.post_case_review, + database_unsafe_update_function=None, + database_document_parameter_name="case_review", + flask_query_set_type="casereviews", + flask_document_set_key="casereviews", + flask_query_set_element_type="casereview", + flask_document_set_element_key="casereview", + ), + ConfigTestPatientSet( + name="moodlogs", + semantic_set_id=scope.database.patient.mood_logs.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_mood_log_factory", + document_factory_fixture_set="data_fake_mood_logs_factory", + database_get_set_function=scope.database.patient.mood_logs.get_mood_logs, + database_get_function=scope.database.patient.mood_logs.get_mood_log, + database_post_function=scope.database.patient.mood_logs.post_mood_log, + database_unsafe_update_function=None, + database_document_parameter_name="mood_log", + flask_query_set_type="moodlogs", + flask_document_set_key="moodlogs", + flask_query_set_element_type="moodlog", + flask_document_set_element_key="moodlog", + ), ConfigTestPatientSet( name="pushsubscriptions", semantic_set_id=scope.database.patient.push_subscriptions.SEMANTIC_SET_ID, @@ -206,74 +206,77 @@ class ConfigTestPatientSet: flask_document_set_key="pushsubscriptions", flask_query_set_element_type="pushsubscription", flask_document_set_element_key="pushsubscription", + options=ConfigTestPatientSetOptions( + set_supports_deletion=True, + ), + ), + ConfigTestPatientSet( + name="sessions", + semantic_set_id=scope.database.patient.sessions.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_session_factory", + document_factory_fixture_set="data_fake_sessions_factory", + database_get_set_function=scope.database.patient.sessions.get_sessions, + database_get_function=scope.database.patient.sessions.get_session, + database_post_function=scope.database.patient.sessions.post_session, + database_unsafe_update_function=None, + database_document_parameter_name="session", + flask_query_set_type="sessions", + flask_document_set_key="sessions", + flask_query_set_element_type="session", + flask_document_set_element_key="session", + ), + ConfigTestPatientSet( + name="scheduledactivities", + semantic_set_id=scope.database.patient.scheduled_activities.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_scheduled_activity_factory", + document_factory_fixture_set="data_fake_scheduled_activities_factory", + database_get_set_function=scope.database.patient.scheduled_activities.get_scheduled_activities, + database_get_function=scope.database.patient.scheduled_activities.get_scheduled_activity, + database_post_function=scope.database.patient.scheduled_activities.post_scheduled_activity, + database_unsafe_update_function=None, + database_document_parameter_name="scheduled_activity", + flask_query_set_type="scheduledactivities", + flask_document_set_key="scheduledactivities", + flask_query_set_element_type="scheduledactivity", + flask_document_set_element_key="scheduledactivity", + ), + ConfigTestPatientSet( + name="scheduledassessments", + semantic_set_id=scope.database.patient.scheduled_assessments.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_scheduled_assessment_factory", + document_factory_fixture_set="data_fake_scheduled_assessments_factory", + database_get_set_function=scope.database.patient.scheduled_assessments.get_scheduled_assessments, + database_get_function=scope.database.patient.scheduled_assessments.get_scheduled_assessment, + database_post_function=scope.database.patient.scheduled_assessments.post_scheduled_assessment, + database_unsafe_update_function=None, + database_document_parameter_name="scheduled_assessment", + flask_query_set_type="scheduledassessments", + flask_document_set_key="scheduledassessments", + flask_query_set_element_type="scheduledassessment", + flask_document_set_element_key="scheduledassessment", + options=ConfigTestPatientSetOptions( + set_id_will_already_exist=False, + set_element_will_already_exist=True, + ), + ), + ConfigTestPatientSet( + name="values", + semantic_set_id=scope.database.patient.values.SEMANTIC_SET_ID, + document_factory_fixture_set_element="data_fake_value_factory", + document_factory_fixture_set="data_fake_values_factory", + database_get_set_function=scope.database.patient.values.get_values, + database_get_function=scope.database.patient.values.get_value, + database_post_function=scope.database.patient.values.post_value, + database_unsafe_update_function=None, + database_document_parameter_name="value", + flask_query_set_type="values", + flask_document_set_key="values", + flask_query_set_element_type="value", + flask_document_set_element_key="value", + options=ConfigTestPatientSetOptions( + set_supports_deletion=True, + ), ), - # ConfigTestPatientSet( - # name="sessions", - # semantic_set_id=scope.database.patient.sessions.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_session_factory", - # document_factory_fixture_set="data_fake_sessions_factory", - # database_get_set_function=scope.database.patient.sessions.get_sessions, - # database_get_function=scope.database.patient.sessions.get_session, - # database_post_function=scope.database.patient.sessions.post_session, - # database_unsafe_update_function=None, - # database_document_parameter_name="session", - # flask_query_set_type="sessions", - # flask_document_set_key="sessions", - # flask_query_set_element_type="session", - # flask_document_set_element_key="session", - # ), - # ConfigTestPatientSet( - # name="scheduledactivities", - # semantic_set_id=scope.database.patient.scheduled_activities.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_scheduled_activity_factory", - # document_factory_fixture_set="data_fake_scheduled_activities_factory", - # database_get_set_function=scope.database.patient.scheduled_activities.get_scheduled_activities, - # database_get_function=scope.database.patient.scheduled_activities.get_scheduled_activity, - # database_post_function=scope.database.patient.scheduled_activities.post_scheduled_activity, - # database_unsafe_update_function=None, - # database_document_parameter_name="scheduled_activity", - # flask_query_set_type="scheduledactivities", - # flask_document_set_key="scheduledactivities", - # flask_query_set_element_type="scheduledactivity", - # flask_document_set_element_key="scheduledactivity", - # ), - # ConfigTestPatientSet( - # name="scheduledassessments", - # semantic_set_id=scope.database.patient.scheduled_assessments.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_scheduled_assessment_factory", - # document_factory_fixture_set="data_fake_scheduled_assessments_factory", - # database_get_set_function=scope.database.patient.scheduled_assessments.get_scheduled_assessments, - # database_get_function=scope.database.patient.scheduled_assessments.get_scheduled_assessment, - # database_post_function=scope.database.patient.scheduled_assessments.post_scheduled_assessment, - # database_unsafe_update_function=None, - # database_document_parameter_name="scheduled_assessment", - # flask_query_set_type="scheduledassessments", - # flask_document_set_key="scheduledassessments", - # flask_query_set_element_type="scheduledassessment", - # flask_document_set_element_key="scheduledassessment", - # options=ConfigTestPatientSetOptions( - # set_id_will_already_exist=False, - # set_element_will_already_exist=True, - # ), - # ), - # ConfigTestPatientSet( - # name="values", - # semantic_set_id=scope.database.patient.values.SEMANTIC_SET_ID, - # document_factory_fixture_set_element="data_fake_value_factory", - # document_factory_fixture_set="data_fake_values_factory", - # database_get_set_function=scope.database.patient.values.get_values, - # database_get_function=scope.database.patient.values.get_value, - # database_post_function=scope.database.patient.values.post_value, - # database_unsafe_update_function=None, - # database_document_parameter_name="value", - # flask_query_set_type="values", - # flask_document_set_key="values", - # flask_query_set_element_type="value", - # flask_document_set_element_key="value", - # options=ConfigTestPatientSetOptions( - # set_supports_deletion=True, - # ), - # ), ] QUERY_SET = "patient/{patient_id}/{query_type}" From 8e77d7fc8ac32c3570a74b2773528075236f07f7 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 22:26:19 -0800 Subject: [PATCH 17/22] Update push subscriptions fixtures --- scope_shared/scope/testing/__init__.py | 1 - .../fixtures_fake_push_subscription.py | 64 +++++++++++++++++++ .../fixtures_fake_push_subscriptions.py | 51 +++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 scope_shared/scope/testing/fake_data/fixtures_fake_push_subscription.py create mode 100644 scope_shared/scope/testing/fake_data/fixtures_fake_push_subscriptions.py diff --git a/scope_shared/scope/testing/__init__.py b/scope_shared/scope/testing/__init__.py index 43a730da..02a5abfe 100644 --- a/scope_shared/scope/testing/__init__.py +++ b/scope_shared/scope/testing/__init__.py @@ -17,7 +17,6 @@ "scope.testing.fake_data.fixtures_fake_life_area_contents", "scope.testing.fake_data.fixtures_fake_mood_log", "scope.testing.fake_data.fixtures_fake_mood_logs", - "scope.testing.fake_data.fixtures_fake_notification_permissions", "scope.testing.fake_data.fixtures_fake_patient_profile", "scope.testing.fake_data.fixtures_fake_provider_identity", "scope.testing.fake_data.fixtures_fake_push_subscription", diff --git a/scope_shared/scope/testing/fake_data/fixtures_fake_push_subscription.py b/scope_shared/scope/testing/fake_data/fixtures_fake_push_subscription.py new file mode 100644 index 00000000..7384bd2b --- /dev/null +++ b/scope_shared/scope/testing/fake_data/fixtures_fake_push_subscription.py @@ -0,0 +1,64 @@ +import datetime +import faker +import pytest +import random +from typing import Callable + +import scope.database.date_utils as date_utils +import scope.database.patient.push_subscriptions +import scope.enums +import scope.schema +import scope.schema_utils +import scope.testing.fake_data.fake_utils as fake_utils + + +def fake_push_subscription_factory( + *, + faker_factory: faker.Faker, + fake_referral_status_factory: Callable[[], dict], +) -> Callable[[], dict]: + """ + Obtain a factory that will generate fake push subscription documents. + """ + + def factory() -> dict: + fake_push_subscription = { + "_type": scope.database.patient.push_subscriptions.DOCUMENT_TYPE, + "endpoint": faker_factory.url(), + "expirationTime": random.choice([faker_factory.random_number(), None]), + "keys": { + "p256dh": faker_factory.text(), + "auth": faker_factory.text(), + }, + } + + return fake_push_subscription + + return factory + + +@pytest.fixture(name="data_fake_push_subscription_factory") +def fixture_data_fake_push_subscription_factory( + faker: faker.Faker, + data_fake_referral_status_factory: Callable[[], dict], +) -> Callable[[], dict]: + """ + Fixture for data_fake_push_subscription_factory. + """ + + unvalidated_factory = fake_push_subscription_factory( + faker_factory=faker, + fake_referral_status_factory=data_fake_referral_status_factory, + ) + + def factory() -> dict: + fake_push_subscription = unvalidated_factory() + + scope.schema_utils.xfail_for_invalid_schema( + schema=scope.schema.push_subscription_schema, + data=fake_push_subscription, + ) + + return fake_push_subscription + + return factory diff --git a/scope_shared/scope/testing/fake_data/fixtures_fake_push_subscriptions.py b/scope_shared/scope/testing/fake_data/fixtures_fake_push_subscriptions.py new file mode 100644 index 00000000..01de3e71 --- /dev/null +++ b/scope_shared/scope/testing/fake_data/fixtures_fake_push_subscriptions.py @@ -0,0 +1,51 @@ +import pytest +import random +from typing import Callable, List + +import scope.database.document_utils as document_utils +import scope.schema +import scope.schema_utils +import scope.testing.fake_data.fake_utils as fake_utils + + +def fake_push_subscriptions_factory( + *, + fake_push_subscription_factory: Callable[[], dict], +) -> Callable[[], List[dict]]: + """ + Obtain a factory that will generate a list of fake push subscription documents. + """ + + def factory() -> List[dict]: + fake_push_subscriptions = [ + fake_push_subscription_factory() for _ in range(random.randint(1, 5)) + ] + + return fake_push_subscriptions + + return factory + + +@pytest.fixture(name="data_fake_push_subscriptions_factory") +def fixture_data_fake_push_subscriptions_factory( + data_fake_push_subscription_factory: Callable[[], dict], +) -> Callable[[], List[dict]]: + """ + Fixture for data_fake_push_subscriptions_factory. + """ + + unvalidated_factory = fake_push_subscriptions_factory( + fake_push_subscription_factory=data_fake_push_subscription_factory, + ) + + def factory() -> List[dict]: + fake_push_subscriptions = unvalidated_factory() + + scope.schema_utils.xfail_for_invalid_schema( + schema=scope.schema.push_subscriptions_schema, + data=fake_push_subscriptions, + ) + + return fake_push_subscriptions + + return factory From b424b2bf88d53348baeb9a3faccd752d3dac5747 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 22:27:10 -0800 Subject: [PATCH 18/22] Update database layer --- scope_shared/scope/database/database_utils.py | 36 +++++++++++++++++++ .../scope/database/patient/__init__.py | 4 --- .../database/patient/push_subscriptions.py | 18 ++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 scope_shared/scope/database/database_utils.py diff --git a/scope_shared/scope/database/database_utils.py b/scope_shared/scope/database/database_utils.py new file mode 100644 index 00000000..73bf0f60 --- /dev/null +++ b/scope_shared/scope/database/database_utils.py @@ -0,0 +1,36 @@ +import pymongo.collection +import pymongo.database + +from typing import List, Optional + +import scope.database.date_utils as date_utils +import scope.database.collection_utils +import scope.database.patient.assessments +import scope.database.patient.clinical_history +import scope.database.patient.patient_profile +import scope.database.patient.safety_plan +import scope.database.patient.values_inventory +import scope.enums +import scope.schema +import scope.schema_utils as schema_utils + + +def get_patient_collections( + *, + database: pymongo.database.Database, +) -> Optional[List[pymongo.collection.Collection]]: + """ + Retrieve all patient collections documents. + """ + + collection_names = database.list_collection_names() + + patient_collection_names = list( + filter(lambda cn: "patient_" in cn, collection_names) + ) + + patient_collections: List[pymongo.collection.Collection] = [] + for patient_collection_name in patient_collection_names: + patient_collections.append(database.get_collection(patient_collection_name)) + + return patient_collections diff --git a/scope_shared/scope/database/patient/__init__.py b/scope_shared/scope/database/patient/__init__.py index 0454922c..60d28992 100644 --- a/scope_shared/scope/database/patient/__init__.py +++ b/scope_shared/scope/database/patient/__init__.py @@ -31,10 +31,6 @@ post_mood_log, put_mood_log, ) -from scope.database.patient.notification_permissions import ( - get_notification_permissions, - put_notification_permissions, -) from scope.database.patient.patient_profile import ( get_patient_profile, put_patient_profile, diff --git a/scope_shared/scope/database/patient/push_subscriptions.py b/scope_shared/scope/database/patient/push_subscriptions.py index 5aa94713..49a4cc02 100644 --- a/scope_shared/scope/database/patient/push_subscriptions.py +++ b/scope_shared/scope/database/patient/push_subscriptions.py @@ -7,6 +7,24 @@ SEMANTIC_SET_ID = "pushSubscriptionId" +def delete_push_subscription( + *, + collection: pymongo.collection.Collection, + set_id: str, + rev: int, +) -> scope.database.collection_utils.SetPutResult: + """ + Delete "push-subscription" document. + """ + + return scope.database.collection_utils.delete_set_element( + collection=collection, + document_type=DOCUMENT_TYPE, + set_id=set_id, + rev=rev, + ) + + def get_push_subscriptions( *, collection: pymongo.collection.Collection, From 3cc04d88b0b44b8d41d88c3badd4778156dc2a35 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 22:27:41 -0800 Subject: [PATCH 19/22] Add web push schema to store webpush responses --- .../scope/schemas/documents/web-push.json | 34 +++++++++++++++++++ .../scope/schemas/documents/web-pushes.json | 9 +++++ 2 files changed, 43 insertions(+) create mode 100644 scope_shared/scope/schemas/documents/web-push.json create mode 100644 scope_shared/scope/schemas/documents/web-pushes.json diff --git a/scope_shared/scope/schemas/documents/web-push.json b/scope_shared/scope/schemas/documents/web-push.json new file mode 100644 index 00000000..555d8db7 --- /dev/null +++ b/scope_shared/scope/schemas/documents/web-push.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://uwscope.org/schemas/documents/web-push", + "title": "Webpush Details", + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "_type": { + "const": "webpushResponse" + }, + "_set_id": { + "type": "string" + }, + "_rev": { + "type": "number" + }, + "webPushId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "response": { + "type": "string" + }, + "editedDateTime": { + "$ref": "/schemas/utils/datetime#/properties/datetime" + } + }, + "additionalProperties": false, + "required": ["_type", "message", "response", "editedDateTime"] +} diff --git a/scope_shared/scope/schemas/documents/web-pushes.json b/scope_shared/scope/schemas/documents/web-pushes.json new file mode 100644 index 00000000..15b62b9c --- /dev/null +++ b/scope_shared/scope/schemas/documents/web-pushes.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://uwscope.org/schemas/documents/web-pushes", + "title": "Webpush Details", + "type": "array", + "items": { + "$ref": "/schemas/documents/web-push" + } +} From f5a74391efceb873869568d12ec37aade2a9e268 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Tue, 28 Nov 2023 22:28:06 -0800 Subject: [PATCH 20/22] Add vapid config to scope_shared --- scope_shared/scope/config/__init__.py | 1 + scope_shared/scope/config/vapid.py | 33 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 scope_shared/scope/config/vapid.py diff --git a/scope_shared/scope/config/__init__.py b/scope_shared/scope/config/__init__.py index 2bdfac5e..0368f664 100644 --- a/scope_shared/scope/config/__init__.py +++ b/scope_shared/scope/config/__init__.py @@ -6,3 +6,4 @@ from scope.config.documentdb import DocumentDBConfig from scope.config.flask import FlaskClientConfig from scope.config.flask import FlaskConfig +from scope.config.vapid import VapidKeysConfig diff --git a/scope_shared/scope/config/vapid.py b/scope_shared/scope/config/vapid.py new file mode 100644 index 00000000..8f3d73ff --- /dev/null +++ b/scope_shared/scope/config/vapid.py @@ -0,0 +1,33 @@ +from dataclasses import dataclass +from pathlib import Path +import ruamel.yaml +from typing import Union + + +@dataclass(frozen=True) +class VapidKeysConfig: + """ + Configuration for vapid keys. + """ + + public_key: str + private_key: str + claim_email: str + + @staticmethod + def load(config_path: Union[Path, str]): + config_path = Path(config_path) + + with open(config_path) as config_file: + yaml = ruamel.yaml.YAML(typ="safe", pure=True) + config_dict = yaml.load(config_file) + + return VapidKeysConfig.parse(config_dict) + + @staticmethod + def parse(config_dict: dict): + return VapidKeysConfig( + public_key=config_dict["vapid_public_key"], + private_key=config_dict["vapid_private_key"], + claim_email=config_dict["vapid_claim_email"], + ) From 1fdfb0b41d2a583a43a2e564f5d2f0559d7a1c2c Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Mon, 26 Feb 2024 15:57:08 -0800 Subject: [PATCH 21/22] Fix web_patient package.json --- web_patient/package.json | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/web_patient/package.json b/web_patient/package.json index b39c0dd3..a3f36331 100644 --- a/web_patient/package.json +++ b/web_patient/package.json @@ -1,5 +1,5 @@ { - "name": "scope-patient", + "name": "web-patient", "scripts": { "dev_serve": "node scripts/dev_serve.js", "prod_build": "node scripts/prod_build.js", @@ -10,23 +10,22 @@ "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest" }, "dependencies": { - "@babel/polyfill": "^7.12.1", - "@date-io/date-fns": "1.x", + "@babel/polyfill": "7.12.x", + "@date-io/date-fns": "1.3.x", "@mui/icons-material": "5.3.1", - "@mui/lab": "^5.0.0-alpha.66", + "@mui/lab": "5.0.0-alpha.66", "@mui/material": "5.3.1", "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest", "@mui/styled-engine-sc": "5.3.0", - "@mui/styles": "5.3.0", - "@types/node": "17.0.x", - "amazon-cognito-identity-js": "^5.2.6", + "@mui/styles": "5.3.x", + "amazon-cognito-identity-js": "5.2.x", "axios": "0.25.x", - "date-fns": "2.28.0", - "idb-keyval": "^6.2.1", - "lodash": "4.17.21", - "lodash.debounce": "4.0.8", - "lodash.throttle": "4.1.1", - "lorem-ipsum": "^2.0.3", + "date-fns": "2.28.x", + "idb-keyval": "^6.2.x", + "lodash": "4.17.x", + "lodash.debounce": "4.0.x", + "lodash.throttle": "4.1.x", + "lorem-ipsum": "2.0.x", "mobx": "6.3.x", "mobx-react": "7.2.x", "react": "17.0.x", @@ -34,7 +33,7 @@ "react-router": "6.2.x", "react-router-dom": "6.2.x", "styled-components": "5.3.3", - "url": "^0.11.0", + "url": "0.11.x", "workbox-precaching": "*", "workbox-routing": "*" }, @@ -42,22 +41,23 @@ "@babel/core": "7.12.x", "@babel/preset-env": "7.12.x", "@babel/preset-react": "7.12.x", - "@types/lodash.debounce": "^4.0.6", - "@types/lodash.throttle": "^4.1.6", - "@types/lorem-ipsum": "^2.0.0", + "@types/lodash.debounce": "4.0.x", + "@types/lodash.throttle": "4.1.x", + "@types/lorem-ipsum": "2.0.x", + "@types/node": "17.0.x", "@types/react": "17.0.x", "@types/react-dom": "17.0.x", - "@types/react-router": "^5.1.11", - "@types/react-router-dom": "^5.1.7", - "@types/styled-components": "^5.1.7", + "@types/react-router": "5.1.18", + "@types/react-router-dom": "5.3.3", + "@types/styled-components": "5.1.21", "babel-loader": "8.2.x", - "copy-webpack-plugin": "^9.0.1", + "copy-webpack-plugin": "9.1.0", "express": "4.17.x", - "html-webpack-plugin": "^5.5.0", + "html-webpack-plugin": "5.5.x", "rimraf": "3.0.x", "ts-loader": "8.0.x", - "tsconfig-paths-webpack-plugin": "^3.3.0", - "typescript": "4.5.5", + "tsconfig-paths-webpack-plugin": "3.5.2", + "typescript": "4.5.x", "webpack": "5.x", "webpack-cli": "5.x", "webpack-dev-middleware": "6.x", From a3a227889ccf7c6ec5a6d9aee5f28dc809315f76 Mon Sep 17 00:00:00 2001 From: Anant Mittal Date: Mon, 26 Feb 2024 15:58:25 -0800 Subject: [PATCH 22/22] Update web_patient yarn.lock file --- web_patient/yarn.lock | 246 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 223 insertions(+), 23 deletions(-) diff --git a/web_patient/yarn.lock b/web_patient/yarn.lock index 0f601ce5..d05648be 100644 --- a/web_patient/yarn.lock +++ b/web_patient/yarn.lock @@ -200,6 +200,15 @@ regexpu-core "^5.3.1" semver "^6.3.1" +"@babel/helper-create-regexp-features-plugin@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" + integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" + "@babel/helper-define-polyfill-provider@^0.4.2": version "0.4.2" resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz#82c825cadeeeee7aad237618ebbe8fa1710015d7" @@ -1434,6 +1443,22 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-unicode-regex@^7.22.5": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz#26897708d8f42654ca4ce1b73e96140fbad879dc" + integrity sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-sets-regex@^7.22.5": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz#4fb6f0a719c2c5859d11f6b55a050cc987f3799e" + integrity sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/polyfill@7.12.x": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.12.1.tgz#1f2d6371d1261bbd961f3c5d5909150e12d0bd96" @@ -1722,10 +1747,10 @@ resolved "https://registry.yarnpkg.com/@date-io/core/-/core-1.3.13.tgz#90c71da493f20204b7a972929cc5c482d078b3fa" integrity sha512-AlEKV7TxjeK+jxWVKcCFrfYAk8spX9aCyiToFIiLPtfQbsjmRGLIhb5VZgptQcJdHtLXo7+m0DuurwFgUToQuA== -"@date-io/core@^2.13.1": - version "2.13.1" - resolved "https://registry.yarnpkg.com/@date-io/core/-/core-2.13.1.tgz#f041765aff5c55fbc7e37fdd75fc1792733426d6" - integrity sha512-pVI9nfkf2qClb2Cxdq0Q4zJhdawMG4ybWZUVGifT78FDwzRMX2SwXBb55s5NRJk0HcIicDuxktmCtemZqMH1Zg== +"@date-io/core@^2.17.0": + version "2.17.0" + resolved "https://registry.yarnpkg.com/@date-io/core/-/core-2.17.0.tgz#360a4d0641f069776ed22e457876e8a8a58c205e" + integrity sha512-+EQE8xZhRM/hsY0CDTVyayMDDY5ihc4MqXCrPxooKw19yAzUIC6uUqsZeaOFNL9YKTNxYKrJP5DFgE8o5xRCOw== "@date-io/date-fns@1.3.x": version "1.3.13" @@ -1735,32 +1760,32 @@ "@date-io/core" "^1.3.13" "@date-io/date-fns@^2.11.0": - version "2.13.1" - resolved "https://registry.yarnpkg.com/@date-io/date-fns/-/date-fns-2.13.1.tgz#19d8a245dab61c03c95ba492d679d98d2b0b4af5" - integrity sha512-8fmfwjiLMpFLD+t4NBwDx0eblWnNcgt4NgfT/uiiQTGI81fnPu9tpBMYdAcuWxaV7LLpXgzLBx1SYWAMDVUDQQ== + version "2.17.0" + resolved "https://registry.yarnpkg.com/@date-io/date-fns/-/date-fns-2.17.0.tgz#1d9d0a02e0137524331819c9576a4e8e19a6142b" + integrity sha512-L0hWZ/mTpy3Gx/xXJ5tq5CzHo0L7ry6KEO9/w/JWiFWFLZgiNVo3ex92gOl3zmzjHqY/3Ev+5sehAr8UnGLEng== dependencies: - "@date-io/core" "^2.13.1" + "@date-io/core" "^2.17.0" "@date-io/dayjs@^2.11.0": - version "2.13.1" - resolved "https://registry.yarnpkg.com/@date-io/dayjs/-/dayjs-2.13.1.tgz#98461d22ee98179b9f2dca3b36f1b618704ae593" - integrity sha512-5bL4WWWmlI4uGZVScANhHJV7Mjp93ec2gNeUHDqqLaMZhp51S0NgD25oqj/k0LqBn1cdU2MvzNpk/ObMmVv5cQ== + version "2.17.0" + resolved "https://registry.yarnpkg.com/@date-io/dayjs/-/dayjs-2.17.0.tgz#ec3e2384136c028971ca2f78800a6877b9fdbe62" + integrity sha512-Iq1wjY5XzBh0lheFA0it6Dsyv94e8mTiNR8vuTai+KopxDkreL3YjwTmZHxkgB7/vd0RMIACStzVgWvPATnDCA== dependencies: - "@date-io/core" "^2.13.1" + "@date-io/core" "^2.17.0" "@date-io/luxon@^2.11.1": - version "2.13.1" - resolved "https://registry.yarnpkg.com/@date-io/luxon/-/luxon-2.13.1.tgz#3701b3cabfffda5102af302979aa6e58acfda91a" - integrity sha512-yG+uM7lXfwLyKKEwjvP8oZ7qblpmfl9gxQYae55ifbwiTs0CoCTkYkxEaQHGkYtTqGTzLqcb0O9Pzx6vgWg+yg== + version "2.17.0" + resolved "https://registry.yarnpkg.com/@date-io/luxon/-/luxon-2.17.0.tgz#76e1f001aaa38fe7f0049f010fe356db1bb517d2" + integrity sha512-l712Vdm/uTddD2XWt9TlQloZUiTiRQtY5TCOG45MQ/8u0tu8M17BD6QYHar/3OrnkGybALAMPzCy1r5D7+0HBg== dependencies: - "@date-io/core" "^2.13.1" + "@date-io/core" "^2.17.0" "@date-io/moment@^2.11.0": - version "2.13.1" - resolved "https://registry.yarnpkg.com/@date-io/moment/-/moment-2.13.1.tgz#122a51e4bdedf71ff3babb264427737dc022c1e6" - integrity sha512-XX1X/Tlvl3TdqQy2j0ZUtEJV6Rl8tOyc5WOS3ki52He28Uzme4Ro/JuPWTMBDH63weSWIZDlbR7zBgp3ZA2y1A== + version "2.17.0" + resolved "https://registry.yarnpkg.com/@date-io/moment/-/moment-2.17.0.tgz#04d2487d9d15d468b2e7903b87268fa1c89b56cb" + integrity sha512-e4nb4CDZU4k0WRVhz1Wvl7d+hFsedObSauDHKtZwU9kt7gdYEAzKgnrSCTHsEaXrDumdrkCYTeZ0Tmyk7uV4tw== dependencies: - "@date-io/core" "^2.13.1" + "@date-io/core" "^2.17.0" "@discoveryjs/json-ext@^0.5.0": version "0.5.6" @@ -2507,6 +2532,13 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +available-typed-arrays@^1.0.6, available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + axios@0.25.x: version "0.25.0" resolved "https://registry.yarnpkg.com/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a" @@ -2681,6 +2713,17 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-bind@^1.0.5, call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + camel-case@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" @@ -2796,6 +2839,11 @@ commander@^9.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== +common-tags@^1.8.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2965,6 +3013,15 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== +define-data-property@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -3161,6 +3218,18 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: unbox-primitive "^1.0.2" which-typed-array "^1.1.10" +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + es-module-lexer@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f" @@ -3425,6 +3494,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 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.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" @@ -3464,6 +3538,17 @@ get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@ has-proto "^1.0.1" has-symbols "^1.0.3" +get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" @@ -3583,11 +3668,23 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-property-descriptors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + has-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== +has-proto@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + has-symbols@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" @@ -3605,6 +3702,13 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" +has-tostringtag@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -3612,6 +3716,13 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hasown@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.1.tgz#26f48f039de2c0f8d3356c223fb8d50253519faa" + integrity sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA== + dependencies: + function-bind "^1.1.2" + he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -3693,6 +3804,11 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +idb-keyval@^6.2.x: + version "6.2.1" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33" + integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg== + idb@^7.0.1: version "7.1.1" resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" @@ -3888,13 +4004,20 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.10, is-typed-array@^1.1.9: +is-typed-array@^1.1.10: version "1.1.12" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== dependencies: which-typed-array "^1.1.11" +is-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== + dependencies: + which-typed-array "^1.1.14" + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -4148,11 +4271,16 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash.debounce@4.0.x: +lodash.debounce@4.0.x, lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + lodash.throttle@4.1.x: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" @@ -4411,7 +4539,7 @@ object-assign@^4.1.1: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -object-inspect@^1.9.0: +object-inspect@^1.12.3, object-inspect@^1.9.0: version "1.13.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== @@ -4542,6 +4670,11 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + postcss-value-parser@^4.0.2: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" @@ -5051,6 +5184,18 @@ serve-static@1.14.2: parseurl "~1.3.3" send "0.17.2" +set-function-length@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.1.tgz#47cc5945f2c771e2cf261c6737cf9684a2a5e425" + integrity sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g== + dependencies: + define-data-property "^1.1.2" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.1" + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -5392,6 +5537,50 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typed-array-buffer@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" + integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-typed-array "^1.1.13" + +typed-array-byte-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67" + integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-byte-offset@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063" + integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-length@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.5.tgz#57d44da160296d8663fd63180a1802ebf25905d5" + integrity sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" + typescript@4.5.x: version "4.5.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" @@ -5652,6 +5841,17 @@ which-typed-array@^1.1.10, which-typed-array@^1.1.11: gopd "^1.0.1" has-tostringtag "^1.0.0" +which-typed-array@^1.1.14: + version "1.1.14" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.14.tgz#1f78a111aee1e131ca66164d8bdc3ab062c95a06" + integrity sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg== + dependencies: + available-typed-arrays "^1.0.6" + call-bind "^1.0.5" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.1" + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"