From b6f7cef1ce856d6d101277b3347b22b78c5b8a9b Mon Sep 17 00:00:00 2001 From: lilidworkin <99899591+lilidworkin@users.noreply.github.com> Date: Tue, 13 Sep 2022 12:03:22 -0400 Subject: [PATCH] Migrate the Justice Counts Publisher frontend (#4) --- README.md | 1 + publisher/README.md | 30 + publisher/package.json | 103 + publisher/public/android-chrome-192x192.png | Bin 0 -> 19031 bytes publisher/public/android-chrome-256x256.png | Bin 0 -> 5713 bytes publisher/public/apple-touch-icon.png | Bin 0 -> 17463 bytes .../public/assets/COURTS_AND_PRETRIAL.xlsx | Bin 0 -> 29598 bytes publisher/public/assets/DEFENSE.xlsx | Bin 0 -> 23834 bytes publisher/public/assets/JAILS.xlsx | Bin 0 -> 26357 bytes publisher/public/assets/LAW_ENFORCEMENT.xlsx | Bin 0 -> 22556 bytes publisher/public/assets/PRISONS.xlsx | Bin 0 -> 27693 bytes publisher/public/assets/PROSECUTION.xlsx | Bin 0 -> 26747 bytes publisher/public/assets/SUPERVISION.xlsx | Bin 0 -> 24599 bytes publisher/public/favicon-16x16.png | Bin 0 -> 748 bytes publisher/public/favicon-32x32.png | Bin 0 -> 1293 bytes publisher/public/favicon.ico | Bin 0 -> 15086 bytes publisher/public/index.html | 50 + publisher/public/manifest.json | 20 + publisher/public/robots.txt | 3 + publisher/src/App.test.tsx | 55 + publisher/src/App.tsx | 56 + publisher/src/analytics.ts | 208 + publisher/src/components/Auth/Auth.test.tsx | 88 + publisher/src/components/Auth/AuthStore.ts | 136 + publisher/src/components/Auth/AuthWall.tsx | 57 + .../src/components/Auth/UnauthorizedPage.tsx | 48 + .../src/components/Auth/VerificationPage.tsx | 126 + publisher/src/components/Auth/index.ts | 19 + publisher/src/components/Badge/Badge.tsx | 77 + publisher/src/components/Badge/index.ts | 18 + .../DataUpload/DataUpload.styles.tsx | 483 + .../src/components/DataUpload/DataUpload.tsx | 323 + .../DataUpload/InstructionsTemplate.tsx | 558 + .../components/DataUpload/SystemSelection.tsx | 66 + .../src/components/DataUpload/UploadFile.tsx | 165 + .../components/DataUpload/UploadedFiles.tsx | 338 + publisher/src/components/DataUpload/index.ts | 23 + publisher/src/components/DataViz/BarChart.tsx | 238 + .../DataViz/DatapointsView.styles.tsx | 203 + .../src/components/DataViz/DatapointsView.tsx | 198 + publisher/src/components/DataViz/Legend.tsx | 78 + publisher/src/components/DataViz/Tooltip.tsx | 138 + .../src/components/DataViz/utils.test.ts | 2066 ++++ publisher/src/components/DataViz/utils.ts | 335 + .../Error/NoAuthConfigErrorPage.tsx | 38 + .../components/Forms/BinaryRadioButton.tsx | 143 + publisher/src/components/Forms/Dropdown.tsx | 92 + .../src/components/Forms/Form.styles.tsx | 282 + publisher/src/components/Forms/Forms.test.tsx | 106 + .../src/components/Forms/NotReportedIcon.tsx | 126 + .../Forms/TabbedDisaggregations.tsx | 271 + publisher/src/components/Forms/TextInput.tsx | 364 + publisher/src/components/Forms/index.ts | 22 + .../src/components/GlobalStyles/Palette.ts | 62 + .../src/components/GlobalStyles/Typography.ts | 55 + .../src/components/GlobalStyles/constants.ts | 18 + .../src/components/GlobalStyles/index.ts | 20 + .../src/components/Header/Header.styles.tsx | 54 + publisher/src/components/Header/Header.tsx | 39 + publisher/src/components/Header/index.ts | 19 + publisher/src/components/Loading/Loading.tsx | 60 + .../src/components/Loading/MiniLoader.tsx | 88 + publisher/src/components/Loading/index.ts | 18 + publisher/src/components/Menu/Menu.styles.tsx | 140 + publisher/src/components/Menu/Menu.tsx | 169 + publisher/src/components/Menu/index.ts | 19 + .../MetricsView/MetricsView.styles.tsx | 330 + .../components/MetricsView/MetricsView.tsx | 959 ++ .../MetricsView/MetricsViewMocks.ts | 163 + publisher/src/components/MetricsView/index.ts | 19 + publisher/src/components/Modal/Modal.tsx | 148 + publisher/src/components/Modal/index.ts | 18 + .../src/components/Onboarding/Onboarding.tsx | 717 ++ .../Onboarding/OnboardingDataEntrySummary.tsx | 229 + publisher/src/components/Onboarding/index.ts | 19 + .../components/Reports/CreateReport.test.tsx | 131 + .../src/components/Reports/CreateReport.tsx | 324 + .../components/Reports/DataEntryForm.test.tsx | 228 + .../src/components/Reports/DataEntryForm.tsx | 450 + .../Reports/DataEntryFormComponents.tsx | 277 + .../src/components/Reports/HelperText.tsx | 144 + .../Reports/PublishConfirmation.tsx | 567 + .../components/Reports/PublishDataPanel.tsx | 65 + .../Reports/ReportDataEntry.styles.tsx | 99 + .../components/Reports/ReportDataEntry.tsx | 165 + .../components/Reports/ReportSummaryPanel.tsx | 412 + .../src/components/Reports/Reports.styles.tsx | 254 + publisher/src/components/Reports/index.ts | 18 + publisher/src/components/Toast/Toast.ts | 118 + publisher/src/components/Toast/index.ts | 18 + .../src/components/assets/check-icon.svg | 4 + .../components/assets/cloud-upload-icon.svg | 12 + .../src/components/assets/dark-close-icon.png | Bin 0 -> 1758 bytes .../src/components/assets/download-icon.png | Bin 0 -> 3639 bytes .../src/components/assets/error-icon.svg | 4 + publisher/src/components/assets/file-icon.svg | 10 + .../src/components/assets/info-red-icon.png | Bin 0 -> 441 bytes .../assets/jc-logo-green-vector.png | Bin 0 -> 3652 bytes .../assets/jc-logo-vector-onboarding.png | Bin 0 -> 179501 bytes .../src/components/assets/jc-logo-vector.png | Bin 0 -> 79735 bytes .../src/components/assets/jc-logo-vector.svg | 3 + .../src/components/assets/jc-logo-vector2.png | Bin 0 -> 6911 bytes .../assets/loader-sprite-horizontal.svg | 105 + .../assets/metrics-view-downright-arrow.png | Bin 0 -> 259 bytes .../assets/microsoft-excel-icon.svg | 11 + .../components/assets/not-reported-icon.png | Bin 0 -> 2388 bytes .../components/assets/spreadsheet-icon.png | Bin 0 -> 7874 bytes .../components/assets/status-check-icon.png | Bin 0 -> 2211 bytes .../assets/status-check-white-icon.png | Bin 0 -> 1087 bytes .../components/assets/status-error-icon.png | Bin 0 -> 1968 bytes publisher/src/components/assets/todo-icon.svg | 5 + .../src/components/assets/upload-icon.png | Bin 0 -> 3296 bytes .../src/components/assets/warning-icon.svg | 10 + publisher/src/index.tsx | 124 + publisher/src/mocks/PreviewDataObject.tsx | 88 + publisher/src/mocks/mockReport.ts | 450 + publisher/src/mocks/reportOverviews.json | 438 + publisher/src/pages/AccountSettings.tsx | 99 + publisher/src/pages/Reports.tsx | 379 + publisher/src/react-app-env.d.ts | 1 + publisher/src/setupTests.ts | 24 + publisher/src/shared/types.ts | 275 + publisher/src/stores/API.test.tsx | 75 + publisher/src/stores/API.ts | 150 + publisher/src/stores/DatapointsStore.ts | 155 + publisher/src/stores/FormStore.test.tsx | 153 + publisher/src/stores/FormStore.ts | 558 + publisher/src/stores/ReportStore.test.tsx | 107 + publisher/src/stores/ReportStore.ts | 377 + publisher/src/stores/RootStore.ts | 66 + publisher/src/stores/StoreProvider.tsx | 48 + publisher/src/stores/UserStore.ts | 235 + publisher/src/stores/index.ts | 22 + publisher/src/utils/conversionUtils.ts | 29 + publisher/src/utils/dateUtils.test.ts | 134 + publisher/src/utils/dateUtils.ts | 133 + publisher/src/utils/helperUtils.test.ts | 127 + publisher/src/utils/helperUtils.ts | 222 + publisher/src/utils/index.ts | 20 + publisher/src/window.d.ts | 32 + publisher/tsconfig.json | 3 + publisher/yarn.lock | 9709 +++++++++++++++++ 142 files changed, 28781 insertions(+) create mode 100644 publisher/README.md create mode 100644 publisher/package.json create mode 100644 publisher/public/android-chrome-192x192.png create mode 100644 publisher/public/android-chrome-256x256.png create mode 100644 publisher/public/apple-touch-icon.png create mode 100644 publisher/public/assets/COURTS_AND_PRETRIAL.xlsx create mode 100644 publisher/public/assets/DEFENSE.xlsx create mode 100644 publisher/public/assets/JAILS.xlsx create mode 100644 publisher/public/assets/LAW_ENFORCEMENT.xlsx create mode 100644 publisher/public/assets/PRISONS.xlsx create mode 100644 publisher/public/assets/PROSECUTION.xlsx create mode 100644 publisher/public/assets/SUPERVISION.xlsx create mode 100644 publisher/public/favicon-16x16.png create mode 100644 publisher/public/favicon-32x32.png create mode 100644 publisher/public/favicon.ico create mode 100644 publisher/public/index.html create mode 100644 publisher/public/manifest.json create mode 100644 publisher/public/robots.txt create mode 100644 publisher/src/App.test.tsx create mode 100644 publisher/src/App.tsx create mode 100644 publisher/src/analytics.ts create mode 100644 publisher/src/components/Auth/Auth.test.tsx create mode 100644 publisher/src/components/Auth/AuthStore.ts create mode 100644 publisher/src/components/Auth/AuthWall.tsx create mode 100644 publisher/src/components/Auth/UnauthorizedPage.tsx create mode 100644 publisher/src/components/Auth/VerificationPage.tsx create mode 100644 publisher/src/components/Auth/index.ts create mode 100644 publisher/src/components/Badge/Badge.tsx create mode 100644 publisher/src/components/Badge/index.ts create mode 100644 publisher/src/components/DataUpload/DataUpload.styles.tsx create mode 100644 publisher/src/components/DataUpload/DataUpload.tsx create mode 100644 publisher/src/components/DataUpload/InstructionsTemplate.tsx create mode 100644 publisher/src/components/DataUpload/SystemSelection.tsx create mode 100644 publisher/src/components/DataUpload/UploadFile.tsx create mode 100644 publisher/src/components/DataUpload/UploadedFiles.tsx create mode 100644 publisher/src/components/DataUpload/index.ts create mode 100644 publisher/src/components/DataViz/BarChart.tsx create mode 100644 publisher/src/components/DataViz/DatapointsView.styles.tsx create mode 100644 publisher/src/components/DataViz/DatapointsView.tsx create mode 100644 publisher/src/components/DataViz/Legend.tsx create mode 100644 publisher/src/components/DataViz/Tooltip.tsx create mode 100644 publisher/src/components/DataViz/utils.test.ts create mode 100644 publisher/src/components/DataViz/utils.ts create mode 100644 publisher/src/components/Error/NoAuthConfigErrorPage.tsx create mode 100644 publisher/src/components/Forms/BinaryRadioButton.tsx create mode 100644 publisher/src/components/Forms/Dropdown.tsx create mode 100644 publisher/src/components/Forms/Form.styles.tsx create mode 100644 publisher/src/components/Forms/Forms.test.tsx create mode 100644 publisher/src/components/Forms/NotReportedIcon.tsx create mode 100644 publisher/src/components/Forms/TabbedDisaggregations.tsx create mode 100644 publisher/src/components/Forms/TextInput.tsx create mode 100644 publisher/src/components/Forms/index.ts create mode 100644 publisher/src/components/GlobalStyles/Palette.ts create mode 100644 publisher/src/components/GlobalStyles/Typography.ts create mode 100644 publisher/src/components/GlobalStyles/constants.ts create mode 100644 publisher/src/components/GlobalStyles/index.ts create mode 100644 publisher/src/components/Header/Header.styles.tsx create mode 100644 publisher/src/components/Header/Header.tsx create mode 100644 publisher/src/components/Header/index.ts create mode 100644 publisher/src/components/Loading/Loading.tsx create mode 100644 publisher/src/components/Loading/MiniLoader.tsx create mode 100644 publisher/src/components/Loading/index.ts create mode 100644 publisher/src/components/Menu/Menu.styles.tsx create mode 100644 publisher/src/components/Menu/Menu.tsx create mode 100644 publisher/src/components/Menu/index.ts create mode 100644 publisher/src/components/MetricsView/MetricsView.styles.tsx create mode 100644 publisher/src/components/MetricsView/MetricsView.tsx create mode 100644 publisher/src/components/MetricsView/MetricsViewMocks.ts create mode 100644 publisher/src/components/MetricsView/index.ts create mode 100644 publisher/src/components/Modal/Modal.tsx create mode 100644 publisher/src/components/Modal/index.ts create mode 100644 publisher/src/components/Onboarding/Onboarding.tsx create mode 100644 publisher/src/components/Onboarding/OnboardingDataEntrySummary.tsx create mode 100644 publisher/src/components/Onboarding/index.ts create mode 100644 publisher/src/components/Reports/CreateReport.test.tsx create mode 100644 publisher/src/components/Reports/CreateReport.tsx create mode 100644 publisher/src/components/Reports/DataEntryForm.test.tsx create mode 100644 publisher/src/components/Reports/DataEntryForm.tsx create mode 100644 publisher/src/components/Reports/DataEntryFormComponents.tsx create mode 100644 publisher/src/components/Reports/HelperText.tsx create mode 100644 publisher/src/components/Reports/PublishConfirmation.tsx create mode 100644 publisher/src/components/Reports/PublishDataPanel.tsx create mode 100644 publisher/src/components/Reports/ReportDataEntry.styles.tsx create mode 100644 publisher/src/components/Reports/ReportDataEntry.tsx create mode 100644 publisher/src/components/Reports/ReportSummaryPanel.tsx create mode 100644 publisher/src/components/Reports/Reports.styles.tsx create mode 100644 publisher/src/components/Reports/index.ts create mode 100644 publisher/src/components/Toast/Toast.ts create mode 100644 publisher/src/components/Toast/index.ts create mode 100644 publisher/src/components/assets/check-icon.svg create mode 100644 publisher/src/components/assets/cloud-upload-icon.svg create mode 100644 publisher/src/components/assets/dark-close-icon.png create mode 100644 publisher/src/components/assets/download-icon.png create mode 100644 publisher/src/components/assets/error-icon.svg create mode 100644 publisher/src/components/assets/file-icon.svg create mode 100644 publisher/src/components/assets/info-red-icon.png create mode 100644 publisher/src/components/assets/jc-logo-green-vector.png create mode 100644 publisher/src/components/assets/jc-logo-vector-onboarding.png create mode 100644 publisher/src/components/assets/jc-logo-vector.png create mode 100644 publisher/src/components/assets/jc-logo-vector.svg create mode 100644 publisher/src/components/assets/jc-logo-vector2.png create mode 100644 publisher/src/components/assets/loader-sprite-horizontal.svg create mode 100644 publisher/src/components/assets/metrics-view-downright-arrow.png create mode 100644 publisher/src/components/assets/microsoft-excel-icon.svg create mode 100644 publisher/src/components/assets/not-reported-icon.png create mode 100644 publisher/src/components/assets/spreadsheet-icon.png create mode 100644 publisher/src/components/assets/status-check-icon.png create mode 100644 publisher/src/components/assets/status-check-white-icon.png create mode 100644 publisher/src/components/assets/status-error-icon.png create mode 100644 publisher/src/components/assets/todo-icon.svg create mode 100644 publisher/src/components/assets/upload-icon.png create mode 100644 publisher/src/components/assets/warning-icon.svg create mode 100644 publisher/src/index.tsx create mode 100644 publisher/src/mocks/PreviewDataObject.tsx create mode 100644 publisher/src/mocks/mockReport.ts create mode 100644 publisher/src/mocks/reportOverviews.json create mode 100644 publisher/src/pages/AccountSettings.tsx create mode 100644 publisher/src/pages/Reports.tsx create mode 100644 publisher/src/react-app-env.d.ts create mode 100644 publisher/src/setupTests.ts create mode 100644 publisher/src/shared/types.ts create mode 100644 publisher/src/stores/API.test.tsx create mode 100644 publisher/src/stores/API.ts create mode 100644 publisher/src/stores/DatapointsStore.ts create mode 100644 publisher/src/stores/FormStore.test.tsx create mode 100644 publisher/src/stores/FormStore.ts create mode 100644 publisher/src/stores/ReportStore.test.tsx create mode 100644 publisher/src/stores/ReportStore.ts create mode 100644 publisher/src/stores/RootStore.ts create mode 100644 publisher/src/stores/StoreProvider.tsx create mode 100644 publisher/src/stores/UserStore.ts create mode 100644 publisher/src/stores/index.ts create mode 100644 publisher/src/utils/conversionUtils.ts create mode 100644 publisher/src/utils/dateUtils.test.ts create mode 100644 publisher/src/utils/dateUtils.ts create mode 100644 publisher/src/utils/helperUtils.test.ts create mode 100644 publisher/src/utils/helperUtils.ts create mode 100644 publisher/src/utils/index.ts create mode 100644 publisher/src/window.d.ts create mode 100644 publisher/tsconfig.json create mode 100644 publisher/yarn.lock diff --git a/README.md b/README.md index a337f0886..64502be8a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # justice-counts + Technical infrastructure for the Justice Counts initiative diff --git a/publisher/README.md b/publisher/README.md new file mode 100644 index 000000000..caa7b560e --- /dev/null +++ b/publisher/README.md @@ -0,0 +1,30 @@ +# Justice Counts Control Panel: Frontend + +Welcome to the Justice Counts Control Panel - a tool that allows agencies to report Justice Counts metrics. + +The frontend of this application, which lives in this directory, was bootstrapped with [Create React App](https://github.com/facebook/create-react-app), written in [TypeScript](https://www.typescriptlang.org/docs), and authenticated via [Auth0](https://auth0.com/). The backend of the application lives in [recidiviz-data/justice_counts/control_panel](https://github.com/Recidiviz/recidiviz-data/tree/main/recidiviz/justice_counts/control_panel). + +To run the app locally, you need to spin up both the backend and frontend simultaneously. Instructions for spinning up the frontend are below; instructions for spinning up the backend can be found in its directory's README. + +## Running the app frontend + +1. Install dependencies + + ##### For all Yarn installation options, see [Yarn Installation](https://yarnpkg.com/en/docs/install). + + ```sh + yarn install + ``` + +2. Run the local development server + + ```sh + yarn run dev + ``` + +3. Test your development environment + + ```sh + yarn test + yarn lint + ``` diff --git a/publisher/package.json b/publisher/package.json new file mode 100644 index 000000000..889383524 --- /dev/null +++ b/publisher/package.json @@ -0,0 +1,103 @@ +{ + "name": "recidiviz-justice-counts-control-panel", + "version": "0.1.0", + "description": "A tool that allows agencies to report Justice Counts metrics", + "private": true, + "author": "Recidiviz ", + "license": "GNU General Public License v3", + "dependencies": { + "@auth0/auth0-react": "^1.9.0", + "@recidiviz/design-system": "^2.7.0", + "@testing-library/dom": "^8.11.3", + "@testing-library/jest-dom": "^5.14.1", + "@testing-library/react": "^12.0.0", + "@testing-library/user-event": "^13.2.1", + "lodash.debounce": "^4.0.8", + "lodash.mapvalues": "^4.6.0", + "lodash.pickby": "^4.6.0", + "mobx": "^6.4.2", + "mobx-persist-store": "^1.0.6", + "mobx-react-lite": "^3.3.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-is": "^17.0.2", + "react-router-dom": "^6", + "react-scripts": "5.0.0", + "recharts": "^2.1.13", + "styled-components": "^5.3.3", + "typescript": "^4.4.2", + "web-vitals": "^2.1.0" + }, + "scripts": { + "dev": "react-scripts start", + "build": "react-scripts build", + "lint": "tsc && eslint '**/*.{ts,tsx}'", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "@recidiviz/eslint-config", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "homepage": "/", + "proxy": "http://localhost:5001", + "devDependencies": { + "@auth0/auth0-spa-js": "^1.20.1", + "@babel/core": "^7.0.0-0", + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "@recidiviz/eslint-config": "^2.0.0", + "@recidiviz/tsconfig": "^1.0.0", + "@types/auth0": "^2.34.13", + "@types/jest": "^27.0.1", + "@types/lodash": "^4.14.182", + "@types/lodash.debounce": "^4.0.7", + "@types/node": "^16.7.13", + "@types/qs": "^6.9.7", + "@types/reach__router": "^1.3.10", + "@types/react": "^17.0.20", + "@types/react-dom": "^17.0.9", + "@types/react-modal": "^3.13.1", + "@types/react-router-dom": "^5.3.3", + "@types/styled-components": "^5.1.24", + "@typescript-eslint/eslint-plugin": "^5.15.0", + "@typescript-eslint/parser": "^5.15.0", + "autoprefixer": "^10.0.2", + "babel-eslint": "^10.1.0", + "babel-plugin-import": "^1.13.3", + "eslint": "^8.11.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-config-prettier": "^8.5.0", + "eslint-config-react-app": "^7.0.0", + "eslint-import-resolver-typescript": "^2.5.0", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-prettier": "^4.0.0", + "eslint-plugin-react": "^7.29.4", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-simple-import-sort": "^7.0.0", + "jest-fetch-mock": "^3.0.3", + "postcss": "^8.1.0", + "prettier": "^2.6.0", + "react-modal": "^3.14.4" + }, + "jest": { + "moduleNameMapper": { + "^d3-(.*)$": "d3-$1/dist/d3-$1" + } + } +} diff --git a/publisher/public/android-chrome-192x192.png b/publisher/public/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..0ed7339980b591452fe36201360551b95105579d GIT binary patch literal 19031 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 literal 0 HcmV?d00001 diff --git a/publisher/public/assets/COURTS_AND_PRETRIAL.xlsx b/publisher/public/assets/COURTS_AND_PRETRIAL.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..49d998d80eedf5b2e89a8198459e3f6de2e54e66 GIT binary patch literal 29598 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 literal 0 HcmV?d00001 diff --git a/publisher/public/assets/JAILS.xlsx b/publisher/public/assets/JAILS.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..91b3612f6503c7fb9f5664dd8b60465b545be4cf GIT binary patch literal 26357 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 literal 0 HcmV?d00001 diff --git a/publisher/public/assets/PROSECUTION.xlsx b/publisher/public/assets/PROSECUTION.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..523b72d9abe353aaa99fc8fbdc3d095d943d40e3 GIT binary patch literal 26747 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℘Tv$CQqC_r)P>0LnijnW~^ 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 literal 0 HcmV?d00001 diff --git a/publisher/public/assets/SUPERVISION.xlsx b/publisher/public/assets/SUPERVISION.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e79242b592d9a4ceef09b6d393584df598612aab GIT binary patch literal 24599 zcmeFZWmJ{j+BUovDcvERB7%T)hae!WbP3WR-OVB-rBNDGxkTYv5KRey%YOedwVu_8*9ZV5e$T9xKg*j9DdYDv_3ZyAADW@4abX|J;p@x+jHM0 zf!1hSDmzl?d35t9O9j|ZgVmy!>EdueL?q$WO8R-W6p0o&#vUM{_1J+AP}!G;MI%)C zXgSGiiZ|F%(wUCfR3+|8Yg-lercCWQw8&Vujy7`zBRu<$jz3Y49SB*zQTd0vMCZis z4*)k=5I`Wjzq@N}=V%J|w?D2`shtBe*Z_HTu6`4u_-Y(uSc!)A8Cu6vxyGkoEx&f; z&rZh&mkMpUP`^AuA1<>% zN*6AjG(Fm0dRsaDt-5rpK3@abVE63x%v_k~xoF+ZK?AyOUjN*c@p6RWbW2%-MKkE1 z@FeS{(c_|kKxs@M5CH&>yEVJBg{h6{{qJXRfOd6sou>E+efP@--OW#IFuHjCtE&i{ zEM2Fol7n`YsNdshMOu59#0L2_%kbj%e!|*~Q>;%FMq=H(9C#tKzQOMS+ha4@2o6m+ zayOi0pB`(dVV_&j?)ogKDpI>tvj!# z=0r`Qn}U>_{bL= z5=_?`aP>av*vpz<>6DG`R!DTH1tSa<>7a3v%^tgT_uC=SWSn@A?>AMT}6Y=+m?@*u1nu#ZxUNP zmtNlX#3%Z`Dn3jD(z16Q>l;G+^oIGuC4p>`vSC(2??7u$APn!Os}pI=a_HeFZfVE# z7-Vb^U&n6+74I^M>hOiOxFNlmF(~tQ6|x5@KmCto0%$vD%C3(S8+x+2Jkxyy2i_(4 zSr&owb{kTm@mEe8E17xm>F9p4ln6---a;R3K2L8QkXyYhMt_n<}h+X_s`L{ zm4wZyH9nQ=L!m1f9~|i$W>2(yPLySA>BkFND(S`(q#0gh{(M@$g2(^;B^D=v*n{-o zBr6pPglx2DpS}d2Rdp5PEfDzBG(Gq^9~pXDWS1hM`9r2!e z>E9>njWbz^T14PP(s}Me9@fq=_m3@yC27Kx1o-_47$_3Ki42eM3j}->WeILra;9$5 zhQ$vO*cmS5Vxui9>GPZ)^>1*IwMv(fyM$N_347ikpQrJlQ^b-}BAAm`O49~eHXKlu zF+`=5wBfNl7d3jwOXm2U*uUDLAjnV$zw5WV(ohxNm3A>tyr|*No&H#tfw5R@ytp@f zz}$g|7`$exV1Buj-LDQ>NY@!}+F!PA1oWC+*ZKyJa#^!Royv@m$gSW!$`jk<%y6WkU&iARSQKdA%3w--~im$EcETBcekIe^~vtRc| zu`kboV2ZO$7SiWsc~+$$HtnD{Xe_a%Ho+P1TtH8t}R3}4tFmm8G_1E zw4c%w$H@CvN-)%3Mf^H=(t);NqRWWZt2S)P7mlCtoZNO(^;quX_-a|*<62?emCdp* z&Z4Z)b76z^s(uVE$r?xbt?GoP?~nN9{#5kYD^c}g3YiPXQC7QsrsTOi(RW>;&*4x_ zl&mFt-h^mVpFShVpOF+>hd%r|#;*N*v(ueyNnjGG&L>IJW_{xK@5}YpSLIpz!k;L+ zLyx}F?tKYPg0@SBcz78knSbn3;U=`PE@ohrt}(0~KV&6bFfn}k88xu%6~fVLb;D=6 zU5G3(U%eGRyx6c`Pt-G5{vEeGooo8twv5^Bp$*+@fi}w|0`sC@bEXxo>XcA*-J|j* zE0HQ9CFqTI$ntxj)cKoVa8=_ck~S`{bvr1j*5bQX z;~;R>H3$@Vnm#knJ(_=tiN>lMs*S&-sJ}b9o|;zbN#}Zz=+iWryg*eM;*{!H+xDXPR%?vv zoO52lep+x2@y!|mt7Nust50}11h2@bslH74oH0$P%InadCiQA;I{RdH0n>Y=NGHdH z1y4*K)tfpF#rT8nA8vzaLZg!0ijuCWXP6!kEg0q(GyeII7b#?1qY=ddk?3|3qvES# z(<4|GCs^DRvB+@xvIjYiu+CX0;f;$WTyuLf@H z-x4`1_z9~zFHj0U2uGR2!q!pSP($W2I%DTevW~|B$2sXMs2?B^ZV)A1?ihlfyVLS@ zjlYV={M2+PELtEIGCRvgZua&|Clh-`&rifKxqK}q`{yi>A6mO%SM!* zC0=11_RxsdJHgrq*lsAHLLv61e;F`G-AU)C{1tmu&ql( zl_O(e>*JU^!c8I$j@a%0_v~=OKjZ(Ko&OWru@TV9JpyWn0`))E4i`K-A3x69PSX%} z8FU^YCUn@`s7K|D4Oi(aM3Q}PNR#!Z$TB=wV0bg``G^pZ~tl6}D(V)kmu` z7SM;A5xoslJzC!ApbZ;jo>8}N;I|rb1yZ`hVqOeVy3P-UMlv!(jNvF}C8l)@+&!>Fk#Br@vF`Ps1zG^$)Y3#@t1kOm3$} zZLKC%ueluC8ZhD=O>I79M%fe=HoD%L}{H*%?Bgm(R|IjBCmbVpwgIC^vV<-_&;Ml#5qtq z$u^5}e~v1?tYA0oss8LtU9*3>utzy_EnXWl*TVDqEp@crp*s}?v|T(S<_4K%V>@() z&z+k8;<-?~`(2+xhcHx)Q%CfhU8b{YuGkvZ7C~fcm@ago_xC=XV zb5Z{!7(&(U0c0^`DoFv^c?-t*qv#O5*^-mlGl|hCG)jlZk><{PTt4}tdrQ$E(_wvI z^03F-wpz*S7zsp4$FJoYkxrQHag0t#{`of+5jh373Hbg}i}N3O!hOe+M18wd4#MDD z^d(e6g(jAODwCAzh?lR5O2(Czkknd|9a4_xp}Aq{n`y=$iwxZjU`Y|(4!*Hl-&x)d z{+`dZZ7|id^6^xNv(*d_cEdSh(1EScsJDNASZF+yp0IG)G&1t?Q|@r~qB=Q=ho4eyEnSPkOn;Ye1j&+Xr_dx1P(=;8rR}tyes`fD0qp`20y9&X}P?w>J zAH&4^Wp&Y zwa;8e!L0qH!SbsW2V}wEo}aNFP~u`dJ|F@ApNRc{8mDrOCyme!F~} ztvII(!>~Vtnr}dC3kOZIK-{D_{u8lISwqs8KFS_%8nlm@Zy7i+Wr?Fqp2Y;iWqQ0Lbte8_ z#$GJpc6%ivcSQ6z(_x%-p9gs+yRl>ZB*~-2c-+tQr?=5hTfBuIOI_TJkpauHF;H8) z?XL9*-U`tc@3?C*!CMj9;$3&G#|&7va~_oDV9G3R6Yy+K40raS-~fVPmt{Uey(+Dx ztkdZ{pP_MD@RQHFL~+5~Z@TUznT?%`o&)am@{>O?{sysAm!(*8CpVY0Q6N4jK@amv zTiKg1hgONz32NAoj4l}pZnpO&jCMaeH2%C=AeLs6GxlwhUEZmR_!mkaEHL4Mw>(eH zO^f~Je|>Uw>6hm60AEb|1pXuEdElH+Po1@$md1T=@L~{AYN;$uoOqD`@l-^$gzr>u zK!xTf+;BB!LEE{e>^S?N0fD0QAK@mM%5%#f4kaWVu4h~`m4((XCYwX*1!f1_eEht> zYo+bE?Wv@{sgfDToS&?o{jwF3H@m##yrXw)AB=rWr_a{g`DKa^)_-yJy=K;IR`mF| z$-%B+a&yx@zrL(Ye^zvUApSg>y>VJ>@8S?6qW?lmr2e$@*4=v=3raj(B)o%DDzH0k zHdeR0dzH5`nySu=u-=jBb?RO3E=*qJZ8Z&DjyIsTUGF`VDs?@*KEoe9fRebaZ+Uv> zEK=Nh`~5!u!zFWYbQrC9d#>mE7*-%y*HC@)?sjnBcAXD4891$>>~dS`bJOX=uBL$M zt$I9aHv1h~Y0Fx#Js*uTAa;3`N;-6DcE$5!zhSZAa&)BXHr;bK z58GyVALP2;-Lx}ZPv$4&cWMxgePCC5pnm;F%=+1%bh$j$&4kA1^$G-PiL0;9qTY+u zUg}pimsyP{NN$}?I$!m5y}x2y-*%- z)VIE`NWQf|L|G{Z%X{TLP^k}mz+XX@giwnpZ}5<@Ws`VmvEzvm`T{ZQZfXt)hly^f z!^#Mq5SV>w&Me*?cE(?Uo_seO7-nJmy4ta2`mfnfnU+>No|vI0+|OR9fg+vnk}Dav^ipBiC(;*%l+x3Sq9_4`ALRSNk%ScuVqNn49&j2vs2d;=4FZk zcP5#!Wdr42V5S9ybvH8yq@1_3IkE-l!)Eod`Gla59$uhYRKN_;Ew8fsgut2}o}*fn z!+e0xYiN1PitH{(q@1UrtO{~7+$l)mxf;}L2``i{xNq0IA zQGM$8%ysV>ueAi&`}nC57@Krf+$7!0B$8YO#2cyuL6mdD)m^93UB)JaP|}esK!%@6 zjn~PH*CHbuMuZ~s8#)I@u>7V{T}Hu#BnDbciOGWt2VRWU$&A(_BHD-iMCM;`#&B@i zbKtRU171W}sjamUd6 z(ILV+?Y9E)AZ3!J&9=Kt#bVe495dQ#v$6tsfCseTS#1Mo(9$cxeV5h$HJ5~%vN9zF zq4q@w0tH9CzgB&@P71<-Bd#LA$Clyu?)BxKz^LR30)>73`=t8v|2#Lxy}k;V3si!^ zrMM}iK>nGFB@Yj>eMIOkpP@5ig|p>%Zsdhknv|0P{Ljv)ht8JA+{gePvwQ#^|DHSg zKXVT{X~<4-RDb3*vWu?S0Bn#An~3&At*s~2Ow`a+g^Yx1`5;Pb;=W4Mc%=$5!2IfP z%a8o;(S%SvUqq!*t*}x}4SiM6_-BXtYeaDAo3J8HK=^L@K0jD45m&#gxIP!ej8}Jy zl2%IF^+r2V5&W7So|c00+FBy}M(ANpq1Oywp7w4vVx@Nl8N;wogUi8me3M9qUG3$_ ziH{e**i7A4tBbMW*-f?0CAD&w5J?_6Ki~iUlJx&#dBywR<<)!mq_UjsE&Ht8kZkerGM-5l5y=p z`VX9ew7d<@h?J+w<)3Nmyo*xTU6=Lv&fS`Ysx*fc$0^02X1ncOyG19eKF%RG>D~2{ zn)twuXc&7oZ^rvlb_DYkh*e`uX8x0!tuU&Z* zbE(c@$^N@QwS3&GB4UPP!)?yY6G}R*Nc-ox1Z}$9XsDn;_a3p1s?i zo2u-Nr~T!lFNULhqh+ADE-7QXPF25%t9}bDYH(MWr*GIU)bdx z_#|Bxy6_$Eb-T{ml;)BQ_e_asus7_zyFO{SB+4fxZ!D>|`fj~d^O6fm|0#7aY93V7 zhrs9fgu`2LzCPE_ZQ4(-#?wu`GR?(@yd5^#&b~FJyt^$~1D=SaerFI>>M@ILa5z7E z`P-j<<|6t)XZOubNdHBL@s9I{^f>x#7`KGKw#bvFx19z`e$IsQ1cj&8J0e^s16yzR zi_c1}bcY(H)nMln-nP~mqwQPMdje2vE)b&U1s)A0Gi$vlPNz)e;pb9SBU_{3xh&t>L9EwfzRk1iX2ZY^H zD8hwAnlA2~s^udOPJ^gl20s?B3*+ajkV`~BRse=22|v$DHKuBH%7ZEHhnvDC_$sy% z5%|GHCs?l_{sgb=ja)d8-glkQpxk&7RGzu z|E?V#+RuUq0^fn<;a|STsNy+V5pg2N34CbzC8A15v!W1`ru|+4K;qNoNf=meK&mHM zy@!wnPpi&63Y0}38qZY}&m6OmQ|d#Hg`2)$&1CaNZn%V73AZv4yWH`S#z3(~E+`DQ zA|2&J6phY6u}-cy0$)zm43`X8XF#eqS-qE#291t)6!IHSsxMi+4^T~a0&jKnC3pAb z=ezC1tUNHo3z0hckyG%(H1O5|)#$Xi1FhdCb z-U2}v2CbmD$Y-^<)Fc|zsvy)*Eqz33CjN%tUVtSFNcVoxt+WBH7B2oOfD&L)wvO)i zquqopf5j>F^F2V27PR}Q?_2+h(OWM(S{`r$gg9t5&lm}Q&i3MG&i(9@u{(0XTkzRD z)O3&y(9-hImN7bjhb|lsx|N}OFXaE$g7E?Ad_k+Jk*Tj^1CU2HAgQ+qF+ndpPQECP zS)5LawFC@jiafv+2y}kX5lVr~Uq{H4sKKNPVF=aIMU;M_75b4xgGCi2^Le!?;ux{2 z5%(!Oz!i|FpJeYj1z3vdul7saiaI!xjNWKQT6Zq&-bUI^W~^qT)a)>Qoe zT~qycP4$1%nyQzWtt%YZ%I8-2k6Ts(aL(tX-ECP(-)&jZbGc4@N7$!n!@zm>;{mK2vBH zxH&)1hV_n9v~EZHiCo&5pG&MYZEa1P-I|_G*x9XhdY@>Csk2|+7{e~Su2moZpg52m z)l7AnZXB3;^PqFxw{KSV?%?_p-qoQCSkpkPRo;< z!h%BNu2(zoEw5UNCJw5Mfvon*x0#tf{ZAr}j9!sF-4Om}*dCSX6Pe#GBfmL2mCYcI=#t;J#64vZkJBH3{IcM;4G^@*xw zN6-h}7%G`D8dVy96z-lY&x6Mf49ro*PjlhYrQ5Ca-LZf8zo8@}Oh6t@u6rKjJ27}f z75n6ZG~V6~|BmGr{3e}(z|8$Qd2KvUCY`>=$z+!cxg3=0s*ghz7RC6xg6B6O1jTu3 z-4j%<5v$cbrlkrhD!1%D29es>e}A0HXNqDnNMopZBJ0c=7F7}kn0}y@1kS=@xD#zb zQLQ!uy(0>9v5w?HE|+WB!X&k!sfa46$Q8%N+PUNsuYxcLRzFHX(4sL6LjmHE>K>C) z1(7REW`m2>8OADj#t2)UfVa5~|LoH-j#r2keNEQgjj%I{`r++fo|vz@gW0% z!vFCN&@*B9OBBnn#PPVu2DV@Q5TcH7V%cJW7>YZ-U`vxSq7;VgS53GT45Xc5 z$ZwRmjgLT-fU75#a98hU8h*T2YV_k*!{3jD6RuBtB%Rj%SEYNWSA(3PpaBNG;M1d>DVXgUkk9>frqg!M)l?!aC`) zMFj7Pn8h&>c;5l4!(5C2I78bKM#);HUVKZ}s#F9o;gN*@7zrPH5; z>g}0IkJnSO#Z-mN}egb3V`WC{L?B83f~{%c zm&^ksYwLec1Bw2ZU0LV9><~Yg$iHJ{@_nj_t?pQ9cF#&tEK<`L`C=!4U7&r@FT+=! zpitr%sr7%5Wai%HCHI}pntN|E@4Q|Ax3@qQeRX>2Y^%tPTrS=M=(V8<8-SMuZ_+nq zM6DvdYs*jfl)mH!Qqds@*K@E(Ah=sgC5)dg|JCW;S7rz@oV1SvpX2Lm5h#K!#PfdK z$PLhsz3-?m|GQa|f0;c$2H`%X31fpJ3PhTB7wP-IliKC&zas_ekFB^O7u0kd6eYy= zAX=JaXrt}ltkzlFiq0>I%>}(m`V%rj^@A;Y{QdWFLK-%(5RkU#%&lxCt@pC9cL+37 z;)41*LW*D`+;Vk9X%^Xh`FHuu;)J=yqo6Uip`D>AYjoU1$PY3O9f_~{I$4Tf?`$yPF%3vxi4C;`)>M-ti5e94klQx9txcB5BQlJL=`B|mhj0YZ4 zeq*yEtUky2=VR7=I$xB@2Ov>hIM!Czzig6TVEjR7%{$}==AfZta^G5Rwqn*n|r>_d4Z*kntXIu?VigGvEZ)R;> zFMEF%?o%5?cVAAcSC*WXO?8{Oo&EBew%NWpDEA`Wr*6n?5|Wtiul@PWs9XnB7vnPqQNH~K%{>tW4rJ%=W`*|yquHbMMQe5wmjmbb*<>c4y{@#h zy?#e zUyO~+I?hlVQ2@{3{Zz&stfu!ah+1ryCL}8x-VN4x5v(_jrRJ^OPMi(G^s4z2pZ??` z)Q-(cv8KYBFJE*!&XvfyYLpihV9E^bnG{wS2%e|HrX1KqOZ4#^5GAUt^hip_x}7XL zXlBHz-B=ayWR^CEaR`#%WX)bX{+Oe@F?fD1vU;Sse)Taav%mey`fPZwx726u%K??c zqWSs(*E8XCnZ-#Cp%ULY#>~ukXy=ME6{C6kRh4I(sXgky27(196(@pAw<2x>RhufF>lw609R-r|j>YFApHh)^pP-~(6T=cL|3nAC<+ z7ywrhrn;8`L}#_Xbxwe3=3sjX|u9#m}zHmY>5nT5h<> z5&IH3$Vmz#frmp36QmqX{&zzD=)5X6m>}x;d;L*m)1)*_kb8Z4;?>V+u5fVsy9h?R z2qEX2&R3*&T9o0QCCZjRGxSERJd^?qn3elm8H3KwTA^Q7sin9;-O6XL{(#7p`|d*fa45K0dNsvhib>q zkYy3Ie?sh$

-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 literal 0 HcmV?d00001 diff --git a/publisher/public/favicon-16x16.png b/publisher/public/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2ea290586e5b6502ca2f710c8071b67b9d106c GIT binary patch literal 748 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>S9PVV?p}3q|Gd-N^EOV>?2c1xkDPFL zb<(O%#!`E)x#jsACx@{x55PH*3K{lwH`8??LQb$S!K53DHKJT-G&pKNQGOiPGzdz5-t z?EnA&MNeIH0(y|KB*-uL$LEGc9w1JVx4Vm*_^zLCfgH{PkH}&M25w;xW@MN(M*=9w zUgGKN%KnU1P{hLOnL%>^P^jP2#W6(Ua&kg~3nNcP%>s^=Bqk;mMzu7tFtai~wHXY; z>f+}7`tti3ghLvf13V&JLVRMHn3WEwXsYTeYpbtcu;K`dU_h8)U}{kC^$Q_wTpSsh ztBqd1c=b}+ft9DXC)MYP&(SkyW-e%piinErmbiVR=)juPt;U2OC7#SED=^B{o8k&a~8CaQ` zS(#dB8yHv_7&I7qhN5W5%}>cptHiD0W6sByKn>wlArU1(iRB6fMfqu&IjIUIl?AB^ znFS@u3=9=>9)IHDC=AokIOTu(jOWuJ24-b$y<~1-Wnu5hBFw@HE)6D!Q<#-EhbWxB oaplC3Ge=~Ou%B-5Sm33{@Jd{;RG<|Mp00i_>zopr0JfD500000 literal 0 HcmV?d00001 diff --git a/publisher/public/favicon-32x32.png b/publisher/public/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..2a925bdb695aecc28b61194e9148b5a6f85805a6 GIT binary patch literal 1293 zcmZ`%dsNbQ6#pU-3Ys%pR;xx@=1yf~T8PaDA`kHe;@g~x;4~{AKM+L=EnON}s2M)8 zoR*r1B8rjkS0Ugdv65-qj&8MFr=Rih;Q1pqD< zfaO>K@Dc!QQfnU2PXGX03-V+70Iui1>46qd%(6+QStOKz0w52|T-u$GVWZf%HX%oYFgw&4m{)I_eEuT`uyKm6+ z&QGWe+P?V-sPjg}!}if1^h3|5`N}GICc(8VdF;p8jwfR+GlPBelQR8qtA4mmKQgc| zrF^E2ynE3E@_=zYH|6>sx)OI&)1{mnm(C2e&5l&6JF3)*_Sun^$AfOyQ#R%JnhU6+ zp=MGw#OtbTp6;(2?>tuewRsNJB8Tc)o?NR{_Ag9z&y8!B=ENhdX4&MsQ@t+YL|j?2 za!#G0sJQV+POj$KU5Z5VeGZ6Xx910Qq@sephMwu9_&Zm!B zXNCr!PaiH}ZOHT%+^;DaZsB!F%bH9TZG3TC|rp*tuNNmFp2wr8ZKr@eo>@=n1D!C(d*9rhly)$F%- z-19|2vu7kJG$6){PL1#h@jvMuyu&-MLRliK?a!+#5zC93D^-XGCiZ5u1E)TVauc{A z$>jZsHaus9>`dvK-K5%>@7?>)#jO4Xi_VkE)F?^*ANk${?(ndkZT+{b-uR_O>l_K) zkMff*1G}OOe8Gud43PgG@Np}R#UZ4@yPLX7aiSh;$eQQkR$pcE(iHWsrScwfqoO;o@u;Db!Qr^8X8p5)f;SeJ(6O)>L zmXnmi#z0xAY)n!r!~%d{v$SGvnilHdpb6CKs6R6R+z#!?LR;He)5^BMtuaKQ^GE{R qPQk=z=VsNTy3w7ZNUe}^+t(2++gL#>1efc^6@cm!K$H<;^Zx<9>MCIX literal 0 HcmV?d00001 diff --git a/publisher/public/favicon.ico b/publisher/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..31f3bbba013832251c7eb862d1790cd47739246d GIT binary patch literal 15086 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 literal 0 HcmV?d00001 diff --git a/publisher/public/index.html b/publisher/public/index.html new file mode 100644 index 000000000..4d6164acb --- /dev/null +++ b/publisher/public/index.html @@ -0,0 +1,50 @@ + + + + + + + + + + + + + Justice Counts | Control Panel + + + + + + + + + + +

+ + + diff --git a/publisher/public/manifest.json b/publisher/public/manifest.json new file mode 100644 index 000000000..67a52fd68 --- /dev/null +++ b/publisher/public/manifest.json @@ -0,0 +1,20 @@ +{ + "short_name": "Control Panel", + "name": "Control Panel by Recidiviz", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "start_url": ".", + "display": "browser", + "theme_color": "#014c48", + "background_color": "#014c48" +} diff --git a/publisher/public/robots.txt b/publisher/public/robots.txt new file mode 100644 index 000000000..e9e57dc4d --- /dev/null +++ b/publisher/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/publisher/src/App.test.tsx b/publisher/src/App.test.tsx new file mode 100644 index 000000000..c51165b4a --- /dev/null +++ b/publisher/src/App.test.tsx @@ -0,0 +1,55 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import createAuth0Client from "@auth0/auth0-spa-js"; +import { render, screen } from "@testing-library/react"; +import React from "react"; + +import App from "./App"; +import AuthWall from "./components/Auth"; +import { StoreProvider } from "./stores"; + +jest.mock("@auth0/auth0-spa-js"); + +const mockCreateAuth0Client = createAuth0Client as jest.Mock; +const mockIsAuthenticated = jest.fn(); +const mockLoginWithRedirect = jest.fn(); + +beforeEach(() => { + mockCreateAuth0Client.mockResolvedValue({ + isAuthenticated: mockIsAuthenticated, + loginWithRedirect: mockLoginWithRedirect, + }); +}); + +afterEach(() => { + jest.resetAllMocks(); +}); + +test("renders loading on load", () => { + render( + + + + + + ); + const loader = screen.getByTestId("loading"); + expect(loader).toBeInTheDocument(); + + expect.hasAssertions(); +}); diff --git a/publisher/src/App.tsx b/publisher/src/App.tsx new file mode 100644 index 000000000..97b8fcef6 --- /dev/null +++ b/publisher/src/App.tsx @@ -0,0 +1,56 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { observer } from "mobx-react-lite"; +import React, { ReactElement, useEffect } from "react"; +import { Route, Routes, useLocation } from "react-router-dom"; + +import { trackNavigation } from "./analytics"; +import { DataUpload } from "./components/DataUpload"; +import { PageWrapper } from "./components/Forms"; +import Header from "./components/Header"; +import { MetricsView } from "./components/MetricsView"; +import CreateReports from "./components/Reports/CreateReport"; +import ReportDataEntry from "./components/Reports/ReportDataEntry"; +import AccountSettings from "./pages/AccountSettings"; +import Reports from "./pages/Reports"; + +const App: React.FC = (): ReactElement => { + const location = useLocation(); + useEffect(() => { + trackNavigation(location.pathname + location.search); + }, [location]); + + return ( + <> + +
+ + + } /> + } /> + } /> + } /> + } /> + } /> + + + + ); +}; + +export default observer(App); diff --git a/publisher/src/analytics.ts b/publisher/src/analytics.ts new file mode 100644 index 000000000..765a17233 --- /dev/null +++ b/publisher/src/analytics.ts @@ -0,0 +1,208 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { UpdatedMetricsValues, UserAgency } from "./shared/types"; + +const TEST_SENDING_ANALYTICS = false; // used for testing sending analytics in development +const LOG_ANALYTICS = false; // used for logging analytics being sent + +export const identify = ( + userId: string, + metadata?: Record +): void => { + const fullMetadata = metadata || {}; + if (LOG_ANALYTICS) { + // eslint-disable-next-line + console.log( + `[Analytics] Identifying user id: ${userId}, with metadata: ${JSON.stringify( + fullMetadata + )}` + ); + } + if ( + (process.env.NODE_ENV !== "development" && + process.env.NODE_ENV !== "test") || + TEST_SENDING_ANALYTICS + ) { + window.analytics.identify(userId, fullMetadata); + } +}; + +const track = (eventName: string, metadata?: Record): void => { + const fullMetadata = metadata || {}; + if (LOG_ANALYTICS) { + // eslint-disable-next-line + console.log( + `[Analytics] Tracking event name: ${eventName}, with metadata: ${JSON.stringify( + fullMetadata + )}` + ); + } + if ( + (process.env.NODE_ENV !== "development" && + process.env.NODE_ENV !== "test") || + TEST_SENDING_ANALYTICS + ) { + window.analytics.track(eventName, fullMetadata); + } +}; + +export const trackReportCreated = ( + reportId: number, + agency?: UserAgency +): void => { + track("frontend_report_created", { + reportId, + agencyId: agency?.id, + agencyName: agency?.name, + agencyFips: agency?.fips_county_code, + agencyState: agency?.state_code, + agencySystem: agency?.system, + agencySystems: agency?.systems, + }); +}; + +export const trackReportNotStartedToDraft = ( + reportId: number, + agency?: UserAgency +): void => { + track("frontend_report_not_started_to_draft", { + reportId, + agencyId: agency?.id, + agencyName: agency?.name, + agencyFips: agency?.fips_county_code, + agencyState: agency?.state_code, + agencySystem: agency?.system, + agencySystems: agency?.systems, + }); +}; + +export const trackReportPublished = ( + reportId: number, + metrics: UpdatedMetricsValues[], + agency?: UserAgency +): void => { + const metricsReported = metrics.reduce((res: string[], metric) => { + if (metric.value !== null) { + res.push(metric.key); + } + return res; + }, []); + const metricsReportedCount = metricsReported.length; + const metricsReportedWithContext = metrics.reduce((res: string[], metric) => { + if ( + metric.contexts.find( + (context) => context.value !== null && context.value !== undefined + ) + ) { + res.push(metric.key); + } + return res; + }, []); + const metricsReportedWithContextCount = metricsReportedWithContext.length; + const metricsReportedWithDisaggregations = metrics.reduce( + (res: string[], metric) => { + if ( + metric.disaggregations.find((disaggregation) => + disaggregation.dimensions.find( + (dimension) => + dimension.value !== undefined && dimension.value !== null + ) + ) + ) { + res.push(metric.key); + } + return res; + }, + [] + ); + const metricsReportedWithDisaggregationsCount = + metricsReportedWithDisaggregations.length; + const totalMetricsCount = metrics.length; + track("frontend_report_published", { + reportId, + metricsReportedCount, + metricsReportedWithContextCount, + metricsReportedWithDisaggregationsCount, + totalMetricsCount, + agencyId: agency?.id, + agencyName: agency?.name, + agencyFips: agency?.fips_county_code, + agencyState: agency?.state_code, + agencySystem: agency?.system, + agencySystems: agency?.systems, + }); +}; + +export const trackReportUnpublished = ( + reportId: number, + agency?: UserAgency +): void => { + track("frontend_report_unpublished", { + reportId, + agencyId: agency?.id, + agencyName: agency?.name, + agencyFips: agency?.fips_county_code, + agencyState: agency?.state_code, + agencySystem: agency?.system, + agencySystems: agency?.systems, + }); +}; + +export const trackNetworkError = ( + path: string, + method: string, + status: number, + errorMsg: string +): void => { + track("frontend_network_error", { + path, + method, + status, + errorMsg, + }); +}; + +export const trackAutosaveTriggered = (reportId: number): void => { + track("frontend_report_autosave_triggered", { + reportId, + }); +}; + +export const trackAutosaveFailed = (reportId: number): void => { + track("frontend_report_autosave_failed", { + reportId, + }); +}; + +export const trackNavigation = (screen: string): void => { + track("frontend_navigate", { + screen, + }); +}; + +export const trackLoadTime = ( + path: string, + method: string, + loadTime: number +): void => { + track("load_time", { + path, + method, + loadTime, + }); +}; diff --git a/publisher/src/components/Auth/Auth.test.tsx b/publisher/src/components/Auth/Auth.test.tsx new file mode 100644 index 000000000..e1db4761f --- /dev/null +++ b/publisher/src/components/Auth/Auth.test.tsx @@ -0,0 +1,88 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import createAuth0Client from "@auth0/auth0-spa-js"; + +import { AuthStore } from "./AuthStore"; + +jest.mock("@auth0/auth0-spa-js"); + +const mockCreateAuth0Client = createAuth0Client as jest.Mock; +const mockGetUser = jest.fn(); +const mockIsAuthenticated = jest.fn(); +const mockLoginWithRedirect = jest.fn(); + +beforeEach(() => { + mockCreateAuth0Client.mockResolvedValue({ + getUser: mockGetUser, + isAuthenticated: mockIsAuthenticated, + loginWithRedirect: mockLoginWithRedirect, + }); +}); + +afterEach(() => { + jest.resetAllMocks(); +}); + +const testAuthSettings = { + domain: "test.auth0.com", + client_id: "testclientid", + redirect_url: window.location.href, +}; + +const store = new AuthStore({ authSettings: testAuthSettings }); + +test("authorization pending when required", async () => { + expect(store.isAuthorized).toBe(false); + expect(store.isLoading).toBe(true); + + expect.hasAssertions(); +}); + +test("authorized when authenticated", async () => { + mockIsAuthenticated.mockResolvedValue(true); + + await store.authenticate(); + expect(store.isAuthorized).toBe(true); + expect(store.isLoading).toBe(false); + + expect.hasAssertions(); +}); + +test("requires email verification", async () => { + mockGetUser.mockResolvedValue({ emailVerified: false }); + mockIsAuthenticated.mockResolvedValue(true); + + await store.authenticate(); + expect(store.isAuthorized).toBe(true); + expect(store.emailVerified).toBe(false); + + expect.hasAssertions(); +}); + +test("redirect to Auth0 when unauthenticated", async () => { + mockIsAuthenticated.mockResolvedValue(false); + expect(mockLoginWithRedirect.mock.calls.length).toBe(0); + + await store.authenticate(); + expect(mockLoginWithRedirect.mock.calls.length).toBe(1); + expect(mockLoginWithRedirect.mock.calls[0][0]).toEqual({ + appState: { targetUrl: window.location.href }, + }); + + expect.hasAssertions(); +}); diff --git a/publisher/src/components/Auth/AuthStore.ts b/publisher/src/components/Auth/AuthStore.ts new file mode 100644 index 000000000..82cb67ba6 --- /dev/null +++ b/publisher/src/components/Auth/AuthStore.ts @@ -0,0 +1,136 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import createAuth0Client, { + Auth0Client, + Auth0ClientOptions, + GetTokenSilentlyOptions, + User, +} from "@auth0/auth0-spa-js"; +import { makeAutoObservable, runInAction } from "mobx"; +import qs from "qs"; + +import { identify } from "../../analytics"; + +export const APP_METADATA_CLAIM = + "https://dashboard.recidiviz.org/app_metadata"; + +interface AuthStoreProps { + authSettings: Auth0ClientOptions | undefined; +} +export class AuthStore { + readonly authSettings: Auth0ClientOptions | undefined; + + private authClient: Auth0Client | undefined; + + emailVerified?: boolean; + + isAuthorized: boolean; + + isLoading: boolean; + + user?: User; + + constructor({ authSettings }: AuthStoreProps) { + makeAutoObservable(this); + + this.authSettings = authSettings; + this.authClient = undefined; + this.isAuthorized = false; + this.isLoading = true; + } + + private get auth0Client(): Promise { + return createAuth0Client(this.authSettings as Auth0ClientOptions); + } + + async authenticate(): Promise { + const auth0 = await this.auth0Client; + + runInAction(() => { + this.authClient = auth0; + }); + + /* + * Note: need to research this issue further + * Auth0 library responds to the presence of query parameters (code, state, and error) all of which + * indicate that we have been redirected from the Auth0 login page. If they are not removed before + * further interaction with the library, the application enters an infinite loop with newly regenerated + * state/code/error params. The below logic mitigates that by stripping away the parameters + * completely or replaces them with the `targetUrl`. + */ + const urlQuery = qs.parse(window.location.search, { + ignoreQueryPrefix: true, + }); + + if (urlQuery.code && urlQuery.state) { + const { appState } = await auth0.handleRedirectCallback(); + // auth0 params are single-use, must be removed from history or they can cause errors + let replacementUrl; + + if (appState && appState.targetUrl) { + replacementUrl = appState.targetUrl; + } else { + // strip away all query params just to be safe + replacementUrl = `${window.location.origin}${window.location.pathname}`; + } + + window.history.replaceState({}, document.title, replacementUrl); + } + + if (await auth0.isAuthenticated()) { + const user = await auth0.getUser(); + if (user?.sub) { + identify(user.sub, { + name: user.name, + email: user.email, + }); + } + + runInAction(() => { + this.isLoading = false; + this.user = user; + this.isAuthorized = true; + this.emailVerified = Boolean(user?.email_verified); + }); + } else { + await auth0.loginWithRedirect({ + appState: { targetUrl: window.location.href }, + }); + } + } + + async logoutUser() { + runInAction(() => { + this.isAuthorized = false; + this.isLoading = true; + }); + + return this.authClient?.logout({ returnTo: window.location.origin }); + } + + async getToken(options?: GetTokenSilentlyOptions): Promise { + try { + if (this.authClient) { + return this.authClient.getTokenSilently(options); + } + return Promise.reject(new Error("No auth client initialized.")); + } catch (error) { + throw new Error(`Unable to retrieve token - ${error}`); + } + } +} diff --git a/publisher/src/components/Auth/AuthWall.tsx b/publisher/src/components/Auth/AuthWall.tsx new file mode 100644 index 000000000..3440ab135 --- /dev/null +++ b/publisher/src/components/Auth/AuthWall.tsx @@ -0,0 +1,57 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { when } from "mobx"; +import { observer } from "mobx-react-lite"; +import React, { useEffect } from "react"; + +import { useStore } from "../../stores/StoreProvider"; +import { Loading } from "../Loading"; +import UnauthorizedPage from "./UnauthorizedPage"; +import VerificationPage from "./VerificationPage"; + +const AuthWall: React.FC = ({ + children, +}): React.ReactElement | null => { + const { authStore } = useStore(); + + useEffect( + () => + // return when's disposer so it is cleaned up if it never runs + when( + () => !authStore.isAuthorized, + () => authStore.authenticate() + ), + [authStore] + ); + + if (authStore.isLoading) { + return ; + } + + if (!authStore.isAuthorized) { + return ; + } + + if (!authStore.emailVerified) { + return ; + } + + return authStore.isAuthorized ? <>{children} : null; +}; + +export default observer(AuthWall); diff --git a/publisher/src/components/Auth/UnauthorizedPage.tsx b/publisher/src/components/Auth/UnauthorizedPage.tsx new file mode 100644 index 000000000..ae52f9e05 --- /dev/null +++ b/publisher/src/components/Auth/UnauthorizedPage.tsx @@ -0,0 +1,48 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { + Button, + ErrorPage, + Link as TypographyLink, +} from "@recidiviz/design-system"; +import React from "react"; + +import { useStore } from "../../stores/StoreProvider"; + +const UnauthorizedPage = () => { + const { authStore } = useStore(); + + return ( + +

+ This page is currently unavailable for your account. Please reach out to{" "} + + Recidiviz Support + {" "} + with any questions. +

+ + {/* Optional: takes user back to login screen */} + +
+ ); +}; + +export default UnauthorizedPage; diff --git a/publisher/src/components/Auth/VerificationPage.tsx b/publisher/src/components/Auth/VerificationPage.tsx new file mode 100644 index 000000000..335b30136 --- /dev/null +++ b/publisher/src/components/Auth/VerificationPage.tsx @@ -0,0 +1,126 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import styled from "styled-components/macro"; + +import { useStore } from "../../stores/StoreProvider"; +import logo from "../assets/jc-logo-green-vector.png"; +import { palette, typography } from "../GlobalStyles"; + +export const PageContainer = styled.div` + display: flex; + justify-content: center; + height: 100%; + align-items: center; +`; + +export const ContentContainer = styled.div` + display: flex; + flex-direction: column; + width: 652px; +`; +export const LogoContainer = styled.div` + display: flex; +`; +export const Logo = styled.img` + width: 60px; + height: 60px; +`; +export const LogoTitleContainer = styled.div` + ${typography.sizeCSS.medium} + display: flex; + flex-direction: column; + padding-left: 10px; + padding-top: 10px; +`; + +export const VerificationPageHeader = styled.div` + ${typography.sizeCSS.large} + padding-top: 50px; +`; + +export const ParagraphContainer = styled.div` + ${typography.sizeCSS.medium} + padding-top: 24px; + padding-bottom: 32px; + color: ${palette.solid.grey}; +`; + +export const JusticeCountsSupportLink = styled.a` + color: ${palette.solid.green}; +`; + +export const VerificationLogoutButton = styled.button` + width: 147px; + height: 56px; + display: flex; + justify-content: center; + align-items: center; + background: ${palette.solid.blue}; + border: 1px solid ${palette.highlight.grey3}; + color: ${palette.solid.white}; + font-size: 18px; + &:hover { + cursor: pointer; + } +`; + +const VerificationPage = () => { + const { authStore } = useStore(); + const handleLogout = () => authStore.logoutUser(); + + return ( + + + + + +
Publisher
+
By Justice Counts
+
+
+ + Please verify your email. + + +

+ If you have just signed up for an account, please check your inbox + for an email asking you to verify your email address. After you + click the verification button or link in that email, you can reach + the home page below. +

+
+

+ If you have reached this page by mistake, please try to log in + again. If you are still having trouble, please reach out to{" "} + + Justice Counts Support + + . +

+
+ + + Logout + +
+
+ ); +}; + +export default VerificationPage; diff --git a/publisher/src/components/Auth/index.ts b/publisher/src/components/Auth/index.ts new file mode 100644 index 000000000..0c1fcc874 --- /dev/null +++ b/publisher/src/components/Auth/index.ts @@ -0,0 +1,19 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./AuthStore"; +export { default } from "./AuthWall"; diff --git a/publisher/src/components/Badge/Badge.tsx b/publisher/src/components/Badge/Badge.tsx new file mode 100644 index 000000000..0ecc41b1c --- /dev/null +++ b/publisher/src/components/Badge/Badge.tsx @@ -0,0 +1,77 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= +import React from "react"; +import styled from "styled-components/macro"; + +import { palette } from "../GlobalStyles"; +import { MiniLoader } from "../Loading/MiniLoader"; + +export type BadgeColors = "RED" | "GREEN" | "ORANGE" | "GREY"; + +export type BadgeColorMapping = { [key: string]: BadgeColors }; + +export type BadgeProps = { + color: BadgeColors; + disabled?: boolean; + loading?: boolean; +}; + +export const BadgeElement = styled.div<{ + color?: BadgeColors; + disabled?: boolean; +}>` + height: 24px; + display: flex; + justify-content: center; + align-items: center; + background: ${({ color, disabled }) => { + if (color === "GREY" || disabled) { + return palette.highlight.grey9; + } + if (color === "RED") { + return palette.solid.red; + } + if (color === "GREEN") { + return palette.solid.green; + } + if (color === "ORANGE") { + return palette.solid.orange; + } + return palette.highlight.grey5; + }}; + color: ${palette.solid.white}; + padding: 4px 8px; + margin-left: 10px; + font-size: 0.65rem; + font-weight: 600; + white-space: nowrap; + text-transform: capitalize; +`; + +export const Badge: React.FC = ({ + color, + disabled, + loading, + children, +}) => { + return ( + + {children} + {loading && } + + ); +}; diff --git a/publisher/src/components/Badge/index.ts b/publisher/src/components/Badge/index.ts new file mode 100644 index 000000000..891be9860 --- /dev/null +++ b/publisher/src/components/Badge/index.ts @@ -0,0 +1,18 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./Badge"; diff --git a/publisher/src/components/DataUpload/DataUpload.styles.tsx b/publisher/src/components/DataUpload/DataUpload.styles.tsx new file mode 100644 index 000000000..dc531368d --- /dev/null +++ b/publisher/src/components/DataUpload/DataUpload.styles.tsx @@ -0,0 +1,483 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import styled from "styled-components/macro"; + +import { rem } from "../../utils"; +import { HEADER_BAR_HEIGHT, palette, typography } from "../GlobalStyles"; +import { + Cell, + LabelCell, + LabelRow, + PageTitle, + Row, + TabbedBar, + Table, +} from "../Reports"; + +const ROW_HEIGHT = 42; + +export const DataUploadContainer = styled.div` + width: 100%; + height: 100%; + position: absolute; + top: 0; + z-index: 5; + background: ${palette.solid.white}; + + a, + a:visited { + color: ${palette.solid.blue}; + text-decoration: none; + transition: 0.2s ease; + } + + a:hover { + color: ${palette.solid.darkblue}; + cursor: pointer; + } +`; + +export const DataUploadHeader = styled.div<{ transparent?: boolean }>` + width: 100%; + height: ${HEADER_BAR_HEIGHT}px; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; + padding-right: 24px; + ${({ transparent }) => + !transparent && + ` + background: ${palette.solid.white}; + border-bottom: 1px solid ${palette.highlight.grey3}; + `} +`; + +export const MediumPageTitle = styled(PageTitle)` + font-size: ${rem("50px")}; +`; + +export const Instructions = styled.div` + height: 100%; + flex: 1 1 50%; + padding: 103px; + display: flex; + flex-direction: column; + overflow-y: scroll; + ${typography.sizeCSS.medium} + + h1 { + ${typography.sizeCSS.title} + } + + h2 { + ${typography.sizeCSS.large} + margin: 15px 0; + } + + h3 { + ${typography.sizeCSS.large} + font-size: ${rem("22px")}; + color: ${palette.highlight.grey10}; + margin-top: 15px; + } + + h1, + h2, + h3 { + text-transform: capitalize; + } + + ol, + ul, + p { + margin: 10px 0; + } + + ol, + ul { + line-height: 1.8rem; + } + + li { + margin-left: 50px; + } + + li ul { + margin: 0; + } + + table { + max-width: 50%; + width: max-content; + margin: 15px 0; + text-align: left; + border: 0.5px solid black; + border-spacing: 0; + ${typography.sizeCSS.normal}; + } + + thead { + background: ${palette.highlight.grey2}; + } + + th, + td { + border: 0.5px solid black; + padding: 5px 20px; + } +`; + +export const ButtonWrapper = styled.div` + display: flex; + flex-wrap: wrap; + gap: 10px; + margin: 13px 0; +`; + +export type ButtonTypes = + | "light-border" + | "border" + | "borderless" + | "blue" + | "red"; + +export const Button = styled.div<{ type?: ButtonTypes }>` + ${typography.sizeCSS.normal}; + display: flex; + align-items: center; + padding: 10px 15px; + border-radius: 3px; + gap: 16px; + text-transform: capitalize; + + ${({ type }) => { + if (type === "light-border") { + return ` + background: none; + border: 1px solid ${palette.solid.white}; + color: ${palette.solid.white}; + border-radius: 4px; + `; + } + if (type === "border") { + return ` + border: 1px solid ${palette.highlight.grey4}; + border-radius: 4px; + `; + } + if (type === "borderless") { + return ` + background: none; + color: ${palette.highlight.grey10}; + `; + } + if (type === "blue") { + return ` + background: ${palette.solid.blue}; + color: ${palette.solid.white}; + `; + } + if (type === "red") { + return ` + background: ${palette.solid.red}; + color: ${palette.solid.white}; + `; + } + return ` + background: ${palette.highlight.grey1}; + color: ${palette.highlight.grey10}; + `; + }} + + &:hover { + cursor: pointer; + ${({ type }) => { + if (type === "border") { + return `background: ${palette.highlight.grey1};`; + } + if (type === "borderless") { + return `opacity: 0.8;`; + } + if (type === "blue" || type === "red") { + return `opacity: 0.9;`; + } + return `background: ${palette.highlight.grey2};`; + }}; + } + + a { + ${typography.sizeCSS.small}; + width: fit-content; + text-decoration: none; + color: ${palette.solid.blue}; + display: flex; + align-items: center; + } +`; + +export const DownloadTemplateBox = styled.div` + ${typography.sizeCSS.normal}; + display: flex; + align-items: center; + padding: 10px 15px; + border-radius: 3px; + gap: 16px; + text-transform: capitalize; + background: none; + border: 1px solid ${palette.highlight.grey4}; + border-radius: 4px; + + a { + ${typography.sizeCSS.small}; + display: block; + width: fit-content; + text-decoration: none; + color: ${palette.solid.blue}; + } +`; + +export const UploadButtonLabel = styled.label` + display: inline-block; + border-bottom: 1px solid ${palette.solid.white}; + + &:hover { + cursor: pointer; + } +`; + +export const UploadButtonInput = styled.input` + display: none; +`; + +export const DropdownItemUploadInput = styled.input` + display: none; +`; + +export const Icon = styled.img<{ grayscale?: boolean }>` + width: 16px; + aspect-ratio: auto; + margin-left: 10px; + ${({ grayscale }) => grayscale && `filter: grayscale(1);`} +`; + +export const ModalLoadingWrapper = styled.div` + div { + height: 100%; + top: 25%; + } +`; + +export const ModalErrorWrapper = styled.div` + display: flex; + justify-content: center; + margin-top: 25px; +`; + +export const DownloadIcon = styled.img` + width: 20px; + margin-right: 5px; +`; + +export const ActionsContainer = styled.div` + ${typography.sizeCSS.normal}; + height: 100%; + display: flex; + justify-content: flex-end; + align-items: center; + background: ${palette.solid.offwhite}; + gap: 10px; + padding-left: 20px; + position: absolute; + right: 22px; + z-index: 3; + width: 25vw; +`; + +export const ActionButton = styled.div<{ red?: boolean }>` + color: ${({ red }) => (red ? palette.solid.red : palette.solid.blue)}; + &:hover { + color: ${palette.solid.darkgrey}; + } +`; + +export const UploadFileContainer = styled.div` + height: 100%; + display: flex; +`; + +export const DragDropContainer = styled.div<{ dragging?: boolean }>` + height: 100%; + display: flex; + flex-direction: column; + flex: 1 1 50%; + align-items: center; + justify-content: center; + background: ${({ dragging }) => + dragging ? palette.solid.darkblue : palette.solid.blue}; + color: ${palette.solid.white}; +`; + +export const UserPromptContainer = styled.div` + width: 100%; + min-height: 100%; + display: flex; + justify-content: center; + align-items: center; + padding-top: ${HEADER_BAR_HEIGHT + 80}px; + padding-bottom: 80px; +`; + +export const UserPromptWrapper = styled.div` + width: 100%; + max-width: 50%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; +`; + +export const UserPromptTitle = styled.div` + ${typography.sizeCSS.title}; +`; + +export const UserPromptDescription = styled.div` + ${typography.sizeCSS.medium}; + margin: 8px 0; + + span { + text-transform: capitalize; + } +`; + +export const UserPromptErrorContainer = styled.div` + width: 100%; + margin-top: 19px; +`; + +export const UserPromptError = styled.div` + margin-bottom: 40px; +`; + +export const MetricTitle = styled.div` + ${typography.sizeCSS.large}; + border-top: 1px solid ${palette.highlight.grey4}; + padding: 16px 0; +`; + +export const ErrorIconWrapper = styled.div` + display: flex; + align-items: center; + gap: 5px; +`; +export const ErrorMessageWrapper = styled.div` + ${typography.sizeCSS.medium}; + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; +`; + +export const ErrorMessageTitle = styled.div` + display: block; +`; + +export const ErrorMessageDescription = styled.div` + display: block; +`; + +export const ErrorAdditionalInfo = styled.div` + ${typography.sizeCSS.normal}; + margin: 8px 0 13px 0; +`; + +export const SelectSystemOptions = styled.div` + width: 100%; + margin-top: 32px; +`; + +export const SystemName = styled.div` + ${typography.sizeCSS.large}; + padding: 20px 0; + border-top: 1px solid ${palette.highlight.grey4}; + display: flex; + justify-content: space-between; + align-items: center; + text-transform: uppercase; + + &:hover { + cursor: pointer; + color: ${palette.solid.blue}; + } +`; + +export const FileName = styled.div<{ error?: boolean }>` + ${typography.sizeCSS.medium}; + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 16px; + color: ${({ error }) => (error ? palette.solid.red : palette.solid.green)}; +`; + +export const ConfirmationPageContainer = styled.div` + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +`; + +export const UploadedFilesContainer = styled.div` + height: 100%; + padding: ${ROW_HEIGHT}px 0; + overflow-y: scroll; +`; + +export const UploadedFilesTable = styled(Table)` + padding: unset; +`; + +export const ExtendedTabbedBar = styled(TabbedBar)` + height: 66px; +`; + +export const ExtendedRow = styled(Row)` + color: ${({ selected }) => selected && palette.highlight.grey9}; + position: relative; + transition: unset; +`; + +export const ExtendedLabelRow = styled(LabelRow)` + position: fixed; + background: ${palette.solid.white}; + z-index: 1; +`; + +export const ExtendedCell = styled(Cell)` + &:first-child { + flex: 4 1 auto; + } +`; + +export const ExtendedLabelCell = styled(LabelCell)` + &:first-child { + flex: 4 1 auto; + } +`; diff --git a/publisher/src/components/DataUpload/DataUpload.tsx b/publisher/src/components/DataUpload/DataUpload.tsx new file mode 100644 index 000000000..569f8d1d3 --- /dev/null +++ b/publisher/src/components/DataUpload/DataUpload.tsx @@ -0,0 +1,323 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { observer } from "mobx-react-lite"; +import React, { Fragment, useState } from "react"; +import { useNavigate } from "react-router-dom"; + +import { AgencySystems } from "../../shared/types"; +import { useStore } from "../../stores"; +import { removeSnakeCase } from "../../utils"; +import { ReactComponent as ErrorIcon } from "../assets/error-icon.svg"; +import logoImg from "../assets/jc-logo-vector.png"; +import { ReactComponent as WarningIcon } from "../assets/warning-icon.svg"; +import { Logo, LogoContainer } from "../Header"; +import { Loading } from "../Loading"; +import { showToast } from "../Toast"; +import { + Button, + ButtonWrapper, + DataUploadContainer, + DataUploadHeader, + ErrorAdditionalInfo, + ErrorIconWrapper, + ErrorMessageDescription, + ErrorMessageTitle, + ErrorMessageWrapper, + FileName, + MetricTitle, + SystemSelection, + UploadFile, + UserPromptContainer, + UserPromptDescription, + UserPromptError, + UserPromptErrorContainer, + UserPromptTitle, + UserPromptWrapper, +} from "."; + +export type UploadedFileStatus = "UPLOADED" | "INGESTED" | "ERRORED"; + +export type UploadedFileAttempt = { + name: string; + upload_attempt_timestamp: number; + status?: "ERRORED"; +}; + +export type UploadedFile = { + name: string; + id: number; + uploaded_at: number; + ingested_at: number; + uploaded_by: string; + system: AgencySystems; + status: UploadedFileStatus | null; +}; + +/** + * The systems in EXCLUDED_SYSTEMS are sub-systems of the SUPERVISION system, + * and should not render a separate template & instructions. + * + * Example: if an agency has the following systems ["SUPERVISION", "PAROLE", "PROBATION"], + * the UI should render a template & instructions for the SUPERVISION system. + */ +export const EXCLUDED_SYSTEMS = ["PAROLE", "PROBATION", "POST_RELEASE"]; + +export const systemToTemplateSpreadsheetFileName: { [system: string]: string } = + { + LAW_ENFORCEMENT: "LAW_ENFORCEMENT.xlsx", + PROSECUTION: "PROSECUTION.xlsx", + DEFENSE: "DEFENSE.xlsx", + COURTS_AND_PRETRIAL: "COURTS_AND_PRETRIAL.xlsx", + JAILS: "JAILS.xlsx", + PRISONS: "PRISONS.xlsx", + SUPERVISION: "SUPERVISION.xlsx", + PAROLE: "SUPERVISION.xlsx", + PROBATION: "SUPERVISION.xlsx", + }; + +export const DataUpload: React.FC = observer(() => { + const { userStore, reportStore } = useStore(); + const navigate = useNavigate(); + const userSystems = + userStore.currentAgency?.systems.filter( + (system) => !EXCLUDED_SYSTEMS.includes(system) + ) || []; + + const [isLoading, setIsLoading] = useState(false); + const [uploadError, setUploadError] = useState(false); + const [selectedFile, setSelectedFile] = useState(); + const [selectedSystem, setSelectedSystem] = useState< + AgencySystems | undefined + >(userSystems.length === 1 ? userSystems[0] : undefined); + + const handleFileUpload = async ( + file: File, + system: AgencySystems + ): Promise => { + if (file && system && userStore.currentAgencyId) { + const formData = new FormData(); + formData.append("file", file); + formData.append("name", file.name); + formData.append("system", system); + formData.append("ingest_on_upload", "True"); + formData.append("agency_id", userStore.currentAgencyId.toString()); + + const response = await reportStore.uploadExcelSpreadsheet(formData); + setIsLoading(false); + + if (response instanceof Error) { + setUploadError(true); + return showToast("Failed to upload. Please try again.", false, "red"); + } + + setUploadError(false); + showToast( + "File uploaded successfully and is pending processing by a Justice Counts administrator.", + true, + undefined, + 3500 + ); + /** Placeholder - this should navigate to the confirmation component */ + navigate("/"); + } + }; + + const handleSystemSelection = (file: File, system: AgencySystems) => { + setIsLoading(true); + setSelectedSystem(system); + handleFileUpload(file, system); + setSelectedFile(undefined); + }; + + if (isLoading) { + return ( + + + + ); + } + + const renderCurrentUploadStep = (): JSX.Element => { + if (selectedFile) { + /** System Selection Step (for multi-system users) */ + return ( + + ); + } + + /** Upload Error/Warnings Step */ + if (uploadError) { + /** This object is temporary for the purpose of displaying each UI state */ + const mockErrors = [ + { + metricTitle: "Releases", + errorsAndWarnings: [ + { + type: "error", + errorTitle: "Breakdown not recognized", + errorDescription: "Label Not Recognized", + }, + { + type: "error", + errorTitle: "Breakdown not recognized", + errorDescription: "Label Not Recognized", + }, + { + type: "error", + errorTitle: "Breakdown not recognized", + errorDescription: "Label Not Recognized", + }, + { + type: "warning", + errorTitle: "Breakdown not recognized", + errorDescription: "Label Not Recognized", + }, + ], + }, + { + metricTitle: "Admissions", + errorsAndWarnings: [ + { + type: "error", + errorTitle: "Missing value", + errorDescription: "August 2022: Total", + additionalInfo: + "The total value for Admissions will be shown as the sum of the breakdowns.", + }, + { + type: "error", + errorTitle: "Breakdown not recognized", + errorDescription: "Label Not Recognized", + }, + { + type: "error", + errorTitle: "Breakdown not recognized", + errorDescription: "Label Not Recognized", + }, + { + type: "warning", + errorTitle: "Breakdown not recognized", + errorDescription: "Label Not Recognized", + }, + ], + }, + ]; + + const systemFileName = + selectedSystem && systemToTemplateSpreadsheetFileName[selectedSystem]; + + return ( + + + + + File Name.xls + + Uh oh, we found 4 errors. + + We ran into a few discrepancies between the uploaded data and the + Justice Counts format for the{" "} + + + {selectedSystem && + removeSnakeCase(selectedSystem).toLowerCase()} + + {" "} + system. To continue, please resolve the errors in your file and + reupload. + + + + + + + + {mockErrors.map((item) => ( + + {item.metricTitle} + + {item.errorsAndWarnings?.map((errorItem) => ( + + + {errorItem.type === "error" ? ( + + ) : ( + + )} + + + + {errorItem.errorTitle} + + + {errorItem.errorDescription} + + + + + {errorItem.additionalInfo} + + + ))} + + ))} + + + + ); + } + + /** Upload File Step */ + return ( + + ); + }; + + return ( + + + navigate("/")}> + + + + + + + {renderCurrentUploadStep()} + + ); +}); diff --git a/publisher/src/components/DataUpload/InstructionsTemplate.tsx b/publisher/src/components/DataUpload/InstructionsTemplate.tsx new file mode 100644 index 000000000..adcd127e6 --- /dev/null +++ b/publisher/src/components/DataUpload/InstructionsTemplate.tsx @@ -0,0 +1,558 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; + +import { removeSnakeCase } from "../../utils"; +import { ReactComponent as SpreadsheetIcon } from "../assets/microsoft-excel-icon.svg"; +import { + ButtonWrapper, + DownloadTemplateBox, + systemToTemplateSpreadsheetFileName, +} from "."; + +export type GeneralInstructionsTemplateParams = { + systems: string[]; +}; + +export type SystemsInstructionsTemplateParams = { + system: string; +}; + +type SystemDetails = { + name: string; + url: string; + metric: string; + metric_sheet_name: string; + metric_disaggregation_sheet_name: string; + metric_category: string; + metric_disaggregation: string; + metric_disaggregation_column_name: string; + metric_disaggregation_values: { [name: string]: number | string }[]; +}; + +export const systemToDetails: { [system: string]: SystemDetails } = { + LAW_ENFORCEMENT: { + name: "Law Enforcement", + url: "https://justicecounts.csgjusticecenter.org/metrics/sectors/law-enforcement/", + metric: "Reported Crime", + metric_sheet_name: "reported_crime", + metric_disaggregation_sheet_name: "reported_crime_by_type", + metric_category: "Population Movements", + metric_disaggregation: "offense type", + metric_disaggregation_column_name: "offense_type", + metric_disaggregation_values: [ + { name: "Person", value: 3291 }, + { name: "Property", value: 1293 }, + { name: "Drug", value: 504 }, + { name: "Other", value: 34 }, + { name: "Unknown", value: 3 }, + ], + }, + DEFENSE: { + name: "Defense", + url: "https://justicecounts.csgjusticecenter.org/metrics/sectors/defense/", + metric: "Cases Appointed Counsel", + metric_sheet_name: "cases_appointed", + metric_disaggregation_sheet_name: "cases_appointed_by_severity", + metric_category: "Population Movements", + metric_disaggregation: "case severity", + metric_disaggregation_column_name: "case_severity", + metric_disaggregation_values: [ + { name: "Felony", value: 3291 }, + { name: "Misdemeanor", value: 1293 }, + { name: "Infraction", value: 504 }, + { name: "Unknown", value: 3 }, + ], + }, + PROSECUTION: { + name: "Prosecution", + url: "https://justicecounts.csgjusticecenter.org/metrics/sectors/prosecution/", + metric: "Cases Declined", + metric_sheet_name: "cases_declined", + metric_disaggregation_sheet_name: "cases_declined_by_severity", + metric_category: "Operations and Dynamics", + metric_disaggregation: "case severity", + metric_disaggregation_column_name: "case_severity", + metric_disaggregation_values: [ + { name: "Felony", value: 3291 }, + { name: "Misdemeanor", value: 1293 }, + { name: "Infraction", value: 504 }, + { name: "Unknown", value: 3 }, + ], + }, + COURTS_AND_PRETRIAL: { + name: "Courts and Pretrial", + url: "https://justicecounts.csgjusticecenter.org/metrics/sectors/courts-pretrial/", + metric: "Pretrial Releases", + metric_sheet_name: "pretrial_releases", + metric_disaggregation_sheet_name: "pretrial_releases_by_type", + metric_category: "Operations and Dynamics", + metric_disaggregation: "release type", + metric_disaggregation_column_name: "release_type", + metric_disaggregation_values: [ + { name: "ROR", value: 3291 }, + { name: "Monetary bail", value: 1293 }, + { name: "Supervision", value: 504 }, + { name: "Other", value: 34 }, + { name: "Unknown", value: 3 }, + ], + }, + JAILS: { + name: "Jails", + url: "https://justicecounts.csgjusticecenter.org/metrics/sectors/jails/", + metric: "Admissions", + metric_sheet_name: "admissions", + metric_disaggregation_sheet_name: "admissions_by_type", + metric_category: "Population Movements", + metric_disaggregation: "admission type", + metric_disaggregation_column_name: "admission_type", + metric_disaggregation_values: [ + { name: "Pretrial", value: 3291 }, + { name: "Sentenced", value: 1293 }, + { name: "Transfer or Hold", value: 504 }, + { name: "Unknown", value: 3 }, + ], + }, + PRISONS: { + name: "Prisons", + url: "https://justicecounts.csgjusticecenter.org/metrics/sectors/prisons/", + metric: "Admissions", + metric_sheet_name: "admissions", + metric_disaggregation_sheet_name: "admissions_by_type", + metric_category: "Population Movements", + metric_disaggregation: "admission type", + metric_disaggregation_column_name: "admission_type", + metric_disaggregation_values: [ + { name: "New Sentence", value: 3291 }, + { name: "Transfer or Hold", value: 1293 }, + { name: "Supervision Violation or Revocation", value: 504 }, + { name: "Other", value: 34 }, + { name: "Unknown", value: 3 }, + ], + }, + SUPERVISION: { + name: "Supervision", + url: "https://justicecounts.csgjusticecenter.org/metrics/sectors/community-supervision/", + metric: "New Supervision Cases", + metric_sheet_name: "new_cases", + metric_disaggregation_sheet_name: "new_cases_by_type", + metric_category: "Population Movements", + metric_disaggregation: "supervision type", + metric_disaggregation_column_name: "supervision_type", + metric_disaggregation_values: [ + { name: "Active", value: 3291 }, + { name: "Passive", value: 1293 }, + { name: "Unknown", value: 504 }, + ], + }, +}; + +export const GeneralInstructions: React.FC< + GeneralInstructionsTemplateParams +> = ({ systems }) => { + return ( + <> +

How to Upload Data to Justice Counts

+

+ Agencies participating in Justice Counts have two options for reporting + their assigned metrics: +

+
    +
  1. + Filling out the autogenerated reports on the{" "} + + Reports + {" "} + page +
  2. +
  3. Uploading an Excel spreadsheet
  4. +
+

+ If you choose the second option, we require that you upload the + spreadsheet in a particular format, so we can build automation on + our end to easily upload this data into our platform. +

+ +

Templates

+ + + {systems.map((system) => { + const systemName = removeSnakeCase(system).toLowerCase(); + const systemFileName = systemToTemplateSpreadsheetFileName[system]; + + return ( + + + + + {systemName} + + Download + + + + ); + })} + + +

+ Complete, downloadable spreadsheet templates can be found above. We + suggest that you download the template and review it, and then read the + description below for more detail. +

+

High-Level Summary

+

+ In this section, we provide instructions applicable to all agencies. In + the next section, we provide instructions specific to your agency. +

+

Basics

+

+ You will need to generate one Excel workbook for each criminal justice + system that your agency is reporting data for. Your agency is + responsible for reporting data for:{" "} + {/* replace last comma with "and": https://stackoverflow.com/a/41035407 */} + {systems + .map((system) => systemToDetails[system].name) + .join(", ") + .replace(/,(?!.*,)/gim, " and")} + . +

+

+ Include one sheet (or tab) in the workbook for each Justice Counts + metric defined for the system. See the{" "} + + Justice Counts website + {" "} + for a list and description of these metrics. +

+

+ We require that each sheet is given a standard name.{" "} + Refer to your template file for the valid sheet names. +

+

+ All sheets will have columns for year and value. Monthly + metrics will also have a column for month. +

+

+ To report data for a metric for a particular time period, add a new row + to the sheet. Fill in the appropriate values for the year and{" "} + month columns, and report the metric value in the value{" "} + column. +

+

+ The year should be in the format 20XX. The month should either be a + number [1 … 12] or the full month name [January … February]. The metric + value should be numeric and contain no other characters (commas are + allowed, e.g. 1,000). +

+ +

The sheets will look roughly like this:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
yearmonthvalue
202175088
202185270
202195113
2021105196
2021115237
2021125123
+

Disaggregations

+

+ If the metric asks you to break the value down into different categories + (e.g. separating out crimes by offense type), add an additional sheet to + the workbook that includes a column with the name of the category (e.g.{" "} + offense_type). Each row should specify a different value for that + category (e.g. person, property, drug). +

+

+ We require that each sheet and column is given a standard name.{" "} + + Refer to your template file for the name of the new sheet, the name of + the new column for category names, and the valid values for this + column. + +

+

+ + Please only provide valid category names (as seen in your template + file) in the new column.{" "} + + If your agency categorizes the metric differently, group any unmatched + data into the Other category. +

+ +

+ For instance, a sheet for reported_crimes_by_type might look like + this: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
yearmonthvalueoffense_type
20217Person3291
20217Property1293
20217Drug504
20217Other372
20217Unknown53
+

+ Fill in as many categories as you can. Skip any that are not applicable + to your agency. +

+

Multiple Jurisdictions

+

+ If you are reporting data for multiple jurisdictions, you should also + add a column to each sheet titled jurisdiction_name. The value of + this column should be the name of the jurisdiction to which that data + point belongs. For instance: +

+ + + + + + + + + + + + + + + + + + + + + +
yearjurisdiction_namevalue
2021County X1000
2021County Y2000
+ + ); +}; + +export const SystemsInstructions: React.FC< + SystemsInstructionsTemplateParams +> = ({ system }) => { + const systemDetails = systemToDetails[system]; + return ( + <> +

+ {systemDetails.name} agencies are required to report the set of metrics + described on the{" "} + + Justice Counts website + + . +

+

+ For this example, consider the {systemDetails.metric} metric in + the {systemDetails.metric_category} section. +

+

+ To report data for this metric, add two sheets to your Excel workbook: + one called {systemDetails.metric_sheet_name} and one called{" "} + {systemDetails.metric_disaggregation_sheet_name}. +

+

+ In the {systemDetails.metric_sheet_name} sheet, we'll report + total values for each month: +

+ + + + + + {system === "SUPERVISION" ? : null} + + + + + + + + {system === "SUPERVISION" ? : null} + + + + + + {system === "SUPERVISION" ? : null} + + + {system === "SUPERVISION" ? ( + <> + + + + + + + + + + + + + + ) : null} + +
yearmonthsystemvalue
20217Parole5088
20218Parole5270
20217Probation2093
20218Probation2392
+ {system === "SUPERVISION" ? ( +

+ Note: If you are able to report separately for Parole and + Probation, then you should fill out rows for both systems. If you have + only aggregate data, leave the system column blank, or write + "Both". +

+ ) : null} +

+ In the {systemDetails.metric_disaggregation_sheet_name} sheet, + break down values by {systemDetails.metric_disaggregation}: +

+ + + + + + {system === "SUPERVISION" ? : null} + + + + + + {systemDetails.metric_disaggregation_values.map((obj) => { + return ( + + + + {system === "SUPERVISION" ? : null} + + + + ); + })} + {system === "SUPERVISION" + ? systemDetails.metric_disaggregation_values.map((obj) => { + return ( + + + + + + + + ); + }) + : null} + +
yearmonthsystem{systemDetails.metric_disaggregation_column_name}value
20217Parole{obj.name}{obj.value}
20217Probation{obj.name}...
+

+ Provide as many categories as you can, but feel free to skip the ones + that you don't have. +

+

+ To add data for another month, just add more rows. Note that the order + of the rows does not matter, though grouping rows from the same + month/year and arranging them in ascending or descending order is + preferable. +

+ + ); +}; diff --git a/publisher/src/components/DataUpload/SystemSelection.tsx b/publisher/src/components/DataUpload/SystemSelection.tsx new file mode 100644 index 000000000..550ad15e3 --- /dev/null +++ b/publisher/src/components/DataUpload/SystemSelection.tsx @@ -0,0 +1,66 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; + +import { AgencySystems } from "../../shared/types"; +import { removeSnakeCase } from "../../utils"; +import { ReactComponent as CheckIcon } from "../assets/check-icon.svg"; +import { + FileName, + SelectSystemOptions, + SystemName, + UserPromptContainer, + UserPromptTitle, + UserPromptWrapper, +} from "."; + +type SystemSelectionProps = { + selectedFile: File; + userSystems: AgencySystems[]; + handleSystemSelection: (file: File, system: AgencySystems) => void; +}; + +export const SystemSelection: React.FC = ({ + selectedFile, + userSystems, + handleSystemSelection, +}) => { + return ( + + + + + {selectedFile.name} + + Which system is this data for? + + + {userSystems.map((system) => ( + handleSystemSelection(selectedFile, system)} + > + {removeSnakeCase(system)} + + + ))} + + + + ); +}; diff --git a/publisher/src/components/DataUpload/UploadFile.tsx b/publisher/src/components/DataUpload/UploadFile.tsx new file mode 100644 index 000000000..ba2c67a54 --- /dev/null +++ b/publisher/src/components/DataUpload/UploadFile.tsx @@ -0,0 +1,165 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { Fragment, useEffect, useRef, useState } from "react"; + +import { AgencySystems } from "../../shared/types"; +import { removeSnakeCase } from "../../utils"; +import { ReactComponent as FileIcon } from "../assets/file-icon.svg"; +import { showToast } from "../Toast"; +import { + DragDropContainer, + GeneralInstructions, + Instructions, + SystemsInstructions, + UploadButtonInput, + UploadButtonLabel, + UploadFileContainer, +} from "."; + +type UploadFileProps = { + userSystems: AgencySystems[]; + setIsLoading: React.Dispatch>; + setSelectedFile: React.Dispatch>; + handleFileUpload: (file: File, system: AgencySystems) => Promise; +}; + +export const UploadFile: React.FC = ({ + userSystems, + setIsLoading, + setSelectedFile, + handleFileUpload, +}) => { + const dragDropAreaRef = useRef(null); + const [dragging, setDragging] = useState(false); + const acceptableFileTypes = [ + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "application/vnd.ms-excel", + ]; + + const handleFileUploadAttempt = ( + e: React.ChangeEvent | DragEvent + ) => { + const files = "dataTransfer" in e ? e.dataTransfer?.files : e.target.files; + + if (!files) return; + if (!acceptableFileTypes.includes(files[0].type)) { + return showToast( + "Invalid file type. Please only upload Excel files.", + false, + "red", + 3000 + ); + } + + setIsLoading(true); + if (userSystems.length > 1) { + setIsLoading(false); + setSelectedFile(files[0]); + } else { + handleFileUpload(files[0], userSystems[0]); + } + }; + + useEffect( + () => { + const dragDropArea = dragDropAreaRef.current; + + const handleDragOver = (e: DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + if (!dragging) setDragging(true); + }; + + const handleDragLeave = (e: DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setDragging(false); + }; + + const handleDrop = (e: DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setDragging(false); + + if (e.dataTransfer?.files.length) { + handleFileUploadAttempt(e); + } + }; + + if (dragDropArea) { + dragDropArea.addEventListener("dragover", handleDragOver); + dragDropArea.addEventListener("dragleave", handleDragLeave); + dragDropArea.addEventListener("drop", handleDrop); + } + + return () => { + if (dragDropArea) { + dragDropArea.removeEventListener("dragover", handleDragOver); + dragDropArea.removeEventListener("dragleave", handleDragLeave); + dragDropArea.removeEventListener("drop", handleDrop); + } + }; + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + return ( + + + {/* General Instructions */} + + + {/* System Specific Instructions */} + {userSystems?.map((system) => { + const systemName = removeSnakeCase(system).toLowerCase(); + const systemTemplate = ; + + return ( + +

{systemName}

+ {systemTemplate} +
+ ); + })} +
+ + + + + Drag & drop a file or{" "} + + { + /** reset event state to allow user to re-upload same file (re-trigger the onChange event) */ + e.currentTarget.value = ""; + }} + /> + browse your computer + + + Accepted file types: .xls, .xlsx + +
+ ); +}; diff --git a/publisher/src/components/DataUpload/UploadedFiles.tsx b/publisher/src/components/DataUpload/UploadedFiles.tsx new file mode 100644 index 000000000..f275201c4 --- /dev/null +++ b/publisher/src/components/DataUpload/UploadedFiles.tsx @@ -0,0 +1,338 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { observer } from "mobx-react-lite"; +import React, { useState } from "react"; + +import { Permission } from "../../shared/types"; +import { useStore } from "../../stores"; +import { removeSnakeCase } from "../../utils"; +import downloadIcon from "../assets/download-icon.png"; +import { Badge, BadgeColorMapping, BadgeColors } from "../Badge"; +import { Loading } from "../Loading"; +import { showToast } from "../Toast"; +import { + ActionButton, + ActionsContainer, + DownloadIcon, + ExtendedCell, + ExtendedLabelCell, + ExtendedLabelRow, + ExtendedRow, + ModalErrorWrapper, + ModalLoadingWrapper, + UploadedFile, + UploadedFileAttempt, + UploadedFilesContainer, + UploadedFilesTable, + UploadedFileStatus, +} from "."; + +export const UploadedFileRow: React.FC<{ + fileRowDetails: { + key: string; + id?: number; + selected: boolean; + name: string; + badgeColor: BadgeColors; + badgeText: string; + dateUploaded: string; + dateIngested: string; + system?: string; + uploadedBy: string; + }; + deleteUploadedFile: (spreadsheetID: number) => void; + updateUploadedFileStatus: ( + spreadsheetID: number, + status: UploadedFileStatus + ) => Promise; +}> = observer( + ({ fileRowDetails, deleteUploadedFile, updateUploadedFileStatus }) => { + const { reportStore, userStore } = useStore(); + const [isDownloading, setIsDownloading] = useState(false); + const [rowHovered, setRowHovered] = useState(false); + + const handleDownload = async (spreadsheetID: number, name: string) => { + setIsDownloading(true); + + const response = await reportStore.fetchSpreadsheetBlob(spreadsheetID); + + if (response instanceof Error) { + setIsDownloading(false); + return showToast("Failed to download. Please try again.", false, "red"); + } + + const data = await response?.blob(); + + if (data) { + const blob = new Blob([data], { + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;", + }); + + const link = document.createElement("a"); + const url = window.URL.createObjectURL(blob); + link.href = url; + link.download = name; + link.click(); + + window.URL.revokeObjectURL(url); + link.remove(); + setIsDownloading(false); + } + }; + + const { + id, + selected, + name, + badgeColor, + badgeText, + dateUploaded, + dateIngested, + system, + uploadedBy, + } = fileRowDetails; + + return ( + id && handleDownload(id, name)} + onMouseOver={() => setRowHovered(true)} + onMouseLeave={() => setRowHovered(false)} + > + {/* Filename */} + + {rowHovered && id && } + {name} + + {isDownloading ? "Downloading" : badgeText} + + + + {/* Date Uploaded */} + + {dateUploaded} + + + {/* Date Ingested */} + + {dateIngested} + + + {/* System */} + + {system} + + + {rowHovered && id && ( + e.stopPropagation()}> + {userStore.permissions.includes(Permission.RECIDIVIZ_ADMIN) && ( + <> + {(badgeText === "processed" || badgeText === "error") && ( + updateUploadedFileStatus(id, "UPLOADED")} + > + Mark as Pending + + )} + {(badgeText === "pending" || badgeText === "error") && ( + updateUploadedFileStatus(id, "INGESTED")} + > + Mark as Processed + + )} + {badgeText !== "error" && ( + updateUploadedFileStatus(id, "ERRORED")} + > + Mark as Error + + )} + + )} + + deleteUploadedFile(id)}> + Delete + + + )} + {/* Uploaded By */} + {uploadedBy} + + ); + } +); + +export const UploadedFiles: React.FC<{ + isLoading: boolean; + fetchError: boolean; + uploadedFiles: (UploadedFile | UploadedFileAttempt)[]; + setUploadedFiles: React.Dispatch< + React.SetStateAction<(UploadedFileAttempt | UploadedFile)[]> + >; +}> = observer(({ isLoading, fetchError, uploadedFiles, setUploadedFiles }) => { + const { reportStore } = useStore(); + const dataUploadColumnTitles = [ + "Filename", + "Date Uploaded", + "Date Ingested", + "System", + "Uploaded By", + ]; + + const isUploadedFile = ( + file: UploadedFile | UploadedFileAttempt + ): file is UploadedFile => { + return (file as UploadedFile).id !== undefined; + }; + + const uploadStatusColorMapping: BadgeColorMapping = { + UPLOADED: "ORANGE", + INGESTED: "GREEN", + ERRORED: "RED", + }; + + const translateBackendFileStatus = (status: UploadedFileStatus): string => { + if (status === "UPLOADED") return "PENDING"; + if (status === "INGESTED") return "PROCESSED"; + if (status === "ERRORED") return "ERROR"; + return status; + }; + + const getFileRowDetails = (file: UploadedFile | UploadedFileAttempt) => { + const fileStatus = file.status && translateBackendFileStatus(file.status); + + if (isUploadedFile(file)) { + const formatDate = (timestamp: number) => + Intl.DateTimeFormat("en-US", { + day: "numeric", + month: "long", + year: "numeric", + }).format(timestamp); + + return { + key: `${file.name}-${file.id}`, + id: file.id, + selected: !file.status, + name: file.name, + badgeColor: file.status + ? uploadStatusColorMapping[file.status] + : "ORANGE", + badgeText: fileStatus?.toLowerCase() || "Uploading", + dateUploaded: formatDate(file.uploaded_at), + dateIngested: file.ingested_at ? formatDate(file.ingested_at) : "--", + system: removeSnakeCase(file.system).toLowerCase(), + uploadedBy: file.uploaded_by, + }; + } + return { + key: `${file.name}-${file.upload_attempt_timestamp}`, + selected: false, + name: file.name, + badgeColor: file.status + ? uploadStatusColorMapping[file.status] + : "ORANGE", + badgeText: fileStatus?.toLowerCase() || "Uploading", + dateUploaded: "--", + dateIngested: "--", + uploadedBy: "--", + }; + }; + + const deleteUploadedFile = async (spreadsheetID: number) => { + const response = await reportStore.deleteUploadedSpreadsheet(spreadsheetID); + + if (response instanceof Error) { + return showToast(response.message, false, "red"); + } + + return setUploadedFiles((prev) => { + const filteredFiles = prev.filter( + (file) => (file as UploadedFile).id !== spreadsheetID + ); + + return filteredFiles; + }); + }; + + const updateUploadedFileStatus = async ( + spreadsheetID: number, + status: UploadedFileStatus + ) => { + const response = await reportStore.updateFileStatus(spreadsheetID, status); + + if (response instanceof Error) { + return showToast(response.message, false, "red"); + } + + return setUploadedFiles((prev) => { + const updatedFilesList = prev.map((file) => { + if (isUploadedFile(file) && file.id === spreadsheetID) { + return { ...file, status }; + } + return file; + }); + + return updatedFilesList; + }); + }; + + if (isLoading) { + return ( + + + + ); + } + + if (fetchError) { + return ( + + Failed to retrieve uploaded files. Please refresh and try again. + + ); + } + + return ( + + + + {dataUploadColumnTitles.map((title) => ( + {title} + ))} + + + {uploadedFiles.map((fileDetails) => { + const fileRowDetails = getFileRowDetails(fileDetails); + + return ( + + ); + })} + + + ); +}); diff --git a/publisher/src/components/DataUpload/index.ts b/publisher/src/components/DataUpload/index.ts new file mode 100644 index 000000000..c2a39c23d --- /dev/null +++ b/publisher/src/components/DataUpload/index.ts @@ -0,0 +1,23 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./DataUpload"; +export * from "./DataUpload.styles"; +export * from "./InstructionsTemplate"; +export * from "./SystemSelection"; +export * from "./UploadedFiles"; +export * from "./UploadFile"; diff --git a/publisher/src/components/DataViz/BarChart.tsx b/publisher/src/components/DataViz/BarChart.tsx new file mode 100644 index 000000000..23bbcca3a --- /dev/null +++ b/publisher/src/components/DataViz/BarChart.tsx @@ -0,0 +1,238 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import { + Bar, + BarChart as BarChartComponent, + CartesianGrid, + ResponsiveContainer, + Tooltip as TooltipComponent, + XAxis, + YAxis, +} from "recharts"; +import styled from "styled-components/macro"; + +import { Datapoint } from "../../shared/types"; +import { rem } from "../../utils"; +import { palette } from "../GlobalStyles"; +import Tooltip from "./Tooltip"; +import { splitUtcString } from "./utils"; + +const MAX_BAR_SIZE = 150; + +const ChartContainer = styled.div` + display: flex; + flex-grow: 1; + justify-content: center; + align-items: center; +`; + +const NoReportedData = styled.div` + position: absolute; + background: white; + padding: 8px; + + &::after { + content: "No reported data for this metric."; + } +`; + +const tickStyle = { + fontSize: rem("12px"), + fontWeight: 600, + fill: palette.solid.darkgrey, +}; + +const abbreviateNumber = (num: number) => { + // abbreviates numbers into 1k, 2.5m, 5.5t, etc + const numLength = num.toString().length; + if (numLength >= 13) { + return `${parseFloat((num / 1000000000000).toFixed(1))}t`; + } + if (numLength >= 10) { + return `${parseFloat((num / 1000000000).toFixed(1))}b`; + } + if (numLength >= 7) { + return `${parseFloat((num / 1000000).toFixed(1))}m`; + } + if (numLength >= 4) { + return `${parseFloat((num / 1000).toFixed(1))}k`; + } + return num.toString(); +}; + +interface TickProps { + y: number; + payload: { + coordinate: number; + isShow: boolean; + offset: number; + tickCoord: number; + value: number; + }; +} + +interface CustomYAxisTickProps extends TickProps { + percentageView: boolean; +} + +const CustomYAxisTick = (props: CustomYAxisTickProps) => { + const { y, payload, percentageView } = props; + const str = percentageView + ? `${payload.value * 100}%` + : abbreviateNumber(payload.value); + const label = str.length > 7 ? str.substring(0, 5).concat("...") : str; + return ( + + + {label} + + + ); +}; + +const CustomCursor = (props: React.SVGProps) => { + const { x, y, width, height } = props; + return ( + + ); +}; + +const ResponsiveBarChart: React.FC<{ + data: Datapoint[]; + dimensionNames: string[]; + percentageView?: boolean; +}> = ({ data, dimensionNames, percentageView = false }) => { + const isAnnual = data[0]?.frequency === "ANNUAL"; + const renderBarDefinitions = () => { + // each Recharts Bar component defines a category type in the stacked bar chart + const barDefinitions = []; + dimensionNames.forEach((dimension, index) => { + barDefinitions.push( + + ); + }); + barDefinitions.push( + + ); + return barDefinitions; + }; + + return ( + + + + + + + + + + + { + if (data.length === 0) { + return ""; + } + const [, , month, year] = splitUtcString(value); + return isAnnual ? year : `${month} ${year}`; + }} + tickMargin={12} + /> + ( + + )} + tickLine={false} + tickCount={percentageView ? 5 : 12} + domain={percentageView ? ["dataMin", "dataMax"] : undefined} + axisLine={false} + /> + } + content={ + + } + /> + {renderBarDefinitions()} + + + {data.length === 0 && } + + ); +}; + +export default ResponsiveBarChart; diff --git a/publisher/src/components/DataViz/DatapointsView.styles.tsx b/publisher/src/components/DataViz/DatapointsView.styles.tsx new file mode 100644 index 000000000..8c3fd8d9c --- /dev/null +++ b/publisher/src/components/DataViz/DatapointsView.styles.tsx @@ -0,0 +1,203 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { + Dropdown, + DropdownMenu, + DropdownToggle, +} from "@recidiviz/design-system"; +import React from "react"; +import styled from "styled-components/macro"; + +import { palette, typography } from "../GlobalStyles"; +import { ExtendedDropdownMenuItem } from "../Menu/Menu.styles"; + +export const DatapointsViewContainer = styled.div` + display: flex; + flex-direction: column; + flex-grow: 1; + padding: 0 15px 0 15px; +`; + +export const DatapointsViewControlsContainer = styled.div` + display: flex; + flex-direction: row; + border-bottom: 1px solid ${palette.highlight.grey9}; +`; + +const DatapointsViewDropdown = styled(Dropdown)` + display: flex; + flex-grow: 1; + flex-basis: 0; + min-width: 0; + border-left: 1px solid ${palette.highlight.grey9}; + + & > button { + transition-duration: 0ms; + border-width: 0; + } + + &:first-child { + border-left: none; + } +`; + +const DatapointsViewDropdownToggleContainer = styled(DropdownToggle)` + font-family: ${typography.family}; + padding: 0; + min-height: unset; + line-height: 0; + position: relative; + flex-grow: 1; + flex-basis: 0; + color: ${palette.solid.darkgrey}; + text-align: start; + + &:hover { + color: ${palette.solid.blue}; + } +`; +const DatapointsViewDropdownToggleSelection = styled.div` + height: 64px; + padding: 32px 32px 0px 8px; + width: 100%; + ${typography.sizeCSS.large} + color: ${palette.solid.darkgrey}; + line-height: 1.6rem; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + + &:hover { + cursor: pointer; + background-color: ${palette.highlight.lightblue1}; + color: ${palette.solid.blue}; + } +`; +const DatapointsViewDropdownToggleTitle = styled.div` + padding: 8px 8px 0; + position: absolute; + ${typography.sizeCSS.small} + pointer-events: none; + top: 0; + left: 0; +`; + +const DatapointsViewDropdownToggleArrow = styled.div` + bottom: 0; + right: 0; + position: absolute; + font-size: 6px; + transform: rotate(45deg); + padding: 16px; + pointer-events: none; + + &::after { + content: "◢"; + } +`; + +interface DatapointsViewControlsDropdownMenuProps { + title: string; + selectedValue: string; +} + +const DatapointsViewControlsDropdownMenu: React.FC< + DatapointsViewControlsDropdownMenuProps +> = ({ title, selectedValue }) => ( + + + {title} + + + {selectedValue} + + + +); + +interface DatapointsViewControlsDropdownProps { + title: string; + selectedValue: string; + onSelect: (value: string) => void; + options: string[]; +} + +export const DatapointsViewControlsDropdown: React.FC< + DatapointsViewControlsDropdownProps +> = ({ title, selectedValue, onSelect, options }) => ( + + + + {options.map((value) => ( + { + onSelect(value); + }} + highlight={selectedValue === value} + > + {value} + + ))} + + +); + +export const MetricInsightsRow = styled.div` + display: flex; + flex-direction: row; + margin-top: 16px; + margin-bottom: 16px; +`; + +const MetricInsightContainer = styled.div` + margin-right: 32px; + + &:last-child { + margin-right: 0; + text-align: right; + margin-left: auto; + } +`; + +const MetricInsightTitle = styled.div` + ${typography.sizeCSS.small} + margin-bottom: 8px; +`; + +const MetricInsightValue = styled.div` + ${typography.sizeCSS.large} +`; + +interface MetricInsightProps { + title: string; + value: string; +} + +export const MetricInsight: React.FC = ({ + title, + value, +}) => ( + + {title} + {value} + +); diff --git a/publisher/src/components/DataViz/DatapointsView.tsx b/publisher/src/components/DataViz/DatapointsView.tsx new file mode 100644 index 000000000..d878a7456 --- /dev/null +++ b/publisher/src/components/DataViz/DatapointsView.tsx @@ -0,0 +1,198 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { observer } from "mobx-react-lite"; +import React, { useEffect } from "react"; + +import { + DatapointsGroupedByAggregateAndDisaggregations, + DatapointsViewSetting, + DataVizAggregateName, + DataVizTimeRangesMap, +} from "../../shared/types"; +import { useStore } from "../../stores"; +import BarChart from "./BarChart"; +import { + DatapointsViewContainer, + DatapointsViewControlsContainer, + DatapointsViewControlsDropdown, + MetricInsight, + MetricInsightsRow, +} from "./DatapointsView.styles"; +import Legend from "./Legend"; +import { + filterByTimeRange, + filterNullDatapoints, + getAverageTotalValue, + getLatestDateFormatted, + getPercentChangeOverTime, + sortDatapointDimensions, + transformData, +} from "./utils"; + +const noDisaggregationOption = "None"; + +const DatapointsView: React.FC<{ + metric: string; +}> = ({ metric }) => { + const { datapointsStore } = useStore(); + const [selectedTimeRange, setSelectedTimeRange] = + React.useState("All"); + const [selectedDisaggregation, setSelectedDisaggregation] = + React.useState(noDisaggregationOption); + const [datapointsViewSetting, setDatapointsViewSetting] = + React.useState("Count"); + + const datapointsForMetric = datapointsStore.datapointsByMetric[ + metric + ] as DatapointsGroupedByAggregateAndDisaggregations; + const data = + (selectedDisaggregation !== noDisaggregationOption && + Object.values( + datapointsForMetric.disaggregations[selectedDisaggregation] || {} + )) || + datapointsForMetric?.aggregate || + []; + const isAnnual = data[0]?.frequency === "ANNUAL"; + const disaggregationOptions = Object.keys( + datapointsStore.dimensionNamesByMetricAndDisaggregation[metric] || {} + ); + disaggregationOptions.unshift(noDisaggregationOption); + const dimensionNames = + selectedDisaggregation !== noDisaggregationOption + ? ( + datapointsStore.dimensionNamesByMetricAndDisaggregation[metric]?.[ + selectedDisaggregation + ] || [] + ) + .slice() // Must use slice() before sorting a MobX observableArray + .sort(sortDatapointDimensions) + : [DataVizAggregateName]; + + const selectedTimeRangeValue = DataVizTimeRangesMap[selectedTimeRange]; + + useEffect(() => { + if (isAnnual && selectedTimeRangeValue === 6) { + setSelectedTimeRange("All"); + } + if (!disaggregationOptions.includes(selectedDisaggregation)) { + setSelectedDisaggregation(noDisaggregationOption); + setDatapointsViewSetting("Count"); + } + if (selectedDisaggregation === noDisaggregationOption) { + setDatapointsViewSetting("Count"); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [metric]); + + const renderChartForMetric = () => { + return ( + + ); + }; + + const renderLegend = () => { + if (selectedDisaggregation !== noDisaggregationOption) { + return ; + } + return ; + }; + + const renderDataVizControls = () => { + return ( + + key !== "6 Months Ago" + ) + : Object.keys(DataVizTimeRangesMap) + } + onSelect={(key) => { + setSelectedTimeRange(key); + }} + /> + {disaggregationOptions.length > 1 && ( + { + setSelectedDisaggregation(key); + }} + /> + )} + {selectedDisaggregation !== noDisaggregationOption && ( + { + setDatapointsViewSetting(key as DatapointsViewSetting); + }} + /> + )} + + ); + }; + + const renderMetricInsightsRow = () => { + const dataSelectedInTimeRange = filterNullDatapoints( + filterByTimeRange( + datapointsForMetric?.aggregate || [], + selectedTimeRangeValue + ) + ); + const percentChange = getPercentChangeOverTime(dataSelectedInTimeRange); + const avgValue = getAverageTotalValue(dataSelectedInTimeRange, isAnnual); + + return ( + + + + + + ); + }; + + return ( + + {renderDataVizControls()} + {renderMetricInsightsRow()} + {renderChartForMetric()} + {renderLegend()} + + ); +}; + +export default observer(DatapointsView); diff --git a/publisher/src/components/DataViz/Legend.tsx b/publisher/src/components/DataViz/Legend.tsx new file mode 100644 index 000000000..0fa7b4f11 --- /dev/null +++ b/publisher/src/components/DataViz/Legend.tsx @@ -0,0 +1,78 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import styled from "styled-components/macro"; + +import { palette } from "../GlobalStyles"; + +const EmptyLegendContainer = styled.div` + display: flex; + flex-direction: row; + align-items: center; + flex-wrap: wrap; + margin-bottom: 20px; + height: 50px; +`; + +const LegendContainer = styled(EmptyLegendContainer)` + border-top: 1px solid rgba(23, 28, 43, 0.6); + padding: 16px 0; + border-bottom: 1px solid rgba(23, 28, 43, 0.6); +`; + +const LegendItem = styled.div` + display: flex; + margin-right: 8px; + flex-direction: row; + align-items: center; +`; + +export const LegendColor = styled.div<{ + index: number; +}>` + width: 8px; + height: 8px; + margin-right: 4px; + background: ${({ index }) => Object.values(palette.dataViz)[index]}; + border-radius: 10px; +`; + +const LegendText = styled.div` + font-size: 12px; +`; + +const Legend: React.FC<{ + names?: string[]; +}> = ({ names }) => { + if (names) { + return ( + + {names.map((name, idx) => ( + + + {name} + + ))} + + ); + } + + return ; +}; + +export default Legend; diff --git a/publisher/src/components/DataViz/Tooltip.tsx b/publisher/src/components/DataViz/Tooltip.tsx new file mode 100644 index 000000000..08a8d4b31 --- /dev/null +++ b/publisher/src/components/DataViz/Tooltip.tsx @@ -0,0 +1,138 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import { TooltipProps as RechartsTooltipProps } from "recharts"; +import styled from "styled-components/macro"; + +import { Datapoint } from "../../shared/types"; +import { formatNumberInput } from "../../utils"; +import { palette, typography } from "../GlobalStyles"; +import { LegendColor } from "./Legend"; +import { getSumOfDimensionValues, splitUtcString } from "./utils"; + +const TooltipContainer = styled.div` + padding: 16px; + border-radius: 4px; + background: ${palette.solid.darkgrey}; +`; + +const TooltipItemContainer = styled.div` + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; +`; + +const TooltipName = styled.div` + ${typography.sizeCSS.normal} + flex-grow: 1; + color: ${palette.solid.white}; +`; + +const TooltipValue = styled(TooltipName)` + flex-grow: 0; + margin-left: 32px; +`; + +const TooltipNameWithBottomMargin = styled(TooltipName)` + margin-bottom: 16px; +`; + +interface TooltipProps extends RechartsTooltipProps { + percentOnly: boolean; + isAnnual: boolean; + dimensionNames: string[]; +} + +const Tooltip: React.FC = ({ + active, + payload, + label, + percentOnly, + isAnnual, + dimensionNames, +}) => { + if (active && payload && payload.length) { + const [, , month, year] = label ? splitUtcString(label) : []; + + const renderText = (val: string | number | null, maxValue: number) => { + if (typeof val !== "number") { + return "Not Reported"; + } + + let percentText = `${ + val !== 0 ? Math.round((val / maxValue) * 100) : 0 + }%`; + // handle case of non-zero being rounded down to 0% + if (percentText === "0%" && val !== 0) { + percentText = "<1%"; + } + return percentOnly + ? percentText + : `${formatNumberInput(val.toString())}${ + payload.length > 2 ? ` (${percentText})` : "" + }`; + }; + + const renderItems = () => { + if (payload.length === 0) { + return null; + } + + const datapoint = payload[0].payload as Datapoint; + if (datapoint.dataVizMissingData !== 0) { + return ( + + Not reported + + ); + } + + const sumOfDimensions = getSumOfDimensionValues(datapoint); + + return dimensionNames.map((dimension, idx: number) => { + if (dimension === "dataVizMissingData") { + return null; + } + + return ( + + + {dimension} + + {renderText(datapoint[dimension], sumOfDimensions)} + + + ); + }); + }; + + return ( + + + {isAnnual ? year : `${month} ${year}`} + + {renderItems()} + + ); + } + + return null; +}; + +export default Tooltip; diff --git a/publisher/src/components/DataViz/utils.test.ts b/publisher/src/components/DataViz/utils.test.ts new file mode 100644 index 000000000..38481aa17 --- /dev/null +++ b/publisher/src/components/DataViz/utils.test.ts @@ -0,0 +1,2066 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { Datapoint } from "../../shared/types"; +import { + fillTimeGapsBetweenDatapoints, + filterByTimeRange, + filterNullDatapoints, + incrementMonth, + incrementYear, + transformData, + transformToRelativePerchanges, +} from "./utils"; + +const testDatapoints: Datapoint[] = [ + { + start_date: "Wed, 01 Jan 2020 00:00:00 GMT", + end_date: "Sat, 01 Feb 2020 00:00:00 GMT", + Pretrial: 50515, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 45427, + "Transfer or Hold": 31375, + Unknown: 29749, + }, + { + start_date: "Sat, 01 Feb 2020 00:00:00 GMT", + end_date: "Sun, 01 Mar 2020 00:00:00 GMT", + Pretrial: 54758, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 65594, + "Transfer or Hold": 89614, + Unknown: 73426, + }, + { + start_date: "Sun, 01 Mar 2020 00:00:00 GMT", + end_date: "Wed, 01 Apr 2020 00:00:00 GMT", + Pretrial: 52304, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 94209, + "Transfer or Hold": 82736, + Unknown: 62748, + }, + { + start_date: "Wed, 01 Apr 2020 00:00:00 GMT", + end_date: "Fri, 01 May 2020 00:00:00 GMT", + Pretrial: 23335, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 90737, + "Transfer or Hold": 57573, + Unknown: 93184, + }, + { + start_date: "Fri, 01 May 2020 00:00:00 GMT", + end_date: "Mon, 01 Jun 2020 00:00:00 GMT", + Pretrial: 39489, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 27098, + "Transfer or Hold": 41196, + Unknown: 28077, + }, + { + start_date: "Mon, 01 Jun 2020 00:00:00 GMT", + end_date: "Wed, 01 Jul 2020 00:00:00 GMT", + Pretrial: 66362, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 44360, + "Transfer or Hold": 61195, + Unknown: 31909, + }, + { + start_date: "Wed, 01 Jul 2020 00:00:00 GMT", + end_date: "Sat, 01 Aug 2020 00:00:00 GMT", + Pretrial: 69380, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 53465, + "Transfer or Hold": 94375, + Unknown: 13442, + }, + { + start_date: "Sat, 01 Aug 2020 00:00:00 GMT", + end_date: "Tue, 01 Sep 2020 00:00:00 GMT", + Pretrial: 30380, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 82698, + "Transfer or Hold": 41340, + Unknown: 40324, + }, + { + start_date: "Tue, 01 Sep 2020 00:00:00 GMT", + end_date: "Thu, 01 Oct 2020 00:00:00 GMT", + Pretrial: 30338, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 74647, + "Transfer or Hold": 85087, + Unknown: 28198, + }, + { + start_date: "Thu, 01 Oct 2020 00:00:00 GMT", + end_date: "Sun, 01 Nov 2020 00:00:00 GMT", + Pretrial: 35571, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 23313, + "Transfer or Hold": 41785, + Unknown: 63556, + }, + { + start_date: "Sun, 01 Nov 2020 00:00:00 GMT", + end_date: "Tue, 01 Dec 2020 00:00:00 GMT", + Pretrial: 65779, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 53664, + "Transfer or Hold": 65962, + Unknown: 59783, + }, + { + start_date: "Tue, 01 Dec 2020 00:00:00 GMT", + end_date: "Fri, 01 Jan 2021 00:00:00 GMT", + Pretrial: 46192, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 49529, + "Transfer or Hold": 78956, + Unknown: 12664, + }, + { + start_date: "Fri, 01 Jan 2021 00:00:00 GMT", + end_date: "Mon, 01 Feb 2021 00:00:00 GMT", + Pretrial: 34311, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 24082, + "Transfer or Hold": 70165, + Unknown: 13003, + }, + { + start_date: "Mon, 01 Feb 2021 00:00:00 GMT", + end_date: "Mon, 01 Mar 2021 00:00:00 GMT", + Pretrial: 94307, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 67799, + "Transfer or Hold": 80348, + Unknown: 24894, + }, + { + start_date: "Mon, 01 Mar 2021 00:00:00 GMT", + end_date: "Thu, 01 Apr 2021 00:00:00 GMT", + Pretrial: 55116, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 65802, + "Transfer or Hold": 46493, + Unknown: 47052, + }, + { + start_date: "Thu, 01 Apr 2021 00:00:00 GMT", + end_date: "Sat, 01 May 2021 00:00:00 GMT", + Pretrial: 60342, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 27224, + "Transfer or Hold": 14822, + Unknown: 35285, + }, + { + start_date: "Sat, 01 May 2021 00:00:00 GMT", + end_date: "Tue, 01 Jun 2021 00:00:00 GMT", + Pretrial: 76072, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 40997, + "Transfer or Hold": 84448, + Unknown: 86808, + }, + { + start_date: "Tue, 01 Jun 2021 00:00:00 GMT", + end_date: "Thu, 01 Jul 2021 00:00:00 GMT", + Pretrial: 55707, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 21701, + "Transfer or Hold": 97274, + Unknown: 70005, + }, + { + start_date: "Thu, 01 Jul 2021 00:00:00 GMT", + end_date: "Sun, 01 Aug 2021 00:00:00 GMT", + "Transfer or Hold": 92055, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 64106, + Pretrial: 19694, + Unknown: 51952, + }, + { + start_date: "Sun, 01 Aug 2021 00:00:00 GMT", + end_date: "Wed, 01 Sep 2021 00:00:00 GMT", + Pretrial: 19163, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 95457, + "Transfer or Hold": 50399, + Unknown: 37598, + }, + { + start_date: "Wed, 01 Sep 2021 00:00:00 GMT", + end_date: "Fri, 01 Oct 2021 00:00:00 GMT", + Pretrial: 56132, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 49555, + "Transfer or Hold": 67307, + Unknown: 16254, + }, + { + start_date: "Fri, 01 Oct 2021 00:00:00 GMT", + end_date: "Mon, 01 Nov 2021 00:00:00 GMT", + Pretrial: 74036, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 53503, + "Transfer or Hold": 29868, + Unknown: 94671, + }, + { + start_date: "Mon, 01 Nov 2021 00:00:00 GMT", + end_date: "Wed, 01 Dec 2021 00:00:00 GMT", + Sentenced: 34289, + frequency: "MONTHLY", + dataVizMissingData: 0, + Pretrial: 30696, + "Transfer or Hold": 56361, + Unknown: 18829, + }, + { + start_date: "Wed, 01 Dec 2021 00:00:00 GMT", + end_date: "Sat, 01 Jan 2022 00:00:00 GMT", + Pretrial: 21968, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 47320, + "Transfer or Hold": 43536, + Unknown: 71164, + }, + { + start_date: "Sat, 01 Jan 2022 00:00:00 GMT", + end_date: "Tue, 01 Feb 2022 00:00:00 GMT", + Pretrial: 38210, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 70537, + "Transfer or Hold": 87658, + Unknown: 84018, + }, + { + start_date: "Tue, 01 Feb 2022 00:00:00 GMT", + end_date: "Tue, 01 Mar 2022 00:00:00 GMT", + Pretrial: 37196, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 34013, + "Transfer or Hold": 35342, + Unknown: 16376, + }, + { + start_date: "Tue, 01 Mar 2022 00:00:00 GMT", + end_date: "Fri, 01 Apr 2022 00:00:00 GMT", + Pretrial: 13935, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 28989, + "Transfer or Hold": 56841, + Unknown: 52659, + }, + { + start_date: "Fri, 01 Apr 2022 00:00:00 GMT", + end_date: "Sun, 01 May 2022 00:00:00 GMT", + Pretrial: 54440, + frequency: "MONTHLY", + dataVizMissingData: 0, + Unknown: 55161, + "Transfer or Hold": 17782, + Sentenced: 90906, + }, + { + start_date: "Sun, 01 May 2022 00:00:00 GMT", + end_date: "Wed, 01 Jun 2022 00:00:00 GMT", + Pretrial: 49829, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 85046, + "Transfer or Hold": 60630, + Unknown: 10732, + }, + { + start_date: "Wed, 01 Jun 2022 00:00:00 GMT", + end_date: "Fri, 01 Jul 2022 00:00:00 GMT", + Pretrial: 15321, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 68658, + "Transfer or Hold": 73603, + Unknown: 72871, + }, + { + start_date: "Fri, 01 Jul 2022 00:00:00 GMT", + end_date: "Mon, 01 Aug 2022 00:00:00 GMT", + Pretrial: 61998, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 29566, + "Transfer or Hold": 98614, + Unknown: 63892, + }, + { + start_date: "Mon, 01 Aug 2022 00:00:00 GMT", + end_date: "Thu, 01 Sep 2022 00:00:00 GMT", + Pretrial: 49052, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 19779, + "Transfer or Hold": 38057, + Unknown: 49554, + }, + { + start_date: "Thu, 01 Sep 2022 00:00:00 GMT", + end_date: "Sat, 01 Oct 2022 00:00:00 GMT", + Sentenced: 52422, + frequency: "MONTHLY", + dataVizMissingData: 0, + Pretrial: 34244, + "Transfer or Hold": 62878, + Unknown: 48777, + }, + { + start_date: "Sat, 01 Oct 2022 00:00:00 GMT", + end_date: "Tue, 01 Nov 2022 00:00:00 GMT", + Pretrial: 67196, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 54738, + "Transfer or Hold": 95846, + Unknown: 94767, + }, + { + start_date: "Tue, 01 Nov 2022 00:00:00 GMT", + end_date: "Thu, 01 Dec 2022 00:00:00 GMT", + Pretrial: 76254, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 63070, + "Transfer or Hold": 25465, + Unknown: 81989, + }, + { + start_date: "Thu, 01 Dec 2022 00:00:00 GMT", + end_date: "Sun, 01 Jan 2023 00:00:00 GMT", + Unknown: 29537, + frequency: "MONTHLY", + dataVizMissingData: 0, + "Transfer or Hold": 52722, + Sentenced: 84901, + Pretrial: 34694, + }, +]; + +const testDatapoints2: Datapoint[] = [ + { + start_date: "Tue, 01 Mar 2022 00:00:00 GMT", + end_date: "Fri, 01 Apr 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 97164, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 36671, + Black: 26028, + "External / Unknown": 47948, + Hispanic: 57558, + "Native Hawaiian / Pacific Islander": 90632, + Other: 16338, + White: 22298, + }, + { + start_date: "Fri, 01 Apr 2022 00:00:00 GMT", + end_date: "Sun, 01 May 2022 00:00:00 GMT", + Hispanic: 66829, + frequency: "MONTHLY", + dataVizMissingData: 0, + "External / Unknown": 97373, + Black: 20261, + Asian: 63835, + "American Indian / Alaskan Native": 31596, + "Native Hawaiian / Pacific Islander": 82033, + Other: 29044, + White: 96511, + }, + { + start_date: "Sun, 01 May 2022 00:00:00 GMT", + end_date: "Wed, 01 Jun 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 79637, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 14139, + Black: 85121, + "External / Unknown": 38446, + Hispanic: 31772, + "Native Hawaiian / Pacific Islander": 88002, + Other: 33259, + White: 70561, + }, + { + start_date: "Wed, 01 Jun 2022 00:00:00 GMT", + end_date: "Fri, 01 Jul 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 45039, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 65632, + Black: 39540, + "External / Unknown": 16119, + Hispanic: 14102, + "Native Hawaiian / Pacific Islander": 52909, + Other: 60103, + White: 73688, + }, + { + start_date: "Fri, 01 Jul 2022 00:00:00 GMT", + end_date: "Mon, 01 Aug 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 80150, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 74203, + Black: 23688, + "External / Unknown": 44627, + Hispanic: 65335, + "Native Hawaiian / Pacific Islander": 56843, + Other: 58110, + White: 62313, + }, + { + start_date: "Mon, 01 Aug 2022 00:00:00 GMT", + end_date: "Thu, 01 Sep 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 21221, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 36873, + Black: 30958, + "External / Unknown": 40857, + Hispanic: 85505, + "Native Hawaiian / Pacific Islander": 66954, + Other: 93569, + White: 52647, + }, + { + start_date: "Thu, 01 Sep 2022 00:00:00 GMT", + end_date: "Sat, 01 Oct 2022 00:00:00 GMT", + Other: 69493, + frequency: "MONTHLY", + dataVizMissingData: 0, + White: 37434, + "Native Hawaiian / Pacific Islander": 87941, + "American Indian / Alaskan Native": 55887, + Asian: 69104, + Black: 73150, + "External / Unknown": 64346, + Hispanic: 33261, + }, + { + start_date: "Sat, 01 Oct 2022 00:00:00 GMT", + end_date: "Tue, 01 Nov 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 69650, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 24615, + Black: 55423, + "External / Unknown": 98968, + Hispanic: 68576, + "Native Hawaiian / Pacific Islander": 94690, + Other: 64054, + White: 81617, + }, + { + start_date: "Tue, 01 Nov 2022 00:00:00 GMT", + end_date: "Thu, 01 Dec 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 17038, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 44387, + Black: 51777, + "External / Unknown": 54533, + Hispanic: 16689, + "Native Hawaiian / Pacific Islander": 69182, + Other: 99842, + White: 29578, + }, + { + start_date: "Thu, 01 Dec 2022 00:00:00 GMT", + end_date: "Sun, 01 Jan 2023 00:00:00 GMT", + "Native Hawaiian / Pacific Islander": 89112, + frequency: "MONTHLY", + dataVizMissingData: 0, + Other: 37341, + White: 59971, + "American Indian / Alaskan Native": 18236, + Asian: 60388, + Black: 35380, + "External / Unknown": 36941, + Hispanic: 90445, + }, +]; + +const testDatapoints2Percentages: Datapoint[] = [ + { + start_date: "Tue, 01 Mar 2022 00:00:00 GMT", + end_date: "Fri, 01 Apr 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 0.24621107498790026, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 0.09292337008440668, + Black: 0.06595428203640308, + "External / Unknown": 0.12149899781318022, + Hispanic: 0.145850490450718, + "Native Hawaiian / Pacific Islander": 0.22965915512230226, + Other: 0.04140007145807413, + White: 0.05650255804701536, + }, + { + start_date: "Fri, 01 Apr 2022 00:00:00 GMT", + end_date: "Sun, 01 May 2022 00:00:00 GMT", + Hispanic: 0.13709018999675884, + frequency: "MONTHLY", + dataVizMissingData: 0, + "External / Unknown": 0.1997468624482545, + Black: 0.04156256025863519, + Asian: 0.1309484247623502, + "American Indian / Alaskan Native": 0.06481470085049294, + "Native Hawaiian / Pacific Islander": 0.16827903389253346, + Other: 0.059579635760910146, + White: 0.1979785920300647, + }, + { + start_date: "Sun, 01 May 2022 00:00:00 GMT", + end_date: "Wed, 01 Jun 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 0.18060856766386127, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 0.03206580531912722, + Black: 0.19304571854936192, + "External / Unknown": 0.08719159426403318, + Hispanic: 0.07205564513751397, + "Native Hawaiian / Pacific Islander": 0.19957953176984466, + Other: 0.07542800898994641, + White: 0.16002512830631133, + }, + { + start_date: "Wed, 01 Jun 2022 00:00:00 GMT", + end_date: "Fri, 01 Jul 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 0.1226779468964841, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 0.1787694889031738, + Black: 0.10769968294782258, + "External / Unknown": 0.04390518941416166, + Hispanic: 0.0384112526284824, + "Native Hawaiian / Pacific Islander": 0.1441143784796749, + Other: 0.16370951047579618, + White: 0.2007125502544044, + }, + { + start_date: "Fri, 01 Jul 2022 00:00:00 GMT", + end_date: "Mon, 01 Aug 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 0.17226593647975688, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 0.1594840834012152, + Black: 0.0509124828862443, + "External / Unknown": 0.09591655579890343, + Hispanic: 0.14042414173306195, + "Native Hawaiian / Pacific Islander": 0.12217233471389669, + Other: 0.12489549056567276, + White: 0.1339289744212488, + }, + { + start_date: "Mon, 01 Aug 2022 00:00:00 GMT", + end_date: "Thu, 01 Sep 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 0.04951421424971534, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 0.08603447632202789, + Black: 0.0722332144923749, + "External / Unknown": 0.09533020364735968, + Hispanic: 0.1995058144961081, + "Native Hawaiian / Pacific Islander": 0.15622141750508653, + Other: 0.21832126257629778, + White: 0.12283939671102981, + }, + { + start_date: "Thu, 01 Sep 2022 00:00:00 GMT", + end_date: "Sat, 01 Oct 2022 00:00:00 GMT", + Other: 0.14164438175681185, + frequency: "MONTHLY", + dataVizMissingData: 0, + White: 0.07629999836939684, + "Native Hawaiian / Pacific Islander": 0.17924609062892363, + "American Indian / Alaskan Native": 0.11391189851125931, + Asian: 0.14085150097020888, + Black: 0.14909827645245977, + "External / Unknown": 0.13115348867546106, + Hispanic: 0.06779436463547867, + }, + { + start_date: "Sat, 01 Oct 2022 00:00:00 GMT", + end_date: "Tue, 01 Nov 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 0.12491189810489013, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 0.04414510225200101, + Black: 0.09939687191195011, + "External / Unknown": 0.1774914677910232, + Hispanic: 0.12298576201638112, + "Native Hawaiian / Pacific Islander": 0.16981920504740913, + Other: 0.11487590410926966, + White: 0.14637378876707563, + }, + { + start_date: "Tue, 01 Nov 2022 00:00:00 GMT", + end_date: "Thu, 01 Dec 2022 00:00:00 GMT", + "American Indian / Alaskan Native": 0.044482619978800396, + frequency: "MONTHLY", + dataVizMissingData: 0, + Asian: 0.11588508351913447, + Black: 0.13517881292653763, + "External / Unknown": 0.14237414692475184, + Hispanic: 0.04357145467931681, + "Native Hawaiian / Pacific Islander": 0.18061959240364883, + Other: 0.2606663777393702, + White: 0.07722191182843985, + }, + { + start_date: "Thu, 01 Dec 2022 00:00:00 GMT", + end_date: "Sun, 01 Jan 2023 00:00:00 GMT", + "Native Hawaiian / Pacific Islander": 0.20829612869144068, + frequency: "MONTHLY", + dataVizMissingData: 0, + Other: 0.08728325861238763, + White: 0.14018007825830853, + "American Indian / Alaskan Native": 0.04262600101913448, + Asian: 0.14115480091815602, + Black: 0.08269949090025104, + "External / Unknown": 0.0863482728475459, + Hispanic: 0.21141196875277574, + }, +]; + +const testDatapoints3: Datapoint[] = [ + { + Total: 28293, + start_date: "Tue, 01 Mar 2022 00:00:00 GMT", + end_date: "Fri, 01 Apr 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 56673, + start_date: "Fri, 01 Apr 2022 00:00:00 GMT", + end_date: "Sun, 01 May 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 59646, + start_date: "Sun, 01 May 2022 00:00:00 GMT", + end_date: "Wed, 01 Jun 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 95570, + start_date: "Wed, 01 Jun 2022 00:00:00 GMT", + end_date: "Fri, 01 Jul 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 23877, + start_date: "Fri, 01 Jul 2022 00:00:00 GMT", + end_date: "Mon, 01 Aug 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 42551, + start_date: "Mon, 01 Aug 2022 00:00:00 GMT", + end_date: "Thu, 01 Sep 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 77484, + start_date: "Thu, 01 Sep 2022 00:00:00 GMT", + end_date: "Sat, 01 Oct 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: null, + start_date: "Sat, 01 Oct 2022 00:00:00 GMT", + end_date: "Tue, 01 Nov 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 12312, + start_date: "Tue, 01 Nov 2022 00:00:00 GMT", + end_date: "Thu, 01 Dec 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 0, + start_date: "Thu, 01 Dec 2022 00:00:00 GMT", + end_date: "Sun, 01 Jan 2023 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, +]; + +const testDatapoints3WithoutNullDatapoints: Datapoint[] = [ + { + Total: 28293, + start_date: "Tue, 01 Mar 2022 00:00:00 GMT", + end_date: "Fri, 01 Apr 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 56673, + start_date: "Fri, 01 Apr 2022 00:00:00 GMT", + end_date: "Sun, 01 May 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 59646, + start_date: "Sun, 01 May 2022 00:00:00 GMT", + end_date: "Wed, 01 Jun 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 95570, + start_date: "Wed, 01 Jun 2022 00:00:00 GMT", + end_date: "Fri, 01 Jul 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 23877, + start_date: "Fri, 01 Jul 2022 00:00:00 GMT", + end_date: "Mon, 01 Aug 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 42551, + start_date: "Mon, 01 Aug 2022 00:00:00 GMT", + end_date: "Thu, 01 Sep 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 77484, + start_date: "Thu, 01 Sep 2022 00:00:00 GMT", + end_date: "Sat, 01 Oct 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 12312, + start_date: "Tue, 01 Nov 2022 00:00:00 GMT", + end_date: "Thu, 01 Dec 2022 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, + { + Total: 0, + start_date: "Thu, 01 Dec 2022 00:00:00 GMT", + end_date: "Sun, 01 Jan 2023 00:00:00 GMT", + frequency: "MONTHLY", + dataVizMissingData: 0, + }, +]; + +const testDatapoints4: Datapoint[] = [ + { + Total: 52342, + start_date: "Thu, 01 Jan 2015 00:00:00 GMT", + end_date: "Fri, 01 Jan 2016 00:00:00 GMT", + frequency: "ANNUAL", + dataVizMissingData: 0, + }, + { + Total: 41241, + start_date: "Tue, 01 Jan 2019 00:00:00 GMT", + end_date: "Wed, 01 Jan 2020 00:00:00 GMT", + frequency: "ANNUAL", + dataVizMissingData: 0, + }, + { + Total: 74435, + start_date: "Sat, 01 Jan 2022 00:00:00 GMT", + end_date: "Sun, 01 Jan 2023 00:00:00 GMT", + frequency: "ANNUAL", + dataVizMissingData: 0, + }, +]; + +const testDatapoints4WithGapDatapoints: Datapoint[] = [ + { + Total: 52342, + start_date: "Thu, 01 Jan 2015 00:00:00 GMT", + end_date: "Fri, 01 Jan 2016 00:00:00 GMT", + frequency: "ANNUAL", + dataVizMissingData: 0, + }, + { + start_date: "Fri, 01 Jan 2016 00:00:00 GMT", + end_date: "Sun, 01 Jan 2017 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + start_date: "Sun, 01 Jan 2017 00:00:00 GMT", + end_date: "Mon, 01 Jan 2018 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + start_date: "Mon, 01 Jan 2018 00:00:00 GMT", + end_date: "Tue, 01 Jan 2019 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + Total: 41241, + start_date: "Tue, 01 Jan 2019 00:00:00 GMT", + end_date: "Wed, 01 Jan 2020 00:00:00 GMT", + frequency: "ANNUAL", + dataVizMissingData: 0, + }, + { + start_date: "Wed, 01 Jan 2020 00:00:00 GMT", + end_date: "Fri, 01 Jan 2021 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + start_date: "Fri, 01 Jan 2021 00:00:00 GMT", + end_date: "Sat, 01 Jan 2022 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + Total: 74435, + start_date: "Sat, 01 Jan 2022 00:00:00 GMT", + end_date: "Sun, 01 Jan 2023 00:00:00 GMT", + frequency: "ANNUAL", + dataVizMissingData: 0, + }, +]; + +const testDatapoints4WithGapDatapoints2: Datapoint[] = [ + { + start_date: "Tue, 01 Jan 2013 00:00:00 GMT", + end_date: "Wed, 01 Jan 2014 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + start_date: "Wed, 01 Jan 2014 00:00:00 GMT", + end_date: "Thu, 01 Jan 2015 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + Total: 52342, + start_date: "Thu, 01 Jan 2015 00:00:00 GMT", + end_date: "Fri, 01 Jan 2016 00:00:00 GMT", + frequency: "ANNUAL", + dataVizMissingData: 0, + }, + { + start_date: "Fri, 01 Jan 2016 00:00:00 GMT", + end_date: "Sun, 01 Jan 2017 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + start_date: "Sun, 01 Jan 2017 00:00:00 GMT", + end_date: "Mon, 01 Jan 2018 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + start_date: "Mon, 01 Jan 2018 00:00:00 GMT", + end_date: "Tue, 01 Jan 2019 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + Total: 41241, + start_date: "Tue, 01 Jan 2019 00:00:00 GMT", + end_date: "Wed, 01 Jan 2020 00:00:00 GMT", + frequency: "ANNUAL", + dataVizMissingData: 0, + }, + { + start_date: "Wed, 01 Jan 2020 00:00:00 GMT", + end_date: "Fri, 01 Jan 2021 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + start_date: "Fri, 01 Jan 2021 00:00:00 GMT", + end_date: "Sat, 01 Jan 2022 00:00:00 GMT", + dataVizMissingData: 24811.666666666668, + frequency: "ANNUAL", + Total: 0, + }, + { + Total: 74435, + start_date: "Sat, 01 Jan 2022 00:00:00 GMT", + end_date: "Sun, 01 Jan 2023 00:00:00 GMT", + frequency: "ANNUAL", + dataVizMissingData: 0, + }, +]; + +const testDatapoints5: Datapoint[] = [ + { + start_date: "Thu, 01 Aug 2019 00:00:00 GMT", + end_date: "Sun, 01 Sep 2019 00:00:00 GMT", + Pretrial: 41, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 32, + "Transfer or Hold": 53, + Unknown: 12, + }, + { + start_date: "Wed, 01 Jan 2020 00:00:00 GMT", + end_date: "Sat, 01 Feb 2020 00:00:00 GMT", + Pretrial: 36541, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 79028, + Unknown: 65749, + "Transfer or Hold": 48334, + }, + { + start_date: "Sat, 01 Feb 2020 00:00:00 GMT", + end_date: "Sun, 01 Mar 2020 00:00:00 GMT", + Pretrial: 24112, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 82706, + "Transfer or Hold": 83057, + Unknown: 17415, + }, + { + start_date: "Sun, 01 Mar 2020 00:00:00 GMT", + end_date: "Wed, 01 Apr 2020 00:00:00 GMT", + Pretrial: 23767, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 90978, + "Transfer or Hold": 82590, + Unknown: 35303, + }, + { + start_date: "Wed, 01 Apr 2020 00:00:00 GMT", + end_date: "Fri, 01 May 2020 00:00:00 GMT", + Pretrial: 78458, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 46769, + "Transfer or Hold": 64874, + Unknown: 38205, + }, + { + start_date: "Fri, 01 May 2020 00:00:00 GMT", + end_date: "Mon, 01 Jun 2020 00:00:00 GMT", + Pretrial: 22677, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 61323, + "Transfer or Hold": 72938, + Unknown: 29553, + }, + { + start_date: "Mon, 01 Jun 2020 00:00:00 GMT", + end_date: "Wed, 01 Jul 2020 00:00:00 GMT", + Pretrial: 88997, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 38048, + "Transfer or Hold": 84709, + Unknown: 62951, + }, + { + start_date: "Wed, 01 Jul 2020 00:00:00 GMT", + end_date: "Sat, 01 Aug 2020 00:00:00 GMT", + Pretrial: 16324, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 16996, + "Transfer or Hold": 63347, + Unknown: 91685, + }, + { + start_date: "Sat, 01 Aug 2020 00:00:00 GMT", + end_date: "Tue, 01 Sep 2020 00:00:00 GMT", + Pretrial: 46650, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 23200, + "Transfer or Hold": 24195, + Unknown: 33681, + }, + { + start_date: "Tue, 01 Sep 2020 00:00:00 GMT", + end_date: "Thu, 01 Oct 2020 00:00:00 GMT", + Pretrial: 82010, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 14841, + "Transfer or Hold": 82407, + Unknown: 97055, + }, + { + start_date: "Thu, 01 Oct 2020 00:00:00 GMT", + end_date: "Sun, 01 Nov 2020 00:00:00 GMT", + Sentenced: 37221, + frequency: "MONTHLY", + dataVizMissingData: 0, + "Transfer or Hold": 22512, + Unknown: 49751, + Pretrial: 51938, + }, + { + start_date: "Sun, 01 Nov 2020 00:00:00 GMT", + end_date: "Tue, 01 Dec 2020 00:00:00 GMT", + Pretrial: 13252, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 89151, + "Transfer or Hold": 31343, + Unknown: 17920, + }, + { + start_date: "Tue, 01 Dec 2020 00:00:00 GMT", + end_date: "Fri, 01 Jan 2021 00:00:00 GMT", + Pretrial: 42300, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 27629, + "Transfer or Hold": 11736, + Unknown: 13635, + }, + { + start_date: "Fri, 01 Jan 2021 00:00:00 GMT", + end_date: "Mon, 01 Feb 2021 00:00:00 GMT", + Pretrial: 98369, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 46574, + "Transfer or Hold": 21353, + Unknown: 88769, + }, + { + start_date: "Mon, 01 Feb 2021 00:00:00 GMT", + end_date: "Mon, 01 Mar 2021 00:00:00 GMT", + Pretrial: 78759, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 53386, + "Transfer or Hold": 59075, + Unknown: 27134, + }, + { + start_date: "Mon, 01 Mar 2021 00:00:00 GMT", + end_date: "Thu, 01 Apr 2021 00:00:00 GMT", + Pretrial: 60053, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 34197, + "Transfer or Hold": 63531, + Unknown: 83579, + }, + { + start_date: "Thu, 01 Apr 2021 00:00:00 GMT", + end_date: "Sat, 01 May 2021 00:00:00 GMT", + Pretrial: 44759, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 17229, + "Transfer or Hold": 77299, + Unknown: 58031, + }, + { + start_date: "Sat, 01 May 2021 00:00:00 GMT", + end_date: "Tue, 01 Jun 2021 00:00:00 GMT", + Pretrial: 61558, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 59243, + "Transfer or Hold": 46498, + Unknown: 53175, + }, + { + start_date: "Tue, 01 Jun 2021 00:00:00 GMT", + end_date: "Thu, 01 Jul 2021 00:00:00 GMT", + Pretrial: 73726, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 60098, + "Transfer or Hold": 24792, + Unknown: 90376, + }, + { + start_date: "Thu, 01 Jul 2021 00:00:00 GMT", + end_date: "Sun, 01 Aug 2021 00:00:00 GMT", + Pretrial: 31102, + frequency: "MONTHLY", + dataVizMissingData: 0, + Unknown: 78794, + "Transfer or Hold": 10572, + Sentenced: 30228, + }, + { + start_date: "Sun, 01 Aug 2021 00:00:00 GMT", + end_date: "Wed, 01 Sep 2021 00:00:00 GMT", + Pretrial: 99665, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 82644, + "Transfer or Hold": 58060, + Unknown: 72892, + }, + { + start_date: "Wed, 01 Sep 2021 00:00:00 GMT", + end_date: "Fri, 01 Oct 2021 00:00:00 GMT", + Pretrial: 46416, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 33763, + "Transfer or Hold": 10680, + Unknown: 94129, + }, + { + start_date: "Fri, 01 Oct 2021 00:00:00 GMT", + end_date: "Mon, 01 Nov 2021 00:00:00 GMT", + Pretrial: 80719, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 96265, + "Transfer or Hold": 12347, + Unknown: 18056, + }, + { + start_date: "Mon, 01 Nov 2021 00:00:00 GMT", + end_date: "Wed, 01 Dec 2021 00:00:00 GMT", + Pretrial: 83549, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 77473, + "Transfer or Hold": 49179, + Unknown: 78634, + }, + { + start_date: "Wed, 01 Dec 2021 00:00:00 GMT", + end_date: "Sat, 01 Jan 2022 00:00:00 GMT", + Sentenced: 52931, + frequency: "MONTHLY", + dataVizMissingData: 0, + "Transfer or Hold": 24687, + Unknown: 92620, + Pretrial: 40598, + }, + { + start_date: "Sat, 01 Jan 2022 00:00:00 GMT", + end_date: "Tue, 01 Feb 2022 00:00:00 GMT", + Pretrial: 75641, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 59666, + "Transfer or Hold": 17668, + Unknown: 92062, + }, + { + start_date: "Tue, 01 Feb 2022 00:00:00 GMT", + end_date: "Tue, 01 Mar 2022 00:00:00 GMT", + Pretrial: 97743, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 34823, + "Transfer or Hold": 37207, + Unknown: 18960, + }, + { + start_date: "Tue, 01 Mar 2022 00:00:00 GMT", + end_date: "Fri, 01 Apr 2022 00:00:00 GMT", + Pretrial: 80843, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 92536, + "Transfer or Hold": 56184, + Unknown: 51573, + }, + { + start_date: "Fri, 01 Apr 2022 00:00:00 GMT", + end_date: "Sun, 01 May 2022 00:00:00 GMT", + Pretrial: 10958, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 48931, + "Transfer or Hold": 46672, + Unknown: 98907, + }, + { + start_date: "Sun, 01 May 2022 00:00:00 GMT", + end_date: "Wed, 01 Jun 2022 00:00:00 GMT", + Pretrial: 63710, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 26703, + "Transfer or Hold": 72473, + Unknown: 85367, + }, + { + start_date: "Wed, 01 Jun 2022 00:00:00 GMT", + end_date: "Fri, 01 Jul 2022 00:00:00 GMT", + Pretrial: 32303, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 85419, + "Transfer or Hold": 98064, + Unknown: 95473, + }, + { + start_date: "Fri, 01 Jul 2022 00:00:00 GMT", + end_date: "Mon, 01 Aug 2022 00:00:00 GMT", + Unknown: 90809, + frequency: "MONTHLY", + dataVizMissingData: 0, + "Transfer or Hold": 18233, + Sentenced: 38446, + Pretrial: 60273, + }, + { + start_date: "Mon, 01 Aug 2022 00:00:00 GMT", + end_date: "Thu, 01 Sep 2022 00:00:00 GMT", + Pretrial: 51711, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 25203, + "Transfer or Hold": 12208, + Unknown: 37137, + }, + { + start_date: "Thu, 01 Sep 2022 00:00:00 GMT", + end_date: "Sat, 01 Oct 2022 00:00:00 GMT", + Pretrial: 92358, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 99972, + "Transfer or Hold": 54671, + Unknown: 49974, + }, + { + start_date: "Sat, 01 Oct 2022 00:00:00 GMT", + end_date: "Tue, 01 Nov 2022 00:00:00 GMT", + Pretrial: null, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: null, + "Transfer or Hold": null, + Unknown: null, + }, + { + start_date: "Tue, 01 Nov 2022 00:00:00 GMT", + end_date: "Thu, 01 Dec 2022 00:00:00 GMT", + Unknown: 4000, + frequency: "MONTHLY", + dataVizMissingData: 0, + Pretrial: null, + Sentenced: null, + "Transfer or Hold": 1, + }, + { + start_date: "Thu, 01 Dec 2022 00:00:00 GMT", + end_date: "Sun, 01 Jan 2023 00:00:00 GMT", + Pretrial: null, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: null, + "Transfer or Hold": 0, + Unknown: null, + }, +]; + +const testDatapoints5Transformed: Datapoint[] = [ + { + start_date: "Fri, 01 Sep 2017 00:00:00 GMT", + end_date: "Sun, 01 Oct 2017 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Sun, 01 Oct 2017 00:00:00 GMT", + end_date: "Wed, 01 Nov 2017 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Wed, 01 Nov 2017 00:00:00 GMT", + end_date: "Fri, 01 Dec 2017 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Fri, 01 Dec 2017 00:00:00 GMT", + end_date: "Mon, 01 Jan 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Mon, 01 Jan 2018 00:00:00 GMT", + end_date: "Thu, 01 Feb 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Thu, 01 Feb 2018 00:00:00 GMT", + end_date: "Thu, 01 Mar 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Thu, 01 Mar 2018 00:00:00 GMT", + end_date: "Sun, 01 Apr 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Sun, 01 Apr 2018 00:00:00 GMT", + end_date: "Tue, 01 May 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Tue, 01 May 2018 00:00:00 GMT", + end_date: "Fri, 01 Jun 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Fri, 01 Jun 2018 00:00:00 GMT", + end_date: "Sun, 01 Jul 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Sun, 01 Jul 2018 00:00:00 GMT", + end_date: "Wed, 01 Aug 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Wed, 01 Aug 2018 00:00:00 GMT", + end_date: "Sat, 01 Sep 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Sat, 01 Sep 2018 00:00:00 GMT", + end_date: "Mon, 01 Oct 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Mon, 01 Oct 2018 00:00:00 GMT", + end_date: "Thu, 01 Nov 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Thu, 01 Nov 2018 00:00:00 GMT", + end_date: "Sat, 01 Dec 2018 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Sat, 01 Dec 2018 00:00:00 GMT", + end_date: "Tue, 01 Jan 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Tue, 01 Jan 2019 00:00:00 GMT", + end_date: "Fri, 01 Feb 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Fri, 01 Feb 2019 00:00:00 GMT", + end_date: "Fri, 01 Mar 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Fri, 01 Mar 2019 00:00:00 GMT", + end_date: "Mon, 01 Apr 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Mon, 01 Apr 2019 00:00:00 GMT", + end_date: "Wed, 01 May 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Wed, 01 May 2019 00:00:00 GMT", + end_date: "Sat, 01 Jun 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Sat, 01 Jun 2019 00:00:00 GMT", + end_date: "Mon, 01 Jul 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Mon, 01 Jul 2019 00:00:00 GMT", + end_date: "Thu, 01 Aug 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Thu, 01 Aug 2019 00:00:00 GMT", + end_date: "Sun, 01 Sep 2019 00:00:00 GMT", + Pretrial: 0.2971014492753623, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.2318840579710145, + "Transfer or Hold": 0.38405797101449274, + Unknown: 0.08695652173913043, + }, + { + start_date: "Sun, 01 Sep 2019 00:00:00 GMT", + end_date: "Tue, 01 Oct 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Tue, 01 Oct 2019 00:00:00 GMT", + end_date: "Fri, 01 Nov 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Fri, 01 Nov 2019 00:00:00 GMT", + end_date: "Sun, 01 Dec 2019 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Sun, 01 Dec 2019 00:00:00 GMT", + end_date: "Wed, 01 Jan 2020 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Wed, 01 Jan 2020 00:00:00 GMT", + end_date: "Sat, 01 Feb 2020 00:00:00 GMT", + Pretrial: 0.15911466044275688, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.3441206695347744, + Unknown: 0.2862983993172278, + "Transfer or Hold": 0.21046627070524096, + }, + { + start_date: "Sat, 01 Feb 2020 00:00:00 GMT", + end_date: "Sun, 01 Mar 2020 00:00:00 GMT", + Pretrial: 0.11632013121713541, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.3989869265280525, + "Transfer or Hold": 0.4006802064740219, + Unknown: 0.0840127357807902, + }, + { + start_date: "Sun, 01 Mar 2020 00:00:00 GMT", + end_date: "Wed, 01 Apr 2020 00:00:00 GMT", + Pretrial: 0.10216301721988669, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.39107110618213703, + "Transfer or Hold": 0.355015087818843, + Unknown: 0.15175078877913326, + }, + { + start_date: "Wed, 01 Apr 2020 00:00:00 GMT", + end_date: "Fri, 01 May 2020 00:00:00 GMT", + Pretrial: 0.343652816833548, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.204852259686561, + "Transfer or Hold": 0.28415372351142765, + Unknown: 0.1673411999684634, + }, + { + start_date: "Fri, 01 May 2020 00:00:00 GMT", + end_date: "Mon, 01 Jun 2020 00:00:00 GMT", + Pretrial: 0.12159836131502325, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.32882551973017465, + "Transfer or Hold": 0.39110734566279337, + Unknown: 0.15846877329200873, + }, + { + start_date: "Mon, 01 Jun 2020 00:00:00 GMT", + end_date: "Wed, 01 Jul 2020 00:00:00 GMT", + Pretrial: 0.32397298920660345, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.13850494166469485, + "Transfer or Hold": 0.3083635172275714, + Unknown: 0.2291585519011303, + }, + { + start_date: "Wed, 01 Jul 2020 00:00:00 GMT", + end_date: "Sat, 01 Aug 2020 00:00:00 GMT", + Pretrial: 0.0866675161399932, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.0902353041114509, + "Transfer or Hold": 0.33632241760108733, + Unknown: 0.48677476214746856, + }, + { + start_date: "Sat, 01 Aug 2020 00:00:00 GMT", + end_date: "Tue, 01 Sep 2020 00:00:00 GMT", + Pretrial: 0.36523495607785417, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.1816388206003476, + "Transfer or Hold": 0.1894289338114401, + Unknown: 0.2636972895103581, + }, + { + start_date: "Tue, 01 Sep 2020 00:00:00 GMT", + end_date: "Thu, 01 Oct 2020 00:00:00 GMT", + Pretrial: 0.296801091515781, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.05371082793788204, + "Transfer or Hold": 0.29823786792514284, + Unknown: 0.3512502126211941, + }, + { + start_date: "Thu, 01 Oct 2020 00:00:00 GMT", + end_date: "Sun, 01 Nov 2020 00:00:00 GMT", + Sentenced: 0.23058195289365763, + frequency: "MONTHLY", + dataVizMissingData: 0, + "Transfer or Hold": 0.1394605444115424, + Unknown: 0.30820458177943527, + Pretrial: 0.32175292091536467, + }, + { + start_date: "Sun, 01 Nov 2020 00:00:00 GMT", + end_date: "Tue, 01 Dec 2020 00:00:00 GMT", + Pretrial: 0.08737620824706922, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.5878113749950549, + "Transfer or Hold": 0.2066580512441813, + Unknown: 0.11815436551369457, + }, + { + start_date: "Tue, 01 Dec 2020 00:00:00 GMT", + end_date: "Fri, 01 Jan 2021 00:00:00 GMT", + Pretrial: 0.4438614900314795, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.28991605456453307, + "Transfer or Hold": 0.1231479538300105, + Unknown: 0.14307450157397691, + }, + { + start_date: "Fri, 01 Jan 2021 00:00:00 GMT", + end_date: "Mon, 01 Feb 2021 00:00:00 GMT", + Pretrial: 0.38566247819183347, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.18259659302530729, + "Transfer or Hold": 0.08371591555093799, + Unknown: 0.34802501323192125, + }, + { + start_date: "Mon, 01 Feb 2021 00:00:00 GMT", + end_date: "Mon, 01 Mar 2021 00:00:00 GMT", + Pretrial: 0.3606941022376508, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.24449288769612648, + "Transfer or Hold": 0.2705469100634749, + Unknown: 0.12426610000274783, + }, + { + start_date: "Mon, 01 Mar 2021 00:00:00 GMT", + end_date: "Thu, 01 Apr 2021 00:00:00 GMT", + Pretrial: 0.2488109048723898, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.14168462048392444, + "Transfer or Hold": 0.26322091481604243, + Unknown: 0.34628355982764336, + }, + { + start_date: "Thu, 01 Apr 2021 00:00:00 GMT", + end_date: "Sat, 01 May 2021 00:00:00 GMT", + Pretrial: 0.22683688259560708, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.08731590630353034, + "Transfer or Hold": 0.39174834531061536, + Unknown: 0.2940988657902472, + }, + { + start_date: "Sat, 01 May 2021 00:00:00 GMT", + end_date: "Tue, 01 Jun 2021 00:00:00 GMT", + Pretrial: 0.2792075256039261, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.2687074212832352, + "Transfer or Hold": 0.21090015149178587, + Unknown: 0.24118490162105283, + }, + { + start_date: "Tue, 01 Jun 2021 00:00:00 GMT", + end_date: "Thu, 01 Jul 2021 00:00:00 GMT", + Pretrial: 0.29609786659812365, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.24136518442359595, + "Transfer or Hold": 0.0995694640791672, + Unknown: 0.36296748489911324, + }, + { + start_date: "Thu, 01 Jul 2021 00:00:00 GMT", + end_date: "Sun, 01 Aug 2021 00:00:00 GMT", + Pretrial: 0.2063890216064129, + frequency: "MONTHLY", + dataVizMissingData: 0, + Unknown: 0.5228672293889686, + "Transfer or Hold": 0.07015448319796146, + Sentenced: 0.20058926580665712, + }, + { + start_date: "Sun, 01 Aug 2021 00:00:00 GMT", + end_date: "Wed, 01 Sep 2021 00:00:00 GMT", + Pretrial: 0.3181532332463984, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.26381834955516326, + "Transfer or Hold": 0.18534065842859468, + Unknown: 0.23268775876984368, + }, + { + start_date: "Wed, 01 Sep 2021 00:00:00 GMT", + end_date: "Fri, 01 Oct 2021 00:00:00 GMT", + Pretrial: 0.25091357277228793, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.1825145414837719, + "Transfer or Hold": 0.05773347460375808, + Unknown: 0.508838411140182, + }, + { + start_date: "Fri, 01 Oct 2021 00:00:00 GMT", + end_date: "Mon, 01 Nov 2021 00:00:00 GMT", + Pretrial: 0.3892191892452275, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.4641804934735543, + "Transfer or Hold": 0.059536036492162, + Unknown: 0.0870642807890562, + }, + { + start_date: "Mon, 01 Nov 2021 00:00:00 GMT", + end_date: "Wed, 01 Dec 2021 00:00:00 GMT", + Pretrial: 0.2892620354181453, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.2682258036595288, + "Transfer or Hold": 0.17026676129970397, + Unknown: 0.2722453996226219, + }, + { + start_date: "Wed, 01 Dec 2021 00:00:00 GMT", + end_date: "Sat, 01 Jan 2022 00:00:00 GMT", + Sentenced: 0.2510529511089188, + frequency: "MONTHLY", + dataVizMissingData: 0, + "Transfer or Hold": 0.11709100912557628, + Unknown: 0.43929879147773626, + Pretrial: 0.19255724828776868, + }, + { + start_date: "Sat, 01 Jan 2022 00:00:00 GMT", + end_date: "Tue, 01 Feb 2022 00:00:00 GMT", + Pretrial: 0.30869215669470323, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.24349792072217666, + "Transfer or Hold": 0.0721033966298967, + Unknown: 0.3757065259532234, + }, + { + start_date: "Tue, 01 Feb 2022 00:00:00 GMT", + end_date: "Tue, 01 Mar 2022 00:00:00 GMT", + Pretrial: 0.5178903530384193, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.1845093332909454, + "Transfer or Hold": 0.19714093454774734, + Unknown: 0.1004593791228879, + }, + { + start_date: "Tue, 01 Mar 2022 00:00:00 GMT", + end_date: "Fri, 01 Apr 2022 00:00:00 GMT", + Pretrial: 0.28755833475613224, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.32915030447897103, + "Transfer or Hold": 0.19984633771555405, + Unknown: 0.18344502304934265, + }, + { + start_date: "Fri, 01 Apr 2022 00:00:00 GMT", + end_date: "Sun, 01 May 2022 00:00:00 GMT", + Pretrial: 0.05333190569821091, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.23814413923335995, + "Transfer or Hold": 0.22714972647808904, + Unknown: 0.4813742285903401, + }, + { + start_date: "Sun, 01 May 2022 00:00:00 GMT", + end_date: "Wed, 01 Jun 2022 00:00:00 GMT", + Pretrial: 0.25663335387689173, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.10756365481988132, + "Transfer or Hold": 0.2919320209624858, + Unknown: 0.3438709703407411, + }, + { + start_date: "Wed, 01 Jun 2022 00:00:00 GMT", + end_date: "Fri, 01 Jul 2022 00:00:00 GMT", + Pretrial: 0.10378173803809689, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.27443061887367115, + "Transfer or Hold": 0.3150559501893921, + Unknown: 0.3067316928988399, + }, + { + start_date: "Fri, 01 Jul 2022 00:00:00 GMT", + end_date: "Mon, 01 Aug 2022 00:00:00 GMT", + Unknown: 0.437083957046799, + frequency: "MONTHLY", + dataVizMissingData: 0, + "Transfer or Hold": 0.08775949287883673, + Sentenced: 0.1850491670717796, + Pretrial: 0.2901073830025847, + }, + { + start_date: "Mon, 01 Aug 2022 00:00:00 GMT", + end_date: "Thu, 01 Sep 2022 00:00:00 GMT", + Pretrial: 0.4095628826459896, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.19961349289951608, + "Transfer or Hold": 0.09669013694073293, + Unknown: 0.2941334875137614, + }, + { + start_date: "Thu, 01 Sep 2022 00:00:00 GMT", + end_date: "Sat, 01 Oct 2022 00:00:00 GMT", + Pretrial: 0.3109958750736594, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: 0.3366343968347504, + "Transfer or Hold": 0.18409293711591884, + Unknown: 0.16827679097567136, + }, + { + start_date: "Sat, 01 Oct 2022 00:00:00 GMT", + end_date: "Tue, 01 Nov 2022 00:00:00 GMT", + dataVizMissingData: 0.3333333333333333, + frequency: "MONTHLY", + Pretrial: 0, + Sentenced: 0, + "Transfer or Hold": 0, + Unknown: 0, + }, + { + start_date: "Tue, 01 Nov 2022 00:00:00 GMT", + end_date: "Thu, 01 Dec 2022 00:00:00 GMT", + Unknown: 0.9997500624843789, + frequency: "MONTHLY", + dataVizMissingData: 0, + Pretrial: null, + Sentenced: null, + "Transfer or Hold": 0.00024993751562109475, + }, + { + start_date: "Thu, 01 Dec 2022 00:00:00 GMT", + end_date: "Sun, 01 Jan 2023 00:00:00 GMT", + Pretrial: null, + frequency: "MONTHLY", + dataVizMissingData: 0, + Sentenced: null, + "Transfer or Hold": 0, + Unknown: null, + }, +]; + +beforeAll(() => { + jest.useFakeTimers("modern"); + jest.setSystemTime(new Date(2022, 7, 23)); +}); + +afterAll(() => { + jest.useRealTimers(); +}); + +describe("incrementMonth", () => { + test("incrementMonth increments month correctly", () => { + const testDate = new Date("Tue, 01 Mar 2022 00:00:00 GMT"); + const testDate2 = new Date("Thu, 01 Dec 2022 00:00:00 GMT"); + expect(incrementMonth(testDate).toUTCString()).toBe( + "Fri, 01 Apr 2022 00:00:00 GMT" + ); + expect(incrementMonth(testDate2).toUTCString()).toBe( + "Sun, 01 Jan 2023 00:00:00 GMT" + ); + }); +}); + +describe("incrementYear", () => { + test("incrementYear increments year correctly", () => { + const testDate = new Date("Tue, 01 Mar 2022 00:00:00 GMT"); + const testDate2 = new Date("Thu, 01 Dec 2022 00:00:00 GMT"); + expect(incrementYear(testDate).toUTCString()).toBe( + "Wed, 01 Mar 2023 00:00:00 GMT" + ); + expect(incrementYear(testDate2).toUTCString()).toBe( + "Fri, 01 Dec 2023 00:00:00 GMT" + ); + }); +}); + +describe("filterByTimeRange", () => { + test("filterByTimeRange filters through different months", () => { + expect(filterByTimeRange(testDatapoints, 6).length).toBe(10); + expect(filterByTimeRange(testDatapoints, 12).length).toBe(16); + }); +}); + +describe("transformToRelativePerchanges", () => { + test("transformToRelativePerchanges transforms datapoints correctly", () => { + expect(transformToRelativePerchanges(testDatapoints2)).toStrictEqual( + testDatapoints2Percentages + ); + }); +}); + +describe("filterNullDatapoints", () => { + test("filterNullDatapoints filters datapoints with all null dimensions only", () => { + expect(filterNullDatapoints(testDatapoints3)).toStrictEqual( + testDatapoints3WithoutNullDatapoints + ); + }); +}); + +describe("fillTimeGapsBetweenDatapoints", () => { + test("fillTimeGapsBetweenDatapoints adds datapoints between data", () => { + expect(fillTimeGapsBetweenDatapoints(testDatapoints4, 0)).toStrictEqual( + testDatapoints4WithGapDatapoints + ); + }); + test("fillTimeGapsBetweenDatapoints adds datapoints between data plus additional earlier month padding", () => { + expect(fillTimeGapsBetweenDatapoints(testDatapoints4, 120)).toStrictEqual( + testDatapoints4WithGapDatapoints2 + ); + }); +}); + +describe("transformData", () => { + test("putting it all together", () => { + expect(transformData(testDatapoints5, 60, "Percentage")).toStrictEqual( + testDatapoints5Transformed + ); + }); +}); diff --git a/publisher/src/components/DataViz/utils.ts b/publisher/src/components/DataViz/utils.ts new file mode 100644 index 000000000..45e0831f5 --- /dev/null +++ b/publisher/src/components/DataViz/utils.ts @@ -0,0 +1,335 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { mapValues, pickBy } from "lodash"; + +import { + Datapoint, + DatapointsViewSetting, + DataVizAggregateName, + DataVizTimeRange, +} from "../../shared/types"; +import { formatNumberInput } from "../../utils"; + +export const thirtyOneDaysInSeconds = 2678400000; +export const threeHundredSixtySixDaysInSeconds = 31622400000; + +export const nextMonthMap = new Map([ + ["Jan", "Feb"], + ["Feb", "Mar"], + ["Mar", "Apr"], + ["Apr", "May"], + ["May", "Jun"], + ["Jun", "Jul"], + ["Jul", "Aug"], + ["Aug", "Sep"], + ["Sep", "Oct"], + ["Oct", "Nov"], + ["Nov", "Dec"], + ["Dec", "Jan"], +]); + +const abbreviatedMonths = [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", +]; + +export const splitUtcString = (utcString: string) => { + // the utc string can be split like this: + // const [dayOfWeek, day, month, year, time, timezone] = splitUtcString(str); + return utcString.split(" "); +}; + +export const getDatapointDimensions = (datapoint: Datapoint) => + // gets the datapoint object minus the non-dimension keys "start_date", "end_date", "frequency", "dataVizMissingData" + pickBy( + datapoint, + (val, key) => + key !== "start_date" && + key !== "end_date" && + key !== "frequency" && + key !== "dataVizMissingData" + ); + +export const sortDatapointDimensions = (dimA: string, dimB: string) => { + // sort alphabetically, except put "Other" and "Unknown" at the end. + if (dimA === "Other" && dimB === "Unknown") { + return -1; + } + if (dimB === "Other" && dimA === "Unknown") { + return 1; + } + if (dimA === "Other" || dimA === "Unknown") { + return 1; + } + if (dimB === "Other" || dimB === "Unknown") { + return -1; + } + return dimA.localeCompare(dimB); +}; + +export const getSumOfDimensionValues = (datapoint: Datapoint) => { + let sumOfDimensions = 0; + const dimensions = getDatapointDimensions(datapoint); + Object.values(dimensions).forEach((value) => { + sumOfDimensions += value as number; + }); + return sumOfDimensions; +}; + +// write my own month incrementer since Date.setMonth doesn't keep the date the same... +export const incrementMonth = (date: Date) => { + const [, day, month, year, time, timezone] = splitUtcString( + date.toUTCString() + ); + return new Date( + `${day} ${nextMonthMap.get(month)} ${ + month === "Dec" ? Number(year) + 1 : year + } ${time} ${timezone}` + ); +}; + +export const incrementYear = (date: Date) => { + const clonedDate = new Date(date.getTime()); + clonedDate.setFullYear(clonedDate.getFullYear() + 1); + return clonedDate; +}; + +// returns a new Date set to the GMT time zone +// for comparing with Datapoint time strings which are also set to 00:00:00 GMT. +export const createGMTDate = ( + day: number, + monthIndex: number, + year: number +) => { + return new Date( + `${day} ${abbreviatedMonths[monthIndex]} ${year} 00:00:00 GMT` + ); +}; + +export const getHighestTotalValue = (data: Datapoint[]) => { + let highestValue = 0; + data.forEach((datapoint) => { + const sumOfDimensions = getSumOfDimensionValues(datapoint); + if (sumOfDimensions > highestValue) { + highestValue = sumOfDimensions; + } + }); + return highestValue; +}; + +// functions to transform and filter an array of Datapoints to display in a chart + +export const filterByTimeRange = ( + data: Datapoint[], + monthsAgo: DataVizTimeRange +) => { + if (monthsAgo === 0) { + return data; + } + const earliestDate = new Date(); + earliestDate.setMonth(earliestDate.getMonth() - monthsAgo); + earliestDate.setHours( + earliestDate.getHours() - earliestDate.getTimezoneOffset() / 60 + ); // account for timezone offset since datapoint dates are in UTC+0 time. + return data.filter((dp) => { + return new Date(dp.start_date) >= earliestDate; + }); +}; + +export const transformToRelativePerchanges = (data: Datapoint[]) => { + return data.map((datapoint) => { + const dimensions = getDatapointDimensions(datapoint); + const sumOfDimensions = getSumOfDimensionValues(datapoint); + const dimensionsPercentage = mapValues(dimensions, (val, key) => { + if (typeof val === "number" && val !== 0) { + return val / sumOfDimensions; + } + return val; + }); + return { + ...datapoint, + ...dimensionsPercentage, + }; + }); +}; + +export const filterNullDatapoints = (data: Datapoint[]) => { + return data.filter((datapoint) => { + const dimensions = getDatapointDimensions(datapoint); + let hasReportedValues = false; + Object.values(dimensions).every((dimValue) => { + if (dimValue !== null) { + hasReportedValues = true; + return false; + } + return true; + }); + return hasReportedValues; + }); +}; + +/** + * A gap datapoint represents a time range with no reported data + * and is formatted by setting all dimension values to 0 + * and setting the value of "dataVizMissingData" to ~1/3 the height of the bar on the chart. + * + * This method generates gap datapoints between datapoints up to a certain number of months ago. + */ +export const fillTimeGapsBetweenDatapoints = ( + data: Datapoint[], + monthsAgo: number +) => { + if (data.length === 0) { + return data; + } + + const isAnnual = data[0].frequency === "ANNUAL"; + const increment = isAnnual ? incrementYear : incrementMonth; + const defaultBarValue = getHighestTotalValue(data) / 3; + const dataWithGapDatapoints = [...data]; + // create the map of dimensions with zero values + const dimensionsMap = mapValues(getDatapointDimensions(data[0]), (_) => 0); + + // loop through all the datapoints + let totalOffset = 0; // whenever we insert a gap datapoint into `dataWithGapDatapoints`, increment the totalOffset + let lastDate = new Date(); + if (isAnnual) { + lastDate.setFullYear(lastDate.getFullYear() - monthsAgo / 12); + } else { + lastDate.setMonth(lastDate.getMonth() - monthsAgo); + } + lastDate = createGMTDate( + 1, + isAnnual ? 0 : lastDate.getMonth(), + lastDate.getFullYear() + ); + for (let i = 0; i < data.length; i += 1) { + const currentDate = new Date(data[i].start_date); + const timeInterval = + data[0].frequency === "MONTHLY" + ? thirtyOneDaysInSeconds + : threeHundredSixtySixDaysInSeconds; + // this while loop can insert multiple gap datapoints between datapoints + // so must increment this offset to maintain correct insert order + let offset = 0; + while (currentDate.getTime() - lastDate.getTime() > timeInterval) { + lastDate = increment(lastDate); + dataWithGapDatapoints.splice(i + offset + totalOffset, 0, { + start_date: lastDate.toUTCString(), + end_date: increment(lastDate).toUTCString(), + dataVizMissingData: defaultBarValue, + frequency: data[0].frequency, + ...dimensionsMap, + }); + offset += 1; + } + totalOffset += offset; + lastDate = currentDate; + } + + return dataWithGapDatapoints; +}; + +export const transformData = ( + d: Datapoint[], + monthsAgo: DataVizTimeRange, + datapointsViewSetting: DatapointsViewSetting +) => { + let transformedData = [...d]; + + if (transformedData.length === 0) { + return transformedData; + } + + // filter by time range + transformedData = filterByTimeRange(transformedData, monthsAgo); + + transformedData = filterNullDatapoints(transformedData); + + // format data into percentages for percentage view + if (datapointsViewSetting === "Percentage") { + transformedData = transformToRelativePerchanges(transformedData); + } + + return fillTimeGapsBetweenDatapoints(transformedData, monthsAgo); +}; + +// get insights from data + +export const getPercentChangeOverTime = (data: Datapoint[]) => { + if (data.length > 0) { + const start = data[0][DataVizAggregateName] as number | undefined; + const end = data[data.length - 1][DataVizAggregateName] as + | number + | undefined; + if (start !== undefined && end !== undefined) { + const formattedPercentChange = formatNumberInput( + Math.round(((end - start) / start) * 100).toString() + ); + if (formattedPercentChange) { + return `${formattedPercentChange}%`; + } + } + } + return "N/A"; +}; + +export const getAverageTotalValue = (data: Datapoint[], isAnnual: boolean) => { + if (data.length > 0) { + let totalValueFound = false; + const avgTotalValue = + data.reduce((res, dp) => { + if (dp[DataVizAggregateName] !== undefined) { + totalValueFound = true; + return res + (dp[DataVizAggregateName] as number); + } + return res; + }, 0) / data.length; + if (totalValueFound && avgTotalValue !== undefined) { + const formattedAvgTotalValue = formatNumberInput( + Math.round(avgTotalValue).toString() + ); + if (formattedAvgTotalValue !== undefined) { + return `${formattedAvgTotalValue}/${isAnnual ? "yr" : "mo"}`; + } + } + } + return "N/A"; +}; + +export const getLatestDateFormatted = ( + data: Datapoint[], + isAnnual: boolean +) => { + const mostRecentDate = data[data.length - 1]?.start_date; + if (mostRecentDate) { + const [, , month, year] = splitUtcString(mostRecentDate); + return `${!isAnnual ? `${month} ` : ""}${year}`; + } + return "N/A"; +}; diff --git a/publisher/src/components/Error/NoAuthConfigErrorPage.tsx b/publisher/src/components/Error/NoAuthConfigErrorPage.tsx new file mode 100644 index 000000000..3cd503240 --- /dev/null +++ b/publisher/src/components/Error/NoAuthConfigErrorPage.tsx @@ -0,0 +1,38 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import styled from "styled-components/macro"; + +const NoAuthConfigError = styled.div` + height: 100vh; + width: 100vw; + display: flex; + justify-content: center; + align-items: center; +`; + +const NoAuthConfigErrorPage = () => { + return ( + + No authentication configuration detected. Please refresh the page or try + again later. + + ); +}; + +export default NoAuthConfigErrorPage; diff --git a/publisher/src/components/Forms/BinaryRadioButton.tsx b/publisher/src/components/Forms/BinaryRadioButton.tsx new file mode 100644 index 000000000..d61ad243b --- /dev/null +++ b/publisher/src/components/Forms/BinaryRadioButton.tsx @@ -0,0 +1,143 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { InputHTMLAttributes } from "react"; +import styled from "styled-components/macro"; + +import { palette, typography } from "../GlobalStyles"; + +export const BinaryRadioGroupContainer = styled.div` + display: flex; + flex-direction: column; + position: relative; +`; + +export const BinaryRadioGroupWrapper = styled.div` + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; +`; + +export const BinaryRadioGroupQuestion = styled.div` + ${typography.sizeCSS.medium} + display: flex; + align-items: center; + margin-top: 22px; + color: ${palette.solid.darkgrey}; +`; + +export const RadioButtonWrapper = styled.div` + display: flex; + flex: 1 1 0; + margin: 15px 0 0 0; + + &:first-child { + margin: 15px 10px 0 0; + } +`; + +export const RadioButtonElement = styled.input<{ + disabled?: boolean; +}>` + width: 0; + position: fixed; + opacity: 0; + + &:focus + label { + border: ${({ disabled }) => + disabled ? "none" : `1px solid ${palette.highlight.grey9}`}; + } + + &:checked + label { + background-color: ${palette.solid.blue}; + border-color: ${palette.solid.blue}; + color: ${palette.solid.white}; + } + + &:checked + label:hover { + background-color: ${({ disabled }) => + disabled ? "none" : palette.solid.darkblue}; + } + + &:hover { + cursor: ${({ disabled }) => (disabled ? "not-allowed" : "pointer")}; + } +`; + +export const RadioButtonLabel = styled.label<{ + disabled?: boolean; +}>` + ${typography.sizeCSS.medium} + width: 100%; + height: 56px; + display: flex; + justify-content: center; + align-items: center; + background: ${palette.highlight.grey1}; + padding: 16px 24px; + border: 1px solid ${palette.highlight.grey3}; + border-radius: 2px; + transition: 0.2s ease; + + &:hover { + cursor: ${({ disabled }) => (disabled ? "not-allowed" : "pointer")}; + background-color: ${({ disabled }) => + disabled ? "none" : palette.highlight.grey2}; + } +`; + +export const BinaryRadioGroupClearButton = styled.div<{ + disabled?: boolean; +}>` + ${typography.sizeCSS.small} + margin-top: 8px; + color: ${palette.solid.blue}; + text-decoration: underline; + + &:hover { + cursor: ${({ disabled }) => (disabled ? "not-allowed" : "pointer")}; + } +`; + +interface RadioButtonProps extends InputHTMLAttributes { + label: string; + context?: string; + metricKey?: string; +} + +/** Single radio button in the style of a regular button */ +export const BinaryRadioButton: React.FC = ({ + label, + context, + metricKey, + disabled, + ...props +}): JSX.Element => { + return ( + + + + {label} + + + ); +}; diff --git a/publisher/src/components/Forms/Dropdown.tsx b/publisher/src/components/Forms/Dropdown.tsx new file mode 100644 index 000000000..5e9442e62 --- /dev/null +++ b/publisher/src/components/Forms/Dropdown.tsx @@ -0,0 +1,92 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { SelectHTMLAttributes } from "react"; +import styled from "styled-components/macro"; + +import { palette, typography } from "../GlobalStyles"; + +const DropdownContainer = styled.div` + position: relative; + width: 100%; + &:first-child { + margin-right: 10px; + } +`; + +const DropdownSelection = styled.select` + ${typography.sizeCSS.large} + height: 71px; + width: 100%; + margin: 10px 0; + background: ${palette.highlight.lightblue1}; + color: ${palette.solid.darkgrey}; + caret-color: ${palette.solid.blue}; + border: none; + border-bottom: 1px solid ${palette.solid.blue}; + + padding-left: 16px; + margin-top: 15px; + + appearance: none; + + &:hover { + cursor: pointer; + } +`; + +const DropdownArrowContainer = styled.div` + pointer-events: none; + width: 30px; + height: 30px; + border-radius: 15px; + background: ${palette.highlight.lightblue2}; + position: absolute; + top: 35px; + right: 16px; + display: flex; + align-items: center; + justify-content: center; +`; + +const DropdownArrow = styled.div` + width: 12px; + height: 12px; + border: none; + border-bottom: 4px solid ${palette.solid.blue}; + border-right: 4px solid ${palette.solid.blue}; + transform: rotate(45deg) translate(-1px, -1px); +`; + +interface DropdownProps extends SelectHTMLAttributes { + children: JSX.Element[]; +} + +export const Dropdown: React.FC = ({ + value, + onChange, + children, +}) => ( + + + {children} + + + + + +); diff --git a/publisher/src/components/Forms/Form.styles.tsx b/publisher/src/components/Forms/Form.styles.tsx new file mode 100644 index 000000000..427424dda --- /dev/null +++ b/publisher/src/components/Forms/Form.styles.tsx @@ -0,0 +1,282 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import styled from "styled-components/macro"; + +import { HEADER_BAR_HEIGHT, palette, typography } from "../GlobalStyles"; +import { + DATA_ENTRY_WIDTH, + ONE_PANEL_MAX_WIDTH, + SINGLE_COLUMN_MAX_WIDTH, + TWO_PANEL_MAX_WIDTH, +} from "../Reports/ReportDataEntry.styles"; + +export const PageWrapper = styled.div` + height: 100%; + width: 100%; + display: flex; + justify-content: center; + padding-top: ${HEADER_BAR_HEIGHT}px; + position: absolute; + top: 0; + z-index: 0; + background: ${palette.solid.white}; +`; + +export const FormWrapper = styled.div` + flex: 0 1 ${DATA_ENTRY_WIDTH}px; + display: flex; + flex-direction: column; + margin: 32px 360px 50px 360px; + + @media only screen and (max-width: ${TWO_PANEL_MAX_WIDTH}px) { + margin: 32px 24px 50px 360px; + } + + @media only screen and (max-width: ${ONE_PANEL_MAX_WIDTH}px) { + margin: 32px 24px 50px 24px; + } +`; + +export const Form = styled.form` + display: block; + padding-bottom: 100px; +`; + +type TitleWrapperProps = { + underlined?: boolean; +}; + +export const TitleWrapper = styled.div` + width: 100%; + display: flex; + flex-direction: column; + border-bottom: ${({ underlined }) => + underlined ? `1px solid ${palette.solid.darkgrey}` : `none`}; +`; + +export const PreTitle = styled.div` + ${typography.sizeCSS.normal} +`; + +export const OnePanelBackLinkContainer = styled(PreTitle)` + display: none; + @media only screen and (max-width: ${ONE_PANEL_MAX_WIDTH}px) { + display: block; + top: 0; + width: 100%; + margin-right: -1px; + margin-left: -1px; + margin-bottom: 26px; + background-color: ${palette.solid.white}; + z-index: 1; + } +`; + +export const MetricsSectionTitle = styled.div` + ${typography.sizeCSS.normal} + margin-top: 6px; + margin-right: 17px; +`; + +export const Title = styled.h1<{ scrolled?: boolean; sticky?: boolean }>` + ${({ scrolled }) => + scrolled ? typography.sizeCSS.medium : typography.sizeCSS.title} + + ${({ scrolled }) => scrolled && `padding-top: 16px;`} + + margin-top: 4px; + padding-bottom: 14px; + border-bottom: 1px solid ${palette.highlight.grey9}; + transition: 0.3s ease; + + ${({ sticky }) => + sticky && + ` + position: sticky; + top: ${HEADER_BAR_HEIGHT}px; + background: ${palette.solid.white}; + z-index: 2; + margin-right: -1px; + margin-left: -1px; + `} +`; + +export const Metric = styled.div<{ notReporting?: boolean }>` + margin-top: -6.5em; + padding-top: 6.5em; + margin-bottom: ${({ notReporting }) => (notReporting ? `50px` : `194px`)}; +`; + +export const MetricSectionTitleWrapper = styled.div` + display: flex; + align-items: flex-end; +`; + +export const MetricSectionTitle = styled.div<{ notReporting?: boolean }>` + ${typography.sizeCSS.large} + margin-right: 17px; + margin-top: 32px; + color: ${({ notReporting }) => + notReporting ? palette.highlight.grey8 : palette.solid.darkgrey}; +`; + +export const MetricSystemTitle = styled(MetricSectionTitle)<{ + firstTitle?: boolean; +}>` + color: ${palette.highlight.grey8}; + border-top: ${({ firstTitle }) => + firstTitle ? `none` : `1px solid ${palette.highlight.grey8}`}; + padding-top: ${({ firstTitle }) => (firstTitle ? `none` : `30px`)}; + width: 100%; + + &:first-child { + border-top: none; + } +`; + +export const MetricSectionSubTitle = styled.div` + ${typography.sizeCSS.medium} + color: ${palette.highlight.grey8}; + margin-top: 8px; + margin-bottom: 16px; +`; + +export const DisaggregationTabsContainer = styled.div` + display: flex; + flex-direction: column; +`; + +export const TabsRow = styled.div` + width: 100%; + display: flex; + margin-bottom: 32px; + border-bottom: 1px solid ${palette.solid.darkgrey}; +`; + +export const TabItem = styled.div<{ active?: boolean }>` + ${typography.sizeCSS.normal} + display: flex; + margin-right: 32px; + transition: 0.2s ease; + color: ${({ active }) => + active ? palette.solid.blue : palette.highlight.grey7}; + padding-bottom: 7px; + border-bottom: 3px solid + ${({ active }) => (active ? palette.solid.blue : `transparent`)}; + + &:hover { + cursor: pointer; + color: ${palette.solid.blue}; + } +`; + +export const DisaggregationHasInputIndicator = styled.div<{ + active?: boolean; + hasInput?: boolean; + error?: boolean; +}>` + height: 16px; + width: 16px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + margin-left: 8px; + align-self: center; + border: 1px solid ${palette.highlight.grey4}; + ${({ active, hasInput, error }) => + !active && + (hasInput || error) && + `border: none; filter: grayscale(1) opacity(0.3);`} +`; + +export const TabDisplay = styled.div` + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: space-between; +`; + +export const DisaggregationInputWrapper = styled.div` + label { + width: 100%; + padding-right: 60px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + @media only screen and (max-width: ${SINGLE_COLUMN_MAX_WIDTH}px) { + width: 100%; + + label { + width: 100%; + } + } +`; + +export const Button = styled.button` + ${typography.sizeCSS.medium} + width: 314px; + height: 56px; + display: flex; + justify-content: center; + align-items: center; + background: ${palette.highlight.grey1}; + border: 1px solid ${palette.highlight.grey3}; + border-radius: 2px; + + &:hover { + cursor: pointer; + background: ${palette.highlight.grey2}; + } +`; + +export const GoBack = styled.a` + color: ${palette.solid.blue}; + transition: 0.2s ease; + + &:hover { + cursor: pointer; + opacity: 0.85; + } + + &::after { + content: "← Back"; + } +`; + +export const GoBackToReportsOverviewLink = styled(GoBack)` + &::after { + content: "← Back to Reports Overview"; + } +`; + +export const OpacityGradient = styled.div` + width: 100%; + height: 200px; + position: fixed; + bottom: 0; + left: 0; + background: linear-gradient(rgba(255, 255, 255, 0), rgba(255, 255, 255, 1)); + pointer-events: none; + + @media only screen and (max-width: ${ONE_PANEL_MAX_WIDTH}px) { + display: none; + } +`; diff --git a/publisher/src/components/Forms/Forms.test.tsx b/publisher/src/components/Forms/Forms.test.tsx new file mode 100644 index 000000000..7b3844c10 --- /dev/null +++ b/publisher/src/components/Forms/Forms.test.tsx @@ -0,0 +1,106 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { render, screen } from "@testing-library/react"; +import React from "react"; + +import { TextInput } from "."; + +test("Optional input label without value expected to be default position, font-size and color", () => { + render( + + ); + + const label = screen.getByText(/Total Staff/i); + + expect(window.getComputedStyle(label).top).toBe("26px"); + expect(window.getComputedStyle(label).fontSize).toBe("1.5rem"); + expect(window.getComputedStyle(label).color).toBe("rgba(23, 28, 43, 0.5)"); + + expect.hasAssertions(); +}); + +test("Required input label with value expected to shrink position, font-size and change color", () => { + render( + + ); + + const label = screen.getByText(/Total Staff/i); + + expect(window.getComputedStyle(label).top).toBe("12px"); + expect(window.getComputedStyle(label).fontSize).toBe("0.75rem"); + expect(window.getComputedStyle(label).color).toBe("rgb(0, 115, 229)"); + + expect.hasAssertions(); +}); + +test("Error description appears in document", () => { + render( + + ); + + const errorDescription = screen.getByText(/Please enter valid number./i); + + expect(errorDescription).toBeInTheDocument(); + + expect.hasAssertions(); +}); + +test("Error state changes text input colors to red", () => { + render( + + ); + + const input = screen.getByLabelText("Total Staff"); + + expect(window.getComputedStyle(input).background).toBe( + "rgba(221, 18, 18, 0.05)" + ); + + expect.hasAssertions(); +}); diff --git a/publisher/src/components/Forms/NotReportedIcon.tsx b/publisher/src/components/Forms/NotReportedIcon.tsx new file mode 100644 index 000000000..a16284ef2 --- /dev/null +++ b/publisher/src/components/Forms/NotReportedIcon.tsx @@ -0,0 +1,126 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { useState } from "react"; +import { useNavigate } from "react-router-dom"; +import styled from "styled-components/macro"; + +import notReportedIcon from "../assets/not-reported-icon.png"; +import { palette, typography } from "../GlobalStyles"; +import { TWO_PANEL_MAX_WIDTH } from "../Reports/ReportDataEntry.styles"; + +export const NotReportedIconWrapper = styled.div<{ + size?: number; +}>` + height: ${({ size }) => size || "23"}px; + width: ${({ size }) => size || "23"}px; + position: relative; +`; + +export const NotReportedIconImg = styled.img<{ + size?: number; + lighter?: boolean; + hasTooltip?: boolean; +}>` + width: ${({ size }) => size || "23"}px; + height: ${({ size }) => size || "23"}px; + + ${({ lighter }) => lighter && `opacity: 0.6;`}; + ${({ hasTooltip }) => + hasTooltip && + ` + &:hover { + cursor: pointer; + } + `}; +`; + +export const NotReportedIconTooltip = styled.div` + width: 267px; + position: absolute; + z-index: 2; + background: ${palette.solid.darkgrey}; + color: ${palette.solid.white}; + padding: 15px; + border-radius: 5px; + box-shadow: 0px 4px 10px ${palette.highlight.grey3}; + ${typography.sizeCSS.normal} + + @media only screen and (max-width: ${TWO_PANEL_MAX_WIDTH}px) { + width: 167px; + left: -38%; + } +`; + +export const NotReportedIconTooltipHoverArea = styled.div<{ + size?: number; +}>` + position: absolute; + top: 0px; + left: -1px; + width: 300px; + height: 200px; + padding-top: ${({ size }) => (size ? size + 5 : 27)}px; + padding-left: ${({ size }) => (size ? size + 5 : 27)}px; +`; + +export const MetricsViewLink = styled.span` + color: ${palette.solid.white}; + text-decoration: underline; + + &:hover { + cursor: pointer; + } +`; + +export const NotReportedIcon: React.FC<{ + size?: number; + lighter?: boolean; + noTooltip?: boolean; +}> = ({ size, lighter, noTooltip }) => { + const [tooltipIsVisible, setTooltipIsVisible] = useState(false); + const navigate = useNavigate(); + + const hideTooltip = () => setTooltipIsVisible(false); + const showTooltip = () => setTooltipIsVisible(true); + + return ( + + + {tooltipIsVisible && !noTooltip && ( + + + This has been disabled by an admin because the data is unavailable.{" "} + If you have the data for this, consider changing the configuration + in the{" "} + navigate("/metrics")}> + Metrics View + + . + + + )} + + ); +}; diff --git a/publisher/src/components/Forms/TabbedDisaggregations.tsx b/publisher/src/components/Forms/TabbedDisaggregations.tsx new file mode 100644 index 000000000..7e43f0a52 --- /dev/null +++ b/publisher/src/components/Forms/TabbedDisaggregations.tsx @@ -0,0 +1,271 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { useEffect, useState } from "react"; + +import { Metric as MetricType } from "../../shared/types"; +import { useStore } from "../../stores"; +import successIcon from "../assets/status-check-icon.png"; +import errorIcon from "../assets/status-error-icon.png"; +import { DisaggregationDimensionTextInput } from "../Reports/DataEntryFormComponents"; +import { + DisaggregationHasInputIndicator, + DisaggregationInputWrapper, + DisaggregationTabsContainer, + NotReportedIcon, + TabDisplay, + TabItem, + TabsRow, +} from "."; + +export const TabbedDisaggregations: React.FC<{ + metric: MetricType; + reportMetrics: MetricType[]; + reportID: number; + currentIndex: number; + disabled?: boolean; + updateFieldDescription: (title?: string, description?: string) => void; +}> = ({ + metric, + reportMetrics, + reportID, + currentIndex, + disabled, + updateFieldDescription, +}) => { + const [activeDisaggregation, setActiveDisaggregation] = useState<{ + [metricKey: string]: { + disaggregationKey: string; + disaggregationIndex: number; + hasValue?: boolean; + }; + }>({}); + const [disaggregationHasInput, setDisaggregationHasInput] = useState<{ + [disaggregationKey: string]: { + hasInput?: boolean; + }; + }>({}); + const { formStore } = useStore(); + + useEffect( + () => { + metric.disaggregations.forEach((disaggregation, index) => { + searchDimensionsForInput(disaggregation.key, index); + }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + const checkMetricForErrorsInUpdatedValues = ( + metricKey: string, + disaggregationKey: string + ) => { + let foundErrors = false; + + if ( + formStore.disaggregations?.[reportID]?.[metricKey]?.[disaggregationKey] + ) { + Object.values( + formStore.disaggregations?.[reportID]?.[metricKey]?.[disaggregationKey] + ).forEach((dimension) => { + if (dimension.error) { + foundErrors = true; + } + }); + } + + return foundErrors; + }; + + const searchDimensionsForInput = ( + disaggregationKey: string, + disaggregationIndex: number + ) => { + let inputFoundInUpdate = false; + let inputFoundFromLastSave = false; + + reportMetrics[currentIndex]?.disaggregations[ + disaggregationIndex + ]?.dimensions?.forEach((dimension) => { + const updatedDimensionValue = + formStore.disaggregations[reportID]?.[metric.key]?.[ + disaggregationKey + ]?.[dimension.key]?.value; + + if ( + dimension.value && + !inputFoundFromLastSave && + updatedDimensionValue !== "" + ) + inputFoundFromLastSave = true; + }); + + if ( + formStore.disaggregations[reportID]?.[metric.key]?.[disaggregationKey] + ) { + Object.values( + formStore.disaggregations[reportID]?.[metric.key]?.[disaggregationKey] + ).forEach((dimension) => { + if (dimension.value && !inputFoundInUpdate) inputFoundInUpdate = true; + }); + } + + if (inputFoundInUpdate || inputFoundFromLastSave) { + setDisaggregationHasInput((prev) => { + return { + ...prev, + [disaggregationKey]: { hasInput: true }, + }; + }); + } else { + setDisaggregationHasInput((prev) => { + return { + ...prev, + [disaggregationKey]: { hasInput: false }, + }; + }); + } + }; + + const updateActiveDisaggregationTab = ( + metricKey: string, + disaggregationKey: string, + disaggregationIndex: number + ) => { + searchDimensionsForInput(disaggregationKey, disaggregationIndex); + setActiveDisaggregation((prev) => ({ + ...prev, + [metricKey]: { + disaggregationKey, + disaggregationIndex, + }, + })); + }; + + const renderIcon = ( + foundError: boolean, + disaggregationEnabled: boolean | undefined, + hasInput: boolean | undefined + ) => { + if (!disaggregationEnabled) { + return ; + } + + if (foundError && disaggregationEnabled) { + return ; + } + + if (hasInput && !foundError && disaggregationEnabled) { + return ; + } + + return <>; + }; + + return ( + + + {metric.disaggregations.map((disaggregation, disaggregationIndex) => { + const foundError = checkMetricForErrorsInUpdatedValues( + metric.key, + disaggregation.key + ); + return ( + + updateActiveDisaggregationTab( + metric.key, + disaggregation.key, + disaggregationIndex + ) + } + > + {disaggregation.display_name} + + {renderIcon( + foundError, + disaggregation.enabled, + disaggregationHasInput[disaggregation.key]?.hasInput + )} + + + ); + })} + + + + {reportMetrics[currentIndex].disaggregations[ + activeDisaggregation[metric.key]?.disaggregationIndex || 0 + ]?.dimensions.map((dimension, dimensionIndex) => { + const activeDisaggregationOrZerothIndex = + activeDisaggregation[metric.key]?.disaggregationIndex || 0; + const disaggregation = + metric.disaggregations[activeDisaggregationOrZerothIndex]; + + return ( + + searchDimensionsForInput( + disaggregation.key, + activeDisaggregationOrZerothIndex + ) + } + > + + updateFieldDescription( + dimension.label, + dimension.reporting_note + ) + } + disabled={ + disabled || !disaggregation.enabled || !dimension.enabled + } + clearFieldDescription={() => updateFieldDescription(undefined)} + /> + + ); + })} + + + ); +}; diff --git a/publisher/src/components/Forms/TextInput.tsx b/publisher/src/components/Forms/TextInput.tsx new file mode 100644 index 000000000..0e1f35c93 --- /dev/null +++ b/publisher/src/components/Forms/TextInput.tsx @@ -0,0 +1,364 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { InputHTMLAttributes, useState } from "react"; +import styled from "styled-components/macro"; + +import { FormError } from "../../shared/types"; +import { rem } from "../../utils"; +import infoRedIcon from "../assets/info-red-icon.png"; +import statusCheckIcon from "../assets/status-check-icon.png"; +import statusErrorIcon from "../assets/status-error-icon.png"; +import { palette, typography } from "../GlobalStyles"; +import { NotReportedIcon } from "."; + +export const InputWrapper = styled.div` + position: relative; + display: flex; + flex-direction: column; + margin-bottom: 32px; +`; + +type InputProps = { + error?: string; + placeholder?: string; + multiline?: boolean; + persistLabel?: boolean; + notReporting?: boolean; +}; + +export const Input = styled.input` + ${typography.sizeCSS.large} + line-height: ${rem("30px")}; + resize: none; + height: ${({ multiline }) => (multiline ? "200px;" : "71px;")}; + padding: ${({ persistLabel }) => + persistLabel ? "42px 16px 16px 16px" : "16px 55px 10px 16px"}}; + background: ${({ value, error, notReporting }) => { + if (error) { + return palette.highlight.red; + } + if (notReporting) { + return palette.highlight.grey1; + } + return value || value === 0 + ? palette.highlight.lightblue1 + : palette.highlight.grey1; + }}; + ${({ notReporting }) => notReporting && `color: ${palette.highlight.grey6}`}; + + caret-color: ${({ error }) => { + if (error) { + return palette.solid.red; + } + return palette.solid.blue; + }}; + + border: none; + border-bottom: 1px solid + ${({ value, error, disabled }) => { + if (error) { + return palette.solid.red; + } + if (disabled) { + return palette.highlight.grey8; + } + return value || value === 0 + ? palette.solid.blue + : palette.highlight.grey9; + }}; + + &:hover { + border-bottom: ${({ disabled }) => + disabled ? undefined : `1px solid ${palette.solid.blue}`}; + } + + &:focus ~ label { + ${typography.sizeCSS.small} + ${({ persistLabel }) => !persistLabel && "display: none"}; + top: 12px; + color: ${({ error }) => { + if (error) { + return palette.solid.red; + } + return palette.solid.blue; + }}; + } + + &:hover ~ label { + color: ${({ error, disabled }) => + !error && !disabled && palette.solid.blue}; + } + + &::placeholder { + opacity: 0; + transition: 0.2s; + } + + &:focus::placeholder { + opacity: 1; + transition: 0.2s; + color: ${palette.highlight.grey6}; + } +`; + +type InputLabelProps = { + inputHasValue?: boolean; + isDisabled?: boolean; + error?: string; + persistLabel?: boolean; + notReporting?: boolean; +}; + +export const InputLabel = styled.label` + ${({ inputHasValue }) => + inputHasValue ? typography.sizeCSS.small : typography.sizeCSS.large} + + /* If persistLabel is false, the label is visible only when the input has no value + * If persistLabel is true, when the input has value, show the label above the value + */ + ${({ persistLabel, inputHasValue }) => + !persistLabel && inputHasValue && "display: none;"} + + min-height: 50px; + position: absolute; + top: ${({ inputHasValue }) => (inputHasValue ? "12px" : "26px")}; + left: 16px; + z-index: -1; + transition: 0.2s ease; + + color: ${({ error, isDisabled, inputHasValue, notReporting }) => { + if (error) { + return palette.solid.red; + } + if (isDisabled || notReporting) { + return palette.highlight.grey6; + } + return inputHasValue ? palette.solid.blue : palette.highlight.grey8; + }}; +`; + +type ErrorLabelProps = { + isDisabled?: boolean; + error?: string; + multiline?: boolean; +}; + +export const ErrorLabel = styled.span` + ${typography.sizeCSS.small} + ${({ error }) => error && `color: ${palette.solid.red};`}; + ${({ isDisabled }) => isDisabled && `color: ${palette.highlight.grey8};`} + margin-top: 8px; + position: absolute; + ${({ multiline }) => `top: ${multiline ? "200" : "71"}px;`}; + display: flex; + align-items: flex-start; + justify-content: flex-start; + width: 100%; +`; + +export const LabelChipPosition = styled.span` + position: absolute; + top: 24px; + right: 16px; +`; + +export const RequiredChip = styled.span` + ${typography.sizeCSS.small} + background-color: ${palette.solid.blue}; + justify-content: center; + align-items: center; + height: 24px; + padding: 4px 8px; + color: ${palette.solid.white}; + + &::after { + content: "Required"; + } +`; + +export const InputTooltip = styled.div` + position: absolute; + top: 72px; + border-radius: 4px; + padding: 16px; + background-color: ${palette.solid.darkgrey}; + color: ${palette.solid.white}; +`; + +export const ErrorIconContainer = styled.span` + transform: translate(1px, -1px); + flex-grow: 1; + z-index: 1; +`; + +export const ErrorInfo = styled.div` + position: absolute; + background-color: ${palette.solid.red}; + color: ${palette.solid.white}; + border-radius: 4px; + z-index: 1; + padding: 16px; + max-width: 300px; + bottom: 24px; +`; + +interface ErrorWithTooltipProps { + error: FormError; + disabled?: boolean; + multiline?: boolean; +} + +export const ErrorWithTooltip: React.FC = ({ + error, + disabled, + multiline, +}): JSX.Element => { + const [showErrorInfo, setShowErrorInfo] = useState(); + return ( + + {error.message} + {error?.info && ( + + setShowErrorInfo(true)} + onMouseLeave={() => setShowErrorInfo(false)} + /> + {showErrorInfo && {error.info}} + + )} + + ); +}; + +interface TextInputProps extends InputHTMLAttributes { + label: string; + error?: FormError; + valueLabel?: string; + multiline?: boolean; + persistLabel?: boolean; + metricKey?: string; + notReporting?: boolean; +} + +export const TextInput: React.FC = ({ + label, + error, + valueLabel, + multiline, + placeholder, + persistLabel, + metricKey, + notReporting, + ...props +}): JSX.Element => { + const [showTooltip, setShowTooltip] = useState(); + const { name, value, disabled } = props; + + const showTooltipIfTruncated = ( + e: React.MouseEvent + ) => { + const labelElement = e.currentTarget.querySelector("label") as HTMLElement; + if (labelElement.offsetWidth < labelElement.scrollWidth) { + setShowTooltip(true); + } + }; + const clearTooltip = () => setShowTooltip(false); + + return ( + + {/* Text Input */} + + + {/* Text Input Label (appears inside of text input) */} + + {label} + + + {showTooltip && {name}} + + {/* Error Description (appears below text input) */} + {error && ( + + )} + + {/* Label Chip (appears inside of text input on the right) */} + + {/* Chip: Required */} + {/* Disable the Required Chip for now. Refer to https://github.com/Recidiviz/recidiviz-data/pull/13849 for more information */} + {/* {required && !error && !value && ( + + + + )} */} + {/* Chip: Not Reporting Status */} + {notReporting && ( + + + + )} + + {/* Chip: Error Status */} + {error && !notReporting && ( + + + + )} + + {/* Chip: Validated Successfully Status */} + {!error && !notReporting && value && ( + + + + )} + + ); +}; diff --git a/publisher/src/components/Forms/index.ts b/publisher/src/components/Forms/index.ts new file mode 100644 index 000000000..23fbe9a3e --- /dev/null +++ b/publisher/src/components/Forms/index.ts @@ -0,0 +1,22 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./BinaryRadioButton"; +export * from "./Form.styles"; +export * from "./NotReportedIcon"; +export * from "./TabbedDisaggregations"; +export * from "./TextInput"; diff --git a/publisher/src/components/GlobalStyles/Palette.ts b/publisher/src/components/GlobalStyles/Palette.ts new file mode 100644 index 000000000..ba52dab94 --- /dev/null +++ b/publisher/src/components/GlobalStyles/Palette.ts @@ -0,0 +1,62 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export const palette = { + solid: { + red: `rgba(221, 18, 18, 1)`, + orange: `rgba(255, 128, 0, 1)`, + green: `rgba(0, 117, 64, 1)`, + lightgreen: `rgba(239, 244, 245, 1)`, + blue: `rgba(0, 115, 229, 1)`, + darkblue: `rgba(0, 86, 224, 1)`, + grey: `rgba(119, 119, 119, 1)`, + darkgrey: `rgba(23, 28, 43, 1)`, + white: `rgba(255,255,255, 1)`, + offwhite: `rgba(239, 244, 245, 1)`, + }, + highlight: { + red: `rgba(221, 18, 18, 0.05)`, + blue: `rgba(0, 115, 229, 0.1)`, + green: `rgba(0, 117, 65, 0.1)`, + lightblue1: `rgba(0, 115, 229, 0.05)`, + lightblue2: `rgba(0, 115, 229, 0.25)`, + grey1: `rgba(23, 28, 43, 0.05)`, + grey2: `rgba(23, 28, 43, 0.1)`, + grey3: `rgba(23, 28, 43, 0.15)`, + grey4: `rgba(23, 28, 43, 0.20)`, + grey5: `rgba(23, 28, 43, 0.25)`, + grey6: `rgba(23, 28, 43, 0.3)`, + grey7: `rgba(23, 28, 43, 0.4)`, + grey8: `rgba(23, 28, 43, 0.5)`, + grey9: `rgba(23, 28, 43, 0.6)`, + grey10: `rgba(23, 28, 43, 0.7)`, + grey11: `rgba(23, 28, 43, 0.8)`, + grey12: `rgba(23, 28, 43, 0.9)`, + }, + dataViz: { + bar1: "#133158", + bar2: "#5C8970", + bar3: "#D4A244", + bar4: "#6E4245", + bar5: "#BD484A", + bar6: "#353A6E", + bar7: "#BA845F", + bar8: "#64859E", + bar9: "#596041", + bar10: "#C36C3B", + }, +}; diff --git a/publisher/src/components/GlobalStyles/Typography.ts b/publisher/src/components/GlobalStyles/Typography.ts new file mode 100644 index 000000000..b027970b9 --- /dev/null +++ b/publisher/src/components/GlobalStyles/Typography.ts @@ -0,0 +1,55 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { rem } from "../../utils"; + +export const typography = { + family: "Inter", + letterSpacing: "-0.02em", + sizeCSS: { + headline: ` + font-size: ${rem("64px")}; + line-height: ${rem("64px")}; + font-weight: 500; + `, + title: ` + font-size: ${rem("32px")}; + line-height: ${rem("48px")}; + font-weight: 600; + `, + large: ` + font-size: ${rem("24px")}; + line-height: ${rem("24px")}; + font-weight: 500; + `, + medium: ` + font-size: ${rem("18px")}; + line-height: ${rem("24px")}; + font-weight: 500; + `, + normal: ` + font-size: ${rem("14px")}; + line-height: ${rem("22px")}; + font-weight: 500; + `, + small: ` + font-size: ${rem("12px")}; + line-height: ${rem("16px")}; + font-weight: 600; + `, + }, +}; diff --git a/publisher/src/components/GlobalStyles/constants.ts b/publisher/src/components/GlobalStyles/constants.ts new file mode 100644 index 000000000..eec628226 --- /dev/null +++ b/publisher/src/components/GlobalStyles/constants.ts @@ -0,0 +1,18 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export const HEADER_BAR_HEIGHT = 64; diff --git a/publisher/src/components/GlobalStyles/index.ts b/publisher/src/components/GlobalStyles/index.ts new file mode 100644 index 000000000..5b304b329 --- /dev/null +++ b/publisher/src/components/GlobalStyles/index.ts @@ -0,0 +1,20 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./constants"; +export * from "./Palette"; +export * from "./Typography"; diff --git a/publisher/src/components/Header/Header.styles.tsx b/publisher/src/components/Header/Header.styles.tsx new file mode 100644 index 000000000..1cb71ad09 --- /dev/null +++ b/publisher/src/components/Header/Header.styles.tsx @@ -0,0 +1,54 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import styled from "styled-components/macro"; + +import { HEADER_BAR_HEIGHT } from "../GlobalStyles"; +import { palette } from "../GlobalStyles/Palette"; + +export const HeaderBar = styled.header` + width: 100%; + height: ${HEADER_BAR_HEIGHT}px; + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; + z-index: 3; + background: ${palette.solid.white}; + padding: 16px 0; +`; + +export const LogoContainer = styled.div` + height: ${HEADER_BAR_HEIGHT}px; + width: ${HEADER_BAR_HEIGHT}px; + display: flex; + justify-content: center; + align-items: center; + background: ${palette.solid.green}; + transition: 0.3s ease; + + &:hover { + cursor: pointer; + opacity: 0.9; + } +`; + +export const Logo = styled.img` + width: 48px; + height: 48px; +`; diff --git a/publisher/src/components/Header/Header.tsx b/publisher/src/components/Header/Header.tsx new file mode 100644 index 000000000..a9d2adc51 --- /dev/null +++ b/publisher/src/components/Header/Header.tsx @@ -0,0 +1,39 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import { useNavigate } from "react-router-dom"; + +import logo from "../assets/jc-logo-vector.png"; +import Menu from "../Menu"; +import { HeaderBar, Logo, LogoContainer } from "."; + +const Header = () => { + const navigate = useNavigate(); + + return ( + + navigate("/")}> + + + + + + ); +}; + +export default Header; diff --git a/publisher/src/components/Header/index.ts b/publisher/src/components/Header/index.ts new file mode 100644 index 000000000..0705f0ce1 --- /dev/null +++ b/publisher/src/components/Header/index.ts @@ -0,0 +1,19 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export { default } from "./Header"; +export * from "./Header.styles"; diff --git a/publisher/src/components/Loading/Loading.tsx b/publisher/src/components/Loading/Loading.tsx new file mode 100644 index 000000000..05cb7d487 --- /dev/null +++ b/publisher/src/components/Loading/Loading.tsx @@ -0,0 +1,60 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import styled, { keyframes } from "styled-components/macro"; + +import sprite from "../assets/loader-sprite-horizontal.svg"; + +const loaderWidth = 144; +const spriteFrames = 104; + +const LoadingWrapper = styled.div` + height: 100vh; + width: 100vw; + display: flex; + justify-content: center; + align-items: center; + position: absolute; + top: 0; + left: 0; +`; + +const loadingSpriteAnimation = keyframes` + to { + background-position: -${loaderWidth * spriteFrames}px 0px; + } +`; + +const Loader = styled.div` + height: ${loaderWidth}px; + width: ${loaderWidth}px; + background-image: url(${sprite}); + background-repeat: no-repeat; + background-size: ${loaderWidth * spriteFrames}px ${loaderWidth}px; + background-position: 0px 0px; + animation: ${loadingSpriteAnimation} 1.5s steps(${spriteFrames}) infinite + alternate; +`; + +export const Loading = () => { + return ( + + + + ); +}; diff --git a/publisher/src/components/Loading/MiniLoader.tsx b/publisher/src/components/Loading/MiniLoader.tsx new file mode 100644 index 000000000..30b94b8c0 --- /dev/null +++ b/publisher/src/components/Loading/MiniLoader.tsx @@ -0,0 +1,88 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= +import React from "react"; +import styled, { keyframes } from "styled-components/macro"; + +const dotLoopAnimation = keyframes` + 0% { + transform: rotate(0); + } + 100% { + transform: rotate(360deg); + } +`; + +export const SVGContainer = styled.div` + height: 100%; + margin-left: 5px; +`; + +export const AnimatedSVGGroup = styled.g` + transform-origin: 8px 8px; + animation: ${dotLoopAnimation} 0.8s infinite steps(8, start); +`; + +export const MiniLoader: React.FC = () => { + return ( + + + dots anim + + + + + + + + + + + + + + + ); +}; diff --git a/publisher/src/components/Loading/index.ts b/publisher/src/components/Loading/index.ts new file mode 100644 index 000000000..829b62965 --- /dev/null +++ b/publisher/src/components/Loading/index.ts @@ -0,0 +1,18 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./Loading"; diff --git a/publisher/src/components/Menu/Menu.styles.tsx b/publisher/src/components/Menu/Menu.styles.tsx new file mode 100644 index 000000000..61fa095e8 --- /dev/null +++ b/publisher/src/components/Menu/Menu.styles.tsx @@ -0,0 +1,140 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= +import { DropdownMenuItem, DropdownToggle } from "@recidiviz/design-system"; +import styled from "styled-components/macro"; + +import { HEADER_BAR_HEIGHT, palette, typography } from "../GlobalStyles"; +import { ONE_PANEL_MAX_WIDTH } from "../Reports/ReportDataEntry.styles"; + +export const MenuContainer = styled.nav` + font-family: ${typography.family}; + ${typography.sizeCSS.normal} + display: flex; + align-items: center; + padding: 0 24px; + gap: 24px; +`; + +export const MenuItem = styled.div<{ + active?: boolean; + highlight?: boolean; + buttonPadding?: boolean; +}>` + height: ${HEADER_BAR_HEIGHT}px; + padding-top: ${({ buttonPadding }) => (buttonPadding ? `5px` : `14px`)}; + border-top: 6px solid + ${({ active }) => (active ? palette.solid.blue : "transparent")}; + transition: 0.2s ease; + color: ${({ highlight }) => + highlight ? palette.solid.red : palette.solid.darkgrey}; + + a, + a:visited { + color: ${palette.solid.darkgrey}; + text-decoration: none; + transition: 0.2s ease; + } + + &:hover, + a:hover { + cursor: pointer; + color: ${palette.solid.blue}; + } +`; + +export const WelcomeUser = styled.div` + color: ${palette.highlight.grey8}; + border-right: 1px solid black; + padding-right: 24px; + + @media only screen and (max-width: ${ONE_PANEL_MAX_WIDTH}px) { + display: none; + } +`; + +export const ExtendedDropdownToggle = styled(DropdownToggle)<{ + noMargin?: boolean; +}>` + font-family: ${typography.family}; + ${typography.sizeCSS.normal} + padding: 0; + min-height: unset; + line-height: 0; + margin-bottom: ${({ noMargin }) => (noMargin ? "0" : "22px")}; + color: ${palette.solid.darkgrey}; + + &[aria-expanded="true"] { + color: ${palette.solid.blue}; + } + + &:hover { + color: ${palette.solid.blue}; + } + + &:focus { + color: ${palette.solid.darkgrey}; + } +`; + +export const ExtendedDropdownMenuItem = styled(DropdownMenuItem)<{ + highlight?: boolean; + noPadding?: boolean; +}>` + min-width: 264px; + display: flex; + align-items: center; + font-family: ${typography.family}; + ${typography.sizeCSS.normal} + color: ${({ highlight }) => + highlight ? palette.solid.red : palette.solid.darkgrey}; + height: auto; + padding: 0; + gap: 8px; + + ${({ noPadding }) => + !noPadding && + ` + padding: 16px; + + &:first-child { + padding: 10px 16px 16px 16px; + } + + &:last-child { + padding: 16px 16px 10px 16px; + } + `} + + &:not(:last-child) { + border-bottom: 1px solid ${palette.solid.offwhite}; + } + + &:focus { + background-color: transparent; + color: ${({ highlight }) => + highlight ? palette.solid.red : palette.solid.darkgrey}; + } + + &:hover { + color: ${palette.solid.blue}; + background-color: transparent; + + svg path { + stroke: ${palette.solid.blue}; + } + } +`; diff --git a/publisher/src/components/Menu/Menu.tsx b/publisher/src/components/Menu/Menu.tsx new file mode 100644 index 000000000..92715cc94 --- /dev/null +++ b/publisher/src/components/Menu/Menu.tsx @@ -0,0 +1,169 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= +import { Dropdown, DropdownMenu } from "@recidiviz/design-system"; +import { observer } from "mobx-react-lite"; +import React, { useEffect, useState } from "react"; +import { useLocation, useNavigate } from "react-router-dom"; + +import { Permission } from "../../shared/types"; +import { useStore } from "../../stores"; +import { Button } from "../DataUpload"; +import { + ExtendedDropdownMenuItem, + ExtendedDropdownToggle, + MenuContainer, + MenuItem, + WelcomeUser, +} from "."; + +enum MenuItems { + Reports = "REPORTS", + CreateReport = "CREATE REPORT", + LearnMore = "LEARN MORE", + Settings = "SETTINGS", + Agencies = "AGENCIES", + Metrics = "METRICS", +} + +const Menu = () => { + const [activeMenuItem, setActiveMenuItem] = useState( + MenuItems.Reports + ); + const { authStore, api, userStore } = useStore(); + const navigate = useNavigate(); + const location = useLocation(); + + const logout = async (): Promise => { + try { + const response = (await api.request({ + path: "/auth/logout", + method: "POST", + })) as Response; + + if (response.status === 200 && authStore) { + return authStore.logoutUser(); + } + + return Promise.reject( + new Error( + "Something went wrong with clearing auth session or authStore is not initialized." + ) + ); + } catch (error) { + if (error instanceof Error) return error.message; + return String(error); + } + }; + + useEffect(() => { + if (location.pathname === "/") { + setActiveMenuItem(MenuItems.Reports); + } else if (location.pathname === "/reports/create") { + setActiveMenuItem(MenuItems.CreateReport); + } else if (location.pathname === "/settings") { + setActiveMenuItem(MenuItems.Settings); + } else if (location.pathname === "/metrics") { + setActiveMenuItem(MenuItems.Metrics); + } else { + setActiveMenuItem(undefined); + } + }, [location]); + + return ( + + + {userStore.nameOrEmail && + userStore.currentAgency?.name && + `Welcome, ${userStore.nameOrEmail} at ${userStore.currentAgency.name}`} + + + {/* Metrics View */} + navigate("/metrics")} + active={activeMenuItem === MenuItems.Metrics} + > + Metrics + + + {/* Reports */} + navigate("/")} + active={activeMenuItem === MenuItems.Reports} + > + Reports + + + {/* Learn More */} + + + Learn More + + + + {/* Agencies Dropdown */} + {(userStore.permissions.includes(Permission.RECIDIVIZ_ADMIN) || + userStore.permissions.includes(Permission.SWITCH_AGENCIES)) && ( + + + + Agencies + + + {userStore.userAgencies?.map((agency) => { + return ( + { + userStore.setCurrentAgencyId(agency.id); + }} + highlight={userStore.currentAgency?.id === agency.id} + > + {agency.name} + + ); + })} + + + + )} + + {/* Settings */} + navigate("/settings")} + active={activeMenuItem === MenuItems.Settings} + > + Settings + + + + Log Out + + + + + + + ); +}; + +export default observer(Menu); diff --git a/publisher/src/components/Menu/index.ts b/publisher/src/components/Menu/index.ts new file mode 100644 index 000000000..cdc66154b --- /dev/null +++ b/publisher/src/components/Menu/index.ts @@ -0,0 +1,19 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export { default } from "./Menu"; +export * from "./Menu.styles"; diff --git a/publisher/src/components/MetricsView/MetricsView.styles.tsx b/publisher/src/components/MetricsView/MetricsView.styles.tsx new file mode 100644 index 000000000..dc4144466 --- /dev/null +++ b/publisher/src/components/MetricsView/MetricsView.styles.tsx @@ -0,0 +1,330 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import styled from "styled-components/macro"; + +import { BinaryRadioGroupWrapper } from "../Forms"; +import { palette, typography } from "../GlobalStyles"; + +export const MetricsViewContainer = styled.div` + width: 100%; + display: flex; + flex-direction: column; + align-items: flex-start; +`; + +export const MetricsViewControlPanel = styled.div` + height: calc(100% - 170px); + width: 100%; + display: flex; + justify-content: space-between; +`; + +export const PanelContainerLeft = styled.div` + width: 35%; + height: 100%; + overflow: scroll; + padding: 10px 15px 0 15px; + + @media only screen and (max-width: 1000px) { + margin-right: 50px; + } +`; + +export const PanelContainerRight = styled.div` + width: 65%; + height: 100%; + display: flex; + position: relative; + flex-direction: column; +`; + +type MetricBoxContainerProps = { + enabled?: boolean; + selected?: boolean; +}; + +export const MetricBoxContainer = styled.div` + display: flex; + flex-direction: column; + border: 1px solid + ${({ selected }) => + selected ? palette.solid.blue : palette.highlight.grey2}; + border-radius: 12px; + padding: 15px; + margin-bottom: 11px; + transition: 0.2s ease; + color: ${({ enabled }) => + enabled ? palette.solid.darkgrey : palette.highlight.grey7}; + ${({ selected }) => + selected && `box-shadow: 0px 4px 10px ${palette.highlight.blue};`} + + &:hover { + cursor: pointer; + ${({ selected }) => + !selected && `border: 1px solid ${palette.highlight.lightblue2}`}; + } +`; + +export const MetricBoxWrapper = styled.div` + display: block; +`; + +export const ActiveMetricSettingHeader = styled.div` + position: relative; + z-index: 1; + background: ${palette.solid.white}; + padding: 10px 15px 0 15px; +`; + +export const MetricNameBadgeToggleWrapper = styled.div` + display: flex; + justify-content: space-between; + margin-bottom: 8px; +`; + +export const MetricNameBadgeWrapper = styled.div` + display: flex; + align-items: center; +`; + +type MetricNameProps = { isTitle?: boolean }; + +export const MetricName = styled.div` + ${({ isTitle }) => + isTitle ? typography.sizeCSS.title : typography.sizeCSS.medium} +`; + +export const MetricDescription = styled.div` + ${typography.sizeCSS.normal} + color: ${palette.highlight.grey9}; + + @media only screen and (max-width: 1000px) { + ${typography.sizeCSS.small} + } +`; + +export const MetricDetailsDisplay = styled.div` + width: 100%; + overflow-y: scroll; + padding: 24px 15px 0 15px; +`; + +export const MetricOnOffWrapper = styled.div` + margin-bottom: 49px; +`; + +export const Header = styled.div` + ${typography.sizeCSS.medium}; + margin-bottom: 16px; +`; + +export const Subheader = styled.div` + ${typography.sizeCSS.normal}; + color: ${palette.highlight.grey9}; + margin-bottom: 9px; +`; + +export const RadioButtonGroupWrapper = styled(BinaryRadioGroupWrapper)` + display: flex; +`; + +export const MetricDisaggregations = styled.div<{ enabled?: boolean }>` + display: block; + position: relative; + + ${({ enabled }) => + !enabled && + ` + &::after { + content: ''; + position: absolute; + background: ${palette.solid.white}; + height: 100%; + width: 100%; + top: 0; + opacity: 0.5; + } + `} +`; + +export const Disaggregation = styled.div` + display: block; + margin-bottom: 15px; +`; + +export const DisaggregationHeader = styled.div` + display: flex; + justify-content: space-between; + padding: 17px 0; + align-items: center; + + border-bottom: 1px solid ${palette.highlight.grey9}; +`; + +export const DisaggregationName = styled.div<{ enabled?: boolean }>` + ${typography.sizeCSS.large}; + + color: ${({ enabled }) => + enabled ? palette.solid.darkgrey : palette.highlight.grey8}; +`; + +export const Dimension = styled.div<{ enabled?: boolean }>` + ${typography.sizeCSS.medium}; + display: flex; + align-items: center; + justify-content: space-between; + padding: 8px 0; + border-bottom: 1px dashed ${palette.highlight.grey9}; + position: relative; + + &:last-child { + border-bottom: none; + } + + ${({ enabled }) => + !enabled && + ` + &::after { + content: ''; + position: absolute; + background: ${palette.solid.white}; + height: 100%; + width: 100%; + top: 0; + opacity: 0.5; + } + `} +`; + +export const DimensionTitleWrapper = styled.div` + display: flex; + align-items: center; +`; + +export const DimensionTitle = styled.div<{ enabled?: boolean }>` + display: block; + color: ${({ enabled }) => + enabled ? palette.solid.darkgrey : palette.highlight.grey8}; +`; + +export const MetricConfigurationContainer = styled.div` + display: block; +`; + +export const MetricContextContainer = styled.div` + display: block; +`; + +export const MetricContextItem = styled.div` + margin-top: 33px; +`; + +export const Label = styled.div<{ noBottomMargin?: boolean }>` + ${typography.sizeCSS.medium}; + margin-bottom: ${({ noBottomMargin }) => (noBottomMargin ? 0 : `16px`)}; +`; + +export const ToggleSwitchWrapper = styled.div` + display: flex; + align-items: center; + padding: 8px 0; +`; + +export const ToggleSwitch = styled.label` + position: relative; + display: inline-block; + width: 38px; + height: 24px; +`; + +export const ToggleSwitchInput = styled.input` + opacity: 0; + width: 0; + height: 0; + + &:checked + span { + background-color: ${palette.solid.blue}; + } + + &:checked + span:before { + transform: translateX(14px); + } +`; + +export const Slider = styled.span` + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: ${palette.solid.grey}; + border-radius: 34px; + transition: 0.3s; + + &:before { + content: ""; + height: 14px; + width: 14px; + position: absolute; + left: 5px; + bottom: 5px; + background-color: ${palette.solid.white}; + border-radius: 50%; + transition: 0.3s; + } +`; + +export const ToggleSwitchLabel = styled.span<{ switchedOn?: boolean }>` + ${typography.sizeCSS.normal} + color: ${({ switchedOn }) => + switchedOn ? palette.solid.blue : palette.solid.grey}; + text-transform: uppercase; + margin-right: 11px; + position: relative; + + &::after { + content: "${({ switchedOn }) => (switchedOn ? "ON" : "OFF")}"; + position: absolute; + top: -11px; + left: -27px; + } +`; + +export const MultipleChoiceWrapper = styled.div` + display: flex; + flex-wrap: wrap; + justify-content: space-between; + + div { + &:nth-child(odd) { + margin: 15px 10px 0 0; + } + + width: 90%; + flex: 40%; + } +`; + +export const MetricSettingsDisplayError = styled.div` + width: 100%; + height: 100%; + display: flex; + justify-content: center; + margin-top: 50px; +`; diff --git a/publisher/src/components/MetricsView/MetricsView.tsx b/publisher/src/components/MetricsView/MetricsView.tsx new file mode 100644 index 000000000..731a3a01d --- /dev/null +++ b/publisher/src/components/MetricsView/MetricsView.tsx @@ -0,0 +1,959 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { debounce as _debounce } from "lodash"; +import { reaction, when } from "mobx"; +import { observer } from "mobx-react-lite"; +import React, { useEffect, useRef, useState } from "react"; + +import { AgencySystems, FormError, ReportFrequency } from "../../shared/types"; +import { useStore } from "../../stores"; +import { + isPositiveNumber, + removeCommaSpaceAndTrim, + removeSnakeCase, +} from "../../utils"; +import { Badge, BadgeColorMapping } from "../Badge"; +import DatapointsView from "../DataViz/DatapointsView"; +import { + BinaryRadioButton, + BinaryRadioGroupClearButton, + BinaryRadioGroupContainer, + BinaryRadioGroupQuestion, + NotReportedIcon, + TextInput, +} from "../Forms"; +import { Loading } from "../Loading"; +import { PageTitle, TabbedBar, TabbedItem, TabbedOptions } from "../Reports"; +import { showToast } from "../Toast"; +import { + ActiveMetricSettingHeader, + Dimension, + DimensionTitle, + DimensionTitleWrapper, + Disaggregation, + DisaggregationHeader, + DisaggregationName, + Header, + Label, + MetricBoxContainer, + MetricBoxWrapper, + MetricConfigurationContainer, + MetricContextContainer, + MetricContextItem, + MetricDescription, + MetricDetailsDisplay, + MetricDisaggregations, + MetricName, + MetricNameBadgeToggleWrapper, + MetricNameBadgeWrapper, + MetricOnOffWrapper, + MetricsViewContainer, + MetricsViewControlPanel, + MultipleChoiceWrapper, + PanelContainerLeft, + PanelContainerRight, + RadioButtonGroupWrapper, + Slider, + Subheader, + ToggleSwitch, + ToggleSwitchInput, + ToggleSwitchLabel, + ToggleSwitchWrapper, +} from "."; + +type MetricsViewMetric = { + key: string; + display_name: string; + description: string; + frequency: string; + enabled: boolean; + system: AgencySystems; + contexts: { + key: string; + display_name: string; + reporting_note: string; + required: boolean; + type: string; + value: string | null; + multiple_choice_options?: string[]; + }[]; + disaggregations: { + key: string; + display_name: string; + enabled: boolean; + dimensions: { + key: string; + label: string; + reporting_note: string; + enabled: boolean; + }[]; + }[]; +}; + +type MetricBoxProps = { + metricKey: string; + displayName: string; + frequency: ReportFrequency; + description: string; + enabled?: boolean; + activeMetricKey: string; + setActiveMetricKey: React.Dispatch>; +}; + +const reportFrequencyBadgeColors: BadgeColorMapping = { + ANNUAL: "ORANGE", + MONTHLY: "GREEN", +}; + +const MetricBox: React.FC = ({ + metricKey, + displayName, + frequency, + description, + enabled, + activeMetricKey, + setActiveMetricKey, +}): JSX.Element => { + return ( + setActiveMetricKey(metricKey)} + enabled={enabled} + selected={metricKey === activeMetricKey} + > + + + {displayName} + + {frequency} + + + + {!enabled && } + + + {description} + + ); +}; + +type MetricConfigurationProps = { + activeMetricKey: string; + metricSettings: { [key: string]: MetricsViewMetric }; + saveAndUpdateMetricSettings: ( + typeOfUpdate: "METRIC" | "DISAGGREGATION" | "DIMENSION" | "CONTEXT", + updatedSetting: MetricSettings, + debounce?: boolean + ) => void; +}; + +const MetricConfiguration: React.FC = ({ + activeMetricKey, + metricSettings, + saveAndUpdateMetricSettings, +}): JSX.Element => { + const metricDisplayName = metricSettings[activeMetricKey]?.display_name; + const metricEnabled = Boolean(metricSettings[activeMetricKey]?.enabled); + + return ( + + +
+ Are you currently able to report any part of this metric? +
+ + Answering “No” means that {metricDisplayName} will not appear on + automatically generated reports from here on out. You can change this + later. + + + + saveAndUpdateMetricSettings("METRIC", { + key: activeMetricKey, + enabled: true, + }) + } + /> + + saveAndUpdateMetricSettings("METRIC", { + key: activeMetricKey, + enabled: false, + }) + } + /> + +
+ + + {metricSettings[activeMetricKey]?.disaggregations.length > 0 && ( + <> +
Breakdowns
+ + Turning any of these breakdowns “Off” means that they will not + appear on automatically generated reports from here on out. You + can change this later. + + + )} + + {metricSettings[activeMetricKey]?.disaggregations?.map( + (disaggregation) => { + return ( + + + + {disaggregation.display_name} + + + + + + + saveAndUpdateMetricSettings("DISAGGREGATION", { + key: activeMetricKey, + disaggregations: [ + { + key: disaggregation.key, + enabled: !disaggregation.enabled, + }, + ], + }) + } + /> + + + + + + {disaggregation?.dimensions.map((dimension) => { + return ( + + + + {dimension.label} + + + + + + + { + if (disaggregation.enabled) { + saveAndUpdateMetricSettings("DIMENSION", { + key: activeMetricKey, + disaggregations: [ + { + key: disaggregation.key, + dimensions: [ + { + key: dimension.key, + enabled: !dimension.enabled, + }, + ], + }, + ], + }); + } + }} + /> + + + + + ); + })} + + ); + } + )} +
+
+ ); +}; + +type MetricSettingsUpdateOptions = + | "METRIC" + | "DISAGGREGATION" + | "DIMENSION" + | "CONTEXT"; + +type MetricContextConfigurationProps = { + metricKey: string; + contexts: { + key: string; + display_name: string; + reporting_note: string; + required: boolean; + type: string; + value: string | null; + multiple_choice_options?: string[]; + }[]; + saveAndUpdateMetricSettings: ( + typeOfUpdate: MetricSettingsUpdateOptions, + updatedSetting: MetricSettings, + debounce?: boolean + ) => void; +}; + +const MetricContextConfiguration: React.FC = ({ + metricKey, + contexts, + saveAndUpdateMetricSettings, +}) => { + const [contextErrors, setContextErrors] = useState<{ + [key: string]: FormError; + }>(); + + const contextNumberValidation = (key: string, value: string) => { + const cleanValue = removeCommaSpaceAndTrim(value); + + if (!isPositiveNumber(cleanValue) && cleanValue !== "") { + setContextErrors({ + [key]: { + message: "Please enter a valid number.", + }, + }); + + return false; + } + + setContextErrors((prev) => { + const otherContextErrors = { ...prev }; + delete otherContextErrors[key]; + + return otherContextErrors; + }); + return true; + }; + + useEffect(() => { + contexts.forEach((context) => { + if (context.type === "NUMBER") { + contextNumberValidation(context.key, context.value || ""); + } + }); + }, [contexts]); + + return ( + + + Anything entered here will appear as the default value for all reports. + If you are entering data for a particular month, you can still replace + this as necessary. + + + {contexts?.map((context) => ( + + {context.type === "BOOLEAN" && ( + <> + + + + saveAndUpdateMetricSettings("CONTEXT", { + key: metricKey, + contexts: [{ key: context.key, value: "yes" }], + }) + } + /> + + saveAndUpdateMetricSettings("CONTEXT", { + key: metricKey, + contexts: [{ key: context.key, value: "no" }], + }) + } + /> + + + saveAndUpdateMetricSettings("CONTEXT", { + key: metricKey, + contexts: [{ key: context.key, value: "" }], + }) + } + > + Clear Input + + + )} + + {(context.type === "TEXT" || context.type === "NUMBER") && ( + <> + + { + if (context.type === "NUMBER") { + contextNumberValidation(context.key, e.currentTarget.value); + } + + saveAndUpdateMetricSettings( + "CONTEXT", + { + key: metricKey, + contexts: [ + { key: context.key, value: e.currentTarget.value }, + ], + }, + true + ); + }} + /> + + )} + + {context.type === "MULTIPLE_CHOICE" && ( + + + {context.display_name} + + + + {context.multiple_choice_options?.map((option) => ( + + saveAndUpdateMetricSettings("CONTEXT", { + key: metricKey, + contexts: [{ key: context.key, value: option }], + }) + } + /> + ))} + + + saveAndUpdateMetricSettings("CONTEXT", { + key: metricKey, + contexts: [{ key: context.key, value: "" }], + }) + } + > + Clear Input + + + )} + + ))} + + ); +}; + +export type MetricSettings = { + key: string; + enabled?: boolean; + contexts?: { + key: string; + value: string; + }[]; + disaggregations?: { + key: string; + enabled?: boolean; + dimensions?: { + key: string; + enabled: boolean; + }[]; + }[]; +}; + +export const MetricsView: React.FC = observer(() => { + const { reportStore, userStore, datapointsStore } = useStore(); + const configPanelRef = useRef(null); + + // TODO(#13805) Temporarily hiding the data tab until it is implemented. Currently it's only visible to Recidiviz admins. + const configSections = ["Data", "Configuration", "Context"]; + type ConfigSections = typeof configSections[number]; + + const [activeMetricFilter, setActiveMetricFilter] = useState(); + + const [activeConfigSection, setActiveConfigSection] = + useState("Data"); + + const [isLoading, setIsLoading] = useState(true); + + const [loadingError, setLoadingError] = useState( + undefined + ); + + const [activeMetricKey, setActiveMetricKey] = useState(""); + + const [metricSettings, setMetricSettings] = useState<{ + [key: string]: MetricsViewMetric; + }>({}); + + const [filteredMetricSettings, setFilteredMetricSettings] = useState<{ + [key: string]: MetricsViewMetric; + }>({}); + + const updateMetricSettings = ( + typeOfUpdate: MetricSettingsUpdateOptions, + updatedSetting: MetricSettings + ) => { + setMetricSettings((prev) => { + const metricKey = updatedSetting.key; + + if (typeOfUpdate === "METRIC") { + return { + ...prev, + [updatedSetting.key]: { + ...prev[metricKey], + enabled: Boolean(updatedSetting.enabled), + }, + }; + } + + if (typeOfUpdate === "DISAGGREGATION") { + const updatedDisaggregations = prev[metricKey].disaggregations.map( + (disaggregation) => { + /** Quick Note: for now, all updates happen one at a time thus leaving + * one item in the disaggregations/dimensions/contexts arrays that will + * be updated at any one time. We can update this in the future to handle + * updating multiple settings at one time if necessary. + */ + if ( + disaggregation.key === updatedSetting.disaggregations?.[0].key + ) { + /** + * When disaggregation is switched off, all dimensions are disabled. + * When disaggregation is switched on, all dimensions are enabled. + */ + if (!updatedSetting.disaggregations?.[0].enabled) { + return { + ...disaggregation, + enabled: false, + dimensions: disaggregation.dimensions.map((dimension) => { + return { + ...dimension, + enabled: false, + }; + }), + }; + } + return { + ...disaggregation, + enabled: Boolean(updatedSetting.disaggregations?.[0].enabled), + dimensions: disaggregation.dimensions.map((dimension) => { + return { + ...dimension, + enabled: true, + }; + }), + }; + } + return disaggregation; + } + ); + + return { + ...prev, + [updatedSetting.key]: { + ...prev[metricKey], + disaggregations: updatedDisaggregations, + }, + }; + } + + if (typeOfUpdate === "DIMENSION") { + const updatedDisaggregations = prev[metricKey].disaggregations.map( + (disaggregation) => { + if ( + disaggregation.key === updatedSetting.disaggregations?.[0].key + ) { + const lastDimensionDisabled = + disaggregation.dimensions.filter( + (dimension) => dimension.enabled + )?.length === 1; + + /** Disable disaggregation when last dimension toggle is switched off */ + if ( + !updatedSetting.disaggregations?.[0].dimensions?.[0].enabled && + lastDimensionDisabled + ) { + return { + ...disaggregation, + enabled: false, + dimensions: disaggregation.dimensions.map((dimension) => { + if ( + dimension.key === + updatedSetting.disaggregations?.[0].dimensions?.[0].key + ) { + return { + ...dimension, + enabled: Boolean( + updatedSetting.disaggregations?.[0].dimensions?.[0] + .enabled + ), + }; + } + return dimension; + }), + }; + } + + return { + ...disaggregation, + dimensions: disaggregation.dimensions.map((dimension) => { + if ( + dimension.key === + updatedSetting.disaggregations?.[0].dimensions?.[0].key + ) { + return { + ...dimension, + enabled: Boolean( + updatedSetting.disaggregations?.[0].dimensions?.[0] + .enabled + ), + }; + } + return dimension; + }), + }; + } + return disaggregation; + } + ); + + return { + ...prev, + [updatedSetting.key]: { + ...prev[metricKey], + disaggregations: updatedDisaggregations, + }, + }; + } + + if (typeOfUpdate === "CONTEXT") { + const updatedContext = prev[metricKey].contexts.map((context) => { + if (context.key === updatedSetting.contexts?.[0].key) { + return { + ...context, + value: updatedSetting.contexts?.[0].value, + }; + } + return context; + }); + + return { + ...prev, + [updatedSetting.key]: { + ...prev[metricKey], + contexts: updatedContext, + }, + }; + } + + return prev; + }); + }; + + const saveMetricSettings = async (updatedSetting: MetricSettings) => { + const response = (await reportStore.updateReportSettings([ + updatedSetting, + ])) as Response; + + if (response.status === 200) { + showToast(`Settings saved.`, true, "grey", 4000); + } else { + showToast(`Failed to save.`, true, "red", 4000); + } + }; + + const debouncedSave = useRef(_debounce(saveMetricSettings, 1500)).current; + + const saveAndUpdateMetricSettings = ( + typeOfUpdate: MetricSettingsUpdateOptions, + updatedSetting: MetricSettings, + debounce?: boolean + ) => { + updateMetricSettings(typeOfUpdate, updatedSetting); + if (debounce) { + debouncedSave(updatedSetting); + } else { + saveMetricSettings(updatedSetting); + } + }; + + const fetchAndSetReportSettings = async () => { + const response = (await reportStore.getReportSettings()) as + | Response + | Error; + + setIsLoading(false); + + if (response instanceof Error) { + return setLoadingError(response.message); + } + + const reportSettings = (await response.json()) as MetricsViewMetric[]; + const metricKeyToMetricMap: { [key: string]: MetricsViewMetric } = {}; + + reportSettings?.forEach((metric) => { + metricKeyToMetricMap[metric.key] = metric; + }); + + setMetricSettings(metricKeyToMetricMap); + setActiveMetricKey(Object.keys(metricKeyToMetricMap)[0]); + }; + + useEffect( + () => + // return when's disposer so it is cleaned up if it never runs + when( + () => userStore.userInfoLoaded, + async () => { + fetchAndSetReportSettings(); + + datapointsStore.getDatapoints(); + setActiveMetricFilter( + removeSnakeCase(userStore.currentAgency?.systems[0] as string) + ); + } + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + // reload report overviews when the current agency ID changes + useEffect( + () => + // return disposer so it is cleaned up if it never runs + reaction( + () => userStore.currentAgencyId, + async (currentAgencyId, previousAgencyId) => { + // prevents us from calling getReportOverviews twice on initial load + if (previousAgencyId !== undefined) { + setIsLoading(true); + fetchAndSetReportSettings(); + datapointsStore.resetState(); + await datapointsStore.getDatapoints(); + setActiveMetricFilter( + removeSnakeCase(userStore.currentAgency?.systems[0] as string) + ); + } + } + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [userStore] + ); + + useEffect(() => { + const filteredMetricKeyToMetricMap: { [key: string]: MetricsViewMetric } = + {}; + + Object.values(metricSettings) + .filter( + (metric) => + metric.system.toLowerCase() === activeMetricFilter?.toLowerCase() + ) + ?.forEach((metric) => { + filteredMetricKeyToMetricMap[metric.key] = metric; + }); + + return setFilteredMetricSettings(filteredMetricKeyToMetricMap); + }, [metricSettings, activeMetricFilter]); + + if (isLoading) { + return ; + } + + if (!metricSettings[activeMetricKey]) { + return
Error: {loadingError}
; + } + + return ( + <> + + Metrics + + + + {userStore.currentAgency?.systems.map((filterOption) => ( + + setActiveMetricFilter(removeSnakeCase(filterOption)) + } + capitalize + > + {removeSnakeCase(filterOption.toLowerCase())} + + ))} + + + + + {/* List Of Metrics */} + + {filteredMetricSettings && + Object.values(filteredMetricSettings).map((metric) => ( + { + if (configPanelRef.current) { + configPanelRef.current.scrollTo({ + top: 0, + behavior: "smooth", + }); + } + }} + > + + + ))} + + + {/* Data | Configuration | Context */} + + + + + {metricSettings[activeMetricKey]?.display_name} + + + {metricSettings[activeMetricKey]?.frequency} + + + + + + {configSections.map((section) => ( + { + setActiveConfigSection(section); + if (configPanelRef.current) { + configPanelRef.current.scrollTo({ + top: 0, + behavior: "smooth", + }); + } + }} + > + {section} + + ))} + + + + + {/* Data */} + {activeConfigSection === "Data" && ( + + )} + + {/* Configuration */} + {activeConfigSection === "Configuration" && ( + + + + )} + + {/* Context */} + {activeConfigSection === "Context" && ( + + + + )} + + + + + ); +}); diff --git a/publisher/src/components/MetricsView/MetricsViewMocks.ts b/publisher/src/components/MetricsView/MetricsViewMocks.ts new file mode 100644 index 000000000..02dfe368a --- /dev/null +++ b/publisher/src/components/MetricsView/MetricsViewMocks.ts @@ -0,0 +1,163 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export const metricsViewMockResponse = [ + { + key: "LAW_ENFORCEMENT_BUDGET__metric/law_enforcement/budget/type", + display_name: "Annual Budget", + description: "Measures the total annual budget (in dollars) of the agency.", + frequency: "ANNUAL", + enabled: true, + contexts: [ + { + key: "PRIMARY_FUNDING_SOURCE", + display_name: "Binary question?", + reporting_note: "put your primary funding source here", + required: false, + type: "BOOLEAN", + value: "government funding", + }, + { + key: "PRIMARY_FUNDING_SOURCE2", + display_name: "Multiple choice", + reporting_note: "put your primary funding source here", + required: false, + type: "MULTIPLE_CHOICE", + multiple_choice_options: [ + "Choice 1", + "Choice 2", + "Choice 3", + "Choice 4", + ], + value: "government funding", + }, + { + key: "ADDITIONAL_CONTEXT", + display_name: "Additional context", + reporting_note: "Any additional context you want to provide", + required: false, + type: "TEXT", + value: "we are special, here's why", + }, + ], + disaggregations: [ + { + key: "law_enforcement/staff/type", + display_name: "Staff Types", + enabled: false, + dimensions: [ + { + key: "SUPPORT", + label: "Support", + reporting_note: "Staff: Support", + enabled: false, + }, + { + key: "SECURITY", + label: "Security", + reporting_note: "Staff: Security", + enabled: true, + }, + ], + }, + ], + }, + { + key: "READMISSION_RATE", + display_name: "Readmission Rate", + description: + "Measure the number of individuals admitted who had at least one other prison admission within the prior year.", + frequency: "MONTHLY", + enabled: false, + contexts: [ + { + key: "DEFINITION_OF_READMISSION", + display_name: "Definition of Readmission", + reporting_note: "Agency's definition of readmission.", + required: false, + type: "NUMBER", + value: null, + }, + { + key: "ADDITIONAL_CONTEXT", + display_name: "Additional Context", + reporting_note: + "Add any additional context that you would like to provide here.", + required: false, + type: "TEXT", + value: null, + }, + ], + disaggregations: [ + { + key: "READMISSION_KEY_TYPE", + display_name: "Readmission Types", + enabled: true, + dimensions: [ + { + key: "NEW_OFFENSE", + label: "New Offense", + reporting_note: "Readmission: New Offense", + enabled: true, + }, + { + key: "VIOLATION_OF_CONDITIONS", + label: "Violation of Conditions", + reporting_note: "Readmission: Violation of Conditions", + enabled: true, + }, + { + key: "OTHER", + label: "Other", + reporting_note: "Readmission: Other", + enabled: true, + }, + { + key: "UNKNOWN", + label: "Unknown", + reporting_note: "Readmission: Unknown", + enabled: true, + }, + { + key: "NEW_OFFENSE2", + label: "New Offense", + reporting_note: "Readmission: New Offense", + enabled: true, + }, + { + key: "VIOLATION_OF_CONDITIONS2", + label: "Violation of Conditions", + reporting_note: "Readmission: Violation of Conditions", + enabled: true, + }, + { + key: "OTHER2", + label: "Other", + reporting_note: "Readmission: Other", + enabled: true, + }, + { + key: "UNKNOWN2", + label: "Unknown", + reporting_note: "Readmission: Unknown", + enabled: true, + }, + ], + }, + ], + }, +]; diff --git a/publisher/src/components/MetricsView/index.ts b/publisher/src/components/MetricsView/index.ts new file mode 100644 index 000000000..1367ec56e --- /dev/null +++ b/publisher/src/components/MetricsView/index.ts @@ -0,0 +1,19 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./MetricsView"; +export * from "./MetricsView.styles"; diff --git a/publisher/src/components/Modal/Modal.tsx b/publisher/src/components/Modal/Modal.tsx new file mode 100644 index 000000000..6cbda3820 --- /dev/null +++ b/publisher/src/components/Modal/Modal.tsx @@ -0,0 +1,148 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { useEffect, useState } from "react"; +import styled, { css, keyframes } from "styled-components/macro"; + +import { HEADER_BAR_HEIGHT, palette } from "../GlobalStyles"; + +const ModalContainer = styled.div` + width: 100vw; + height: 100vh; + position: absolute; + top: 0; + left: 0; + z-index: 10; + background: ${palette.highlight.grey4}; +`; + +const fromBottomToTop = keyframes` + 0% { transform: translateY(100%); } + 100% { transform: translateY(0); } +`; + +const fromTopToBottom = keyframes` + 0% { transform: translateY(0); } + 100% { transform: translateY(100%); } +`; + +const animateBottomToTop = css` + animation: ${fromBottomToTop} 0.5s forwards ease; +`; + +const animateTopToBottom = css` + animation: ${fromTopToBottom} 0.3s forwards ease-in-out; +`; + +const MODAL_TOP_GAP = `${HEADER_BAR_HEIGHT}px`; + +const ModalElement = styled.div<{ showUnmountAnimation?: boolean }>` + height: calc(100% - ${MODAL_TOP_GAP}); + margin-top: ${MODAL_TOP_GAP}; + background: ${palette.solid.white}; + position: relative; + border-top: 1px solid ${palette.solid.darkgrey}; + ${({ showUnmountAnimation }) => + showUnmountAnimation ? animateTopToBottom : animateBottomToTop} +`; + +const CloseButton = styled.div` + width: 64px; + height: 64px; + display: flex; + align-items: center; + justify-content: center; + background: ${palette.solid.red}; + border-radius: 0.5px; + position: absolute; + top: 0; + right: 0; + z-index: 4; + + &:before { + content: ""; + position: absolute; + width: 32px; + height: 2px; + background: ${palette.solid.white}; + transform: rotate(135deg); + } + + &:after { + content: ""; + position: absolute; + width: 32px; + height: 2px; + background: ${palette.solid.white}; + transform: rotate(45deg); + } + + &:hover { + cursor: pointer; + opacity: 0.9; + } +`; + +type ModalProps = { + isOpen: boolean; + handleClose: () => void; +}; + +export const Modal: React.FC = ({ + isOpen, + handleClose, + children, +}) => { + const [showUnmountAnimation, setShowUnmountAnimation] = useState(false); + + const closeModal = () => { + if (showUnmountAnimation) { + setShowUnmountAnimation(false); + handleClose(); + } + }; + + const prepareModalToClose = (e: React.MouseEvent) => { + if (e.target !== e.currentTarget) return; + setShowUnmountAnimation(true); + }; + + useEffect(() => { + if (isOpen) { + document.body.style.overflow = "hidden"; + } else { + document.body.style.overflow = "unset"; + } + + return () => { + document.body.style.overflow = "unset"; + }; + }, [isOpen]); + + if (!isOpen) return null; + + return ( + + + {children} + + + ); +}; diff --git a/publisher/src/components/Modal/index.ts b/publisher/src/components/Modal/index.ts new file mode 100644 index 000000000..b9f7ed337 --- /dev/null +++ b/publisher/src/components/Modal/index.ts @@ -0,0 +1,18 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./Modal"; diff --git a/publisher/src/components/Onboarding/Onboarding.tsx b/publisher/src/components/Onboarding/Onboarding.tsx new file mode 100644 index 000000000..65579c4b6 --- /dev/null +++ b/publisher/src/components/Onboarding/Onboarding.tsx @@ -0,0 +1,717 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { useEffect, useRef, useState } from "react"; +import styled, { keyframes } from "styled-components/macro"; + +import { useStore } from "../../stores"; +import logo from "../assets/jc-logo-vector-onboarding.png"; +import { palette, typography } from "../GlobalStyles"; +import { + DATA_ENTRY_WIDTH, + ONE_PANEL_MAX_WIDTH, + SIDE_PANEL_WIDTH, + TWO_PANEL_MAX_WIDTH, +} from "../Reports/ReportDataEntry.styles"; +import { showToast } from "../Toast"; + +export const OnboardingContainer = styled.div` + width: 100vw; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + position: fixed; + top: 0; + left: 0; + z-index: 99; + color: ${palette.solid.white}; +`; + +export const OnboardingBackdropContainer = styled.div` + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + background-color: ${palette.highlight.grey12}; + backdrop-filter: blur(3px); +`; + +const OnboardingIntroModal = styled.div` + width: 825px; + height: 599px; + display: flex; + flex-direction: column; + position: relative; + border-radius: 15.5px; + padding: 59px 48px 59px 59px; + background: linear-gradient(62.14deg, #007541 50.01%, #029553 100%); + z-index: 1; +`; + +const LogoImage = styled.img` + width: 441px; + position: absolute; + top: 0; + right: 0; + z-index: -1; +`; + +const OnboardingTitle = styled.div` + ${typography.sizeCSS.large} + line-height: 58px; + text-transform: uppercase; + margin-bottom: 25px; + + span { + display: block; + font-weight: 900; + font-size: 60px; + line-height: 34px; + } +`; + +const OnboardingIntroContent = styled.div` + ${typography.sizeCSS.large} + color: rgba(223, 246, 236, 1); + line-height: 36px; + margin-top: 14px; + + p:not(:last-child) { + margin-bottom: 34px; + } + + span { + font-weight: 700; + } +`; + +const OnboardingIntroGetStartedButton = styled.button` + ${typography.sizeCSS.title} + width: 100%; + height: 96px; + position: absolute; + bottom: 0; + left: 0; + border: none; + border-radius: 0 0 15.5px 15.5px; + background: rgba(2, 95, 53, 1); + color: ${palette.solid.white}; + + &:hover { + cursor: pointer; + color: rgba(223, 246, 236, 1); + } +`; + +const float = keyframes` + 0% { transform: translate(0, 0px); } + 50% { transform: translate(0, 10px); } + 100% { transform: translate(0, 0px); } +`; + +type OnboardModalPositionProps = + | "bottomleft" + | "bottomright" + | "reportsummary" + | "publishdata"; + +const OnboardingModal = styled.div<{ + position: OnboardModalPositionProps; + modalHeight: number; + topic: OnboardingTopics; + lastSection?: boolean; +}>` + width: 532px; + height: fit-content; + position: absolute; + z-index: 1; + top: 0; + left: 0; + bottom: 0; + right: 0; + transition: top 0.5s ease, left 0.5s ease, bottom 0.5s ease, right 0.5s ease, + background 1s ease; + ${({ position, modalHeight, topic }) => { + if (position === "bottomleft") { + return ` + top: calc(100% - ${modalHeight}px - 24px); + right: calc(100% - 532px - 24px); + bottom: 24px; + left: 24px; + `; + } + if (position === "bottomright") { + return ` + ${ + topic === "reportsview" + ? `top: unset;` + : `top: calc(100% - ${modalHeight}px - 24px);` + } + left: calc(100% - 532px - 24px); + bottom: 24px; + right: 24px; + `; + } + if (position === "reportsummary") { + return ` + bottom: calc(100% - ${modalHeight}px - 99px); + right: calc(100% - 532px - ${SIDE_PANEL_WIDTH}px); + top: 99px; + left: ${SIDE_PANEL_WIDTH}px; + `; + } + if (position === "publishdata") { + return ` + bottom: calc(100% - ${modalHeight}px - 113px); + left: calc(100% - 532px - ${SIDE_PANEL_WIDTH}px); + top: 113px; + right: ${SIDE_PANEL_WIDTH}px; + `; + } + }} + border-radius: 10px; + padding: 38px 31px 97px 38px; + background: ${({ lastSection }) => + lastSection ? palette.solid.green : palette.solid.blue}; + box-shadow: 0px 4px 10px rgba(53, 83, 98, 0.4); + animation: ${float} 3s infinite ease-in-out; + + @media only screen and (max-width: ${TWO_PANEL_MAX_WIDTH}px) { + ${({ position, modalHeight }) => { + if (position === "publishdata") { + return ` + top: calc(100% - ${modalHeight}px - 28px); + right: calc(100% - 532px - ${SIDE_PANEL_WIDTH}px); + left: ${SIDE_PANEL_WIDTH}px; + `; + } + return ``; + }} + } +`; + +const OnboardingModalTitle = styled.div` + ${typography.sizeCSS.large} + font-weight: 700; +`; + +const OnboardingModalContent = styled.div` + ${typography.sizeCSS.medium} + line-height: 27px; + margin-top: 11px; + + a { + color: ${palette.solid.white}; + } +`; + +const OnboardingModalActionButtonWrapper = styled.div<{ + lastSection?: boolean; +}>` + ${typography.sizeCSS.large} + height: 62px; + width: 100%; + display: flex; + align-items: center; + justify-content: flex-end; + padding-right: 31px; + position: absolute; + left: 0; + bottom: 0; + border-radius: 0px 0px 10px 10px; + background: ${({ lastSection }) => + lastSection + ? `linear-gradient(90deg, rgba(5, 101, 57, 0) 0%, #005931 100%)` + : `linear-gradient(90deg, rgba(0, 69, 137, 0) 0%, #004589 100%)`}; +`; + +const OnboardingProgressIndicatorWrapper = styled.div` + margin-right: 17px; + display: flex; +`; + +const OnboardingProgressIndicator = styled.div<{ filled?: boolean }>` + width: 10px; + height: 10px; + border-radius: 50%; + background: ${({ filled }) => + filled ? palette.solid.white : `rgba(255, 255, 255, 0.3)`}; + margin: 9px; + + &:hover { + cursor: pointer; + } +`; + +type OnboardingActionButtonProps = "Next" | "Finish" | "Close"; + +const OnboardingActionButton = styled.button<{ + action: OnboardingActionButtonProps; +}>` + ${typography.sizeCSS.large} + background: none; + border: none; + color: ${palette.solid.white}; + + &::after { + content: ${({ action }) => { + if (action === "Next") { + return `"Next →"`; + } + if (action === "Finish") { + return `"Finish →"`; + } + if (action === "Close") { + return `"Close"`; + } + }}; + } + + &:hover { + cursor: pointer; + opacity: 0.9; + } +`; + +type OnboardingFadedContainerProps = { + position: string; + currentSectionPosition?: string; +}; + +const OnboardingFadedContainer = styled.div` + height: 100%; + background: ${palette.solid.white}; + opacity: 0.7; + position: absolute; + top: 0; + ${({ position }) => { + if (position === "left") { + return ` + width: ${SIDE_PANEL_WIDTH}px; + left: 0; + `; + } + if (position === "right") { + return ` + width: ${SIDE_PANEL_WIDTH}px; + right: 0; + `; + } + if (position === "center") { + return ` + width: ${DATA_ENTRY_WIDTH}px; + `; + } + }}; + + @media only screen and (max-width: ${TWO_PANEL_MAX_WIDTH}px) { + ${({ position, currentSectionPosition }) => { + if (position === "left" && currentSectionPosition === "publishdata") { + return ` + display: none; + `; + } + if (position === "right") { + return ` + display: none; + `; + } + if (position === "center") { + return ` + margin-left: 336px; + `; + } + }}; + } + + @media only screen and (max-width: ${ONE_PANEL_MAX_WIDTH}px) { + ${({ position }) => { + if (position === "right" || position === "left") { + return ` + display: none; + `; + } + }}; + } +`; + +type OnboardingTopics = "reportsview" | "dataentryview"; + +const OnboardingIntro = ({ closeIntro }: { closeIntro: () => void }) => { + return ( + + + + + Welcome to Publisher. + + +

+ Welcome to the Justice Counts Publisher! Our team is + excited that your agency is leading the charge towards a more + transparent criminal justice system. +

+ +

+ We’ve built the Publisher Tool to make it as quick and easy for you + to publish the Justice Counts Metrics on a regular basis. Let’s walk + through the application. +

+
+ + Let’s Get Started + +
+
+ ); +}; + +type OnboardingSections = { + order: number | null; + title: string; + html: JSX.Element; + position: OnboardModalPositionProps; + action: OnboardingActionButtonProps; +}; + +const OnboardingSessionView = ({ + completeOnboarding, + topic, +}: { + completeOnboarding: () => void; + topic: OnboardingTopics; +}) => { + const [currentSectionIndex, setCurrentSectionIndex] = useState(0); + const [currentModalHeight, setCurrentModalHeight] = useState(305); + const modalHeightRef = useRef() as React.MutableRefObject; + const reportsViewSections: OnboardingSections[] = [ + { + order: 1, + title: "Reports View", + html: ( + <> +

+ Every month, we’ll generate new Reports on this + homepage. As a member of this agency’s Justice Counts team, you’ll + be able to add data for the{" "} + + Justice Counts Metrics + {" "} + via these reports whenever the relevant data is ready on your end. +

+ + ), + position: "bottomright", + action: "Next", + }, + { + order: 2, + title: "Settings", + html: ( + <> +

+ If you need to edit your name or email, click on your name and + access your Settings in the dropdown. +

+

+ Admins can also use these settings to add new team members to + Publisher. +

+ + ), + position: "bottomright", + action: "Next", + }, + { + order: 3, + title: "Feedback", + html: ( + <> +

+ Your feedback helps us to make this product even easier to use. If + you have questions, requests, or any other feedback, please email us + at{" "} + + support@justice-counts.org + {" "} + and we’ll be happy to get back to you. +

+ + ), + position: "bottomright", + action: "Finish", + }, + { + order: null, + title: "You're ready to go!", + html: ( + <> +

+ If you have any questions, email the Justice Counts team at{" "} + + support@justice-counts.org + + . +

+ + ), + position: "bottomright", + action: "Close", + }, + ]; + const dataEntryViewSections: OnboardingSections[] = [ + { + order: 1, + title: "Entering data", + html: ( + <> +

+ This is where you’ll enter the data and important contextual + information about the Justice Counts Metrics (linked{" "} + + here + {" "} + in case you need a refresher). We’ve included additional + descriptions and definitions on the side in case it’s helpful. +

+ + ), + position: "bottomright", + action: "Next", + }, + { + order: 2, + title: "Report Summary", + html: ( + <> +

+ The metrics associated with each report are listed in the Report + Summary. Checkmarks indicate that all inputs are valid; X’s indicate + that there is an error with one of the inputs. +

+
+

+ You can click on a metric to skip to that part in the form, or + scroll to the metric - either works! +

+ + ), + position: "reportsummary", + action: "Next", + }, + { + order: 3, + title: "Publish your data", + html: ( + <> +

+ Whenever you’re ready, you can publish your data with this button. + Don’t worry – you’ll still have a chance to review all the data + before it goes live*, and you can still edit the data even after + it’s been published. +

+
+

+ *NOTE: At this stage, data will just be marked as + published and will not be live just yet. +

+ + ), + position: "publishdata", + action: "Finish", + }, + { + order: null, + title: "You're ready to go!", + html: ( + <> +

+ If you have any questions, email the Justice Counts team at{" "} + + support@justice-counts.org + + . +

+ + ), + position: "bottomright", + action: "Close", + }, + ]; + const currentSections = + topic === "reportsview" ? reportsViewSections : dataEntryViewSections; + + const goToNextSection = () => + setCurrentSectionIndex((prev) => + prev + 1 < currentSections.length ? prev + 1 : prev + ); + + useEffect(() => { + if (topic === "reportsview") { + showToast( + "Welcome! Click “Next” in the onboarding boxes to continue.", + false, + undefined, + -1, + true + ); + return () => showToast("You're ready to go!", false, undefined, 0, false); + } + }, [topic]); + + useEffect(() => { + if ( + topic === "reportsview" && + currentSectionIndex + 1 === currentSections.length + ) { + showToast("You're ready to go!", false, undefined, -1, true); + } + }, [currentSectionIndex, currentSections.length, topic]); + + useEffect(() => { + if (modalHeightRef.current) { + setCurrentModalHeight( + modalHeightRef.current.getBoundingClientRect().height + ); + } + }, [currentSectionIndex]); + + return ( + <> + + + {currentSections[currentSectionIndex].title} + + + + {currentSections[currentSectionIndex].html} + + + + + {currentSectionIndex + 1 < currentSections.length && + currentSections.map( + (section, index) => + section.order && ( + setCurrentSectionIndex(index)} + /> + ) + )} + + + + + + + {topic === "dataentryview" && + currentSections[currentSectionIndex].position === "bottomright" && + currentSections[currentSectionIndex].order && ( + <> + + + + )} + + {topic === "dataentryview" && + currentSections[currentSectionIndex].position === "reportsummary" && ( + <> + + + + )} + + {topic === "dataentryview" && + currentSections[currentSectionIndex].position === "publishdata" && ( + <> + + + + )} + + ); +}; + +const Onboarding = ({ + setShowOnboarding, + topic, +}: { + setShowOnboarding: React.Dispatch>; + topic: OnboardingTopics; +}) => { + const { userStore } = useStore(); + const [showIntro, setShowIntro] = useState(true); + const closeIntro = () => setShowIntro(false); + const completeOnboarding = () => { + userStore.updateOnboardingStatus(topic, true); + setShowOnboarding(false); + }; + + /** Prevent body from scrolling when this dialog is open */ + useEffect(() => { + document.body.style.overflow = "hidden"; + return () => { + document.body.style.overflow = "unset"; + }; + }, []); + + return ( + + {showIntro && topic === "reportsview" && ( + + )} + {(!showIntro || topic === "dataentryview") && ( + + )} + + ); +}; + +export default Onboarding; diff --git a/publisher/src/components/Onboarding/OnboardingDataEntrySummary.tsx b/publisher/src/components/Onboarding/OnboardingDataEntrySummary.tsx new file mode 100644 index 000000000..1523d44c6 --- /dev/null +++ b/publisher/src/components/Onboarding/OnboardingDataEntrySummary.tsx @@ -0,0 +1,229 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { useEffect, useState } from "react"; +import styled from "styled-components/macro"; + +import closeIcon from "../assets/dark-close-icon.png"; +import { ReactComponent as Logo } from "../assets/jc-logo-vector.svg"; +import { palette, typography } from "../GlobalStyles"; +import { ONE_PANEL_MAX_WIDTH } from "../Reports/ReportDataEntry.styles"; +import { OnboardingBackdropContainer, OnboardingContainer } from "./Onboarding"; + +const OnboardingSummaryModal = styled.div` + width: 60%; + height: 76%; + background: ${palette.solid.white}; + box-shadow: inset 0px 0px 10px rgba(23, 28, 43, 0.5); + border-radius: 15px; +`; + +const ModalHeader = styled.div` + ${typography.sizeCSS.title}; + height: 119px; + display: flex; + justify-content: space-between; + position: relative; + z-index: 0; + background: linear-gradient(270deg, #016fdc 0%, #004589 100%); + box-shadow: inset 0px 0px 10px rgba(23, 28, 43, 0.5); + border-radius: 15px 15px 0 0; + padding: 35px 50px; + overflow: hidden; +`; + +const ModalBody = styled.div` + ${typography.sizeCSS.medium} + line-height: 27px; + padding: 35px 50px; + color: ${palette.solid.darkgrey}; + max-height: 76%; + overflow: scroll; + + h1 { + ${typography.sizeCSS.large} + } + + p:not(:last-child) { + margin-bottom: 18px; + } + + ul { + margin-left: 28px; + margin-bottom: 18px; + } +`; + +const CloseIcon = styled.img` + width: 36px; + height: 36px; + filter: brightness(0) invert(1); + + &:hover { + cursor: pointer; + opacity: 0.8; + } +`; + +const LogoVector = styled(Logo)` + width: 524px; + height: 524px; + position: absolute; + z-index: -1; + top: calc(50% - 524px / 2 + 114.5px); + left: 50%; + transform: translateX(-50%); + + path { + fill: rgba(1, 69, 137, 0.3); + } +`; + +export const OnboardingSummaryButton = styled.div` + width: 36px; + height: 36px; + display: flex; + justify-content: center; + align-items: center; + position: fixed; + z-index: 2; + bottom: 25px; + right: 25px; + background: ${palette.solid.blue}; + color: ${palette.solid.white}; + border-radius: 50%; + + &:hover { + cursor: pointer; + opacity: 0.8; + } + + @media only screen and (max-width: ${ONE_PANEL_MAX_WIDTH}px) { + display: none; + } +`; + +export const OnboardingDataEntrySummary: React.FC = () => { + const [showOnboardingSummary, setShowOnboardingSummary] = useState(false); + + /** Prevent body from scrolling when this dialog is open */ + useEffect(() => { + if (showOnboardingSummary) { + document.body.style.overflow = "hidden"; + } + return () => { + document.body.style.overflow = "unset"; + }; + }, [showOnboardingSummary]); + + const closeOnboardingSummary = (e: React.MouseEvent) => { + if (e.target !== e.currentTarget) return; + setShowOnboardingSummary(false); + }; + const openOnboardingSummary = () => setShowOnboardingSummary(true); + + const OnboardingSummary: React.FC = () => ( + + + + + + Data Entry + + + + +

+ + This page is where you can enter the data and important + contextual information about the Justice Counts Metrics.{" "} + +

+ +

Entering Data

+

+ The purpose of this view is to enter data for a given reporting + period. You can access all reports from the Reports View.{" "} +

+ + + Each metric is composed of three components: +
    +
  • + Primary Value: The top-level value associated + with the metric.{" "} +
  • +
  • + Breakdowns: Subdivisions of the primary value + (e.g., staff types, race, gender, etc).{" "} +
  • +
  • + Context: Additional written or predefined + fields that provide additional information about the metric.{" "} +
  • +
+
+ +

+ We’ve also included additional descriptions and definitions on the + right-side panel, including the definition of the metric, + definitions for any terms, and details on how the metric should be + calculated.{" "} +

+ +

Publishing Data

+

+ Whenever you have finished entering data, you can finalize and + publish data via the Review & Publish button.{" "} +

+ +

+ Clicking this button will first take you to a page to review the + numbers that you have entered before publishing. Publishing the + data will mark the report as “Published” in the Reports View and + the underlying data will be made available to the public via + Justice Counts publishing channels* (public dashboard, data feed, + etc). +

+

+ *NOTE: At this stage, data will just be marked as + published and will not be live just yet. +

+ +

+ After publishing, you can always go back to edit the numbers.{" "} +

+
+
+
+
+ ); + + return ( + <> + + ? + + + {showOnboardingSummary && } + + ); +}; diff --git a/publisher/src/components/Onboarding/index.ts b/publisher/src/components/Onboarding/index.ts new file mode 100644 index 000000000..96a0a180c --- /dev/null +++ b/publisher/src/components/Onboarding/index.ts @@ -0,0 +1,19 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export { default as Onboarding } from "./Onboarding"; +export * from "./OnboardingDataEntrySummary"; diff --git a/publisher/src/components/Reports/CreateReport.test.tsx b/publisher/src/components/Reports/CreateReport.test.tsx new file mode 100644 index 000000000..5546e7994 --- /dev/null +++ b/publisher/src/components/Reports/CreateReport.test.tsx @@ -0,0 +1,131 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { render, screen } from "@testing-library/react"; +import { runInAction } from "mobx"; +import React from "react"; +import { BrowserRouter } from "react-router-dom"; + +import Reports from "../../pages/Reports"; +import { rootStore, StoreProvider } from "../../stores"; + +const mockedUseNavigate = jest.fn(); +const mockedUseLocation = jest.fn(); +jest.mock("react-router-dom", () => ({ + ...jest.requireActual("react-router-dom"), + useNavigate: () => mockedUseNavigate, + useLocation: () => mockedUseLocation, +})); + +beforeEach(() => { + rootStore.reportStore.reportOverviews = {}; + rootStore.reportStore.loadingOverview = false; +}); + +test("displayed created reports", async () => { + render( + + + + ); + + await runInAction(() => { + rootStore.reportStore.reportOverviews = { + 0: { + id: 0, + agency_id: 0, + month: 11, + year: 2022, + frequency: "MONTHLY", + last_modified_at: null, + last_modified_at_timestamp: null, + editors: ["Editor #1"], + status: "NOT_STARTED", + }, + }; + }); + + const jan2022 = screen.getByText(/November 2022/i); + const editor1 = screen.getByText(/Editor #1/i); + + expect(jan2022).toBeInTheDocument(); + expect(editor1).toBeInTheDocument(); + + await runInAction(() => { + rootStore.reportStore.reportOverviews[1] = { + id: 1, + agency_id: 0, + month: 11, + year: 2020, + frequency: "ANNUAL", + last_modified_at: null, + last_modified_at_timestamp: null, + editors: ["Editor #2"], + status: "NOT_STARTED", + }; + }); + + const annualReport2020 = screen.getByText(/Annual Report 2020/i); + const editor2 = screen.getByText(/Editor #2/i); + + expect(annualReport2020).toBeInTheDocument(); + expect(editor2).toBeInTheDocument(); + + expect.hasAssertions(); +}); + +describe("test create report button", () => { + test("created reports button should not be displayed if user does not have permission", () => { + render( + + + + + + ); + + runInAction(() => { + rootStore.userStore.permissions = [""]; + }); + + const selectButton = screen.queryByText(/Select/i); + const createNewReportButton = screen.queryByText(/New/i); + + expect(selectButton).not.toBeInTheDocument(); + expect(createNewReportButton).not.toBeInTheDocument(); + }); + + test("created reports button should be displayed if user has permission", () => { + render( + + + + + + ); + + runInAction(() => { + rootStore.userStore.permissions = ["recidiviz_admin"]; + }); + + const selectButton = screen.queryByText(/Select/i); + const createNewReportButton = screen.queryByText(/New/i); + + expect(selectButton).toBeInTheDocument(); + expect(createNewReportButton).toBeInTheDocument(); + }); +}); diff --git a/publisher/src/components/Reports/CreateReport.tsx b/publisher/src/components/Reports/CreateReport.tsx new file mode 100644 index 000000000..e6c51d5fb --- /dev/null +++ b/publisher/src/components/Reports/CreateReport.tsx @@ -0,0 +1,324 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { useState } from "react"; +import { useNavigate } from "react-router-dom"; +import styled from "styled-components/macro"; + +import { trackReportCreated } from "../../analytics"; +import { CreateReportFormValuesType, ReportOverview } from "../../shared/types"; +import { useStore } from "../../stores"; +import { monthsByName, printDateRangeFromMonthYear } from "../../utils"; +import { + BinaryRadioButton, + BinaryRadioGroupWrapper, + Form, + FormWrapper, + GoBackToReportsOverviewLink, + MetricSectionSubTitle, + MetricSectionTitle, + OnePanelBackLinkContainer, + PageWrapper, + PreTitle, + Title, + TitleWrapper, +} from "../Forms"; +import { Dropdown } from "../Forms/Dropdown"; +import { palette, typography } from "../GlobalStyles"; +import { showToast } from "../Toast"; +import { + PublishButton, + PublishDataWrapper, + TWO_PANEL_MAX_WIDTH, +} from "./ReportDataEntry.styles"; +import { ReportSummaryWrapper } from "./ReportSummaryPanel"; + +function createIntegerRange(start: number, end: number) { + return Array.from({ length: end - start + 1 }, (_, i) => start + i); +} + +const Heading = styled.div` + font-size: ${typography.sizeCSS.medium}; + margin-top: 24px; +`; + +const CreateReportInfoContainer = styled.div` + border-radius: 5px; + padding: 20px 30px 20px 30px; + border: 2px solid ${palette.highlight.lightblue2}; + background: ${palette.highlight.lightblue1}; + margin-top: 38px; + color: ${palette.solid.blue}; + ${typography.sizeCSS.medium} +`; + +const BoldFont = styled.span` + font-weight: 700; +`; + +const CreateButton = styled(PublishButton)` + &::after { + content: "Create Report"; + } +`; + +const FormCreateButton = styled(CreateButton)` + display: none; + width: auto; + margin-top: 48px; + + @media only screen and (max-width: ${TWO_PANEL_MAX_WIDTH}px) { + display: block; + } +`; + +const initialCreateReportFormValues: CreateReportFormValuesType = { + month: 1, + year: new Date(Date.now()).getFullYear(), + frequency: "MONTHLY", + annualStartMonth: 1, + isRecurring: false, +}; + +const CreateReport = () => { + const { reportStore, userStore } = useStore(); + const navigate = useNavigate(); + const [createReportFormValues, setCreateReportFormValues] = useState( + initialCreateReportFormValues + ); + + const updateMonth = (e: React.ChangeEvent) => + setCreateReportFormValues((prev) => ({ + ...prev, + month: +e.target.value as CreateReportFormValuesType["month"], + })); + + const updateYearStandard = (e: React.ChangeEvent) => + setCreateReportFormValues((prev) => ({ + ...prev, + annualStartMonth: +e.target + .value as CreateReportFormValuesType["annualStartMonth"], + })); + + const updateYear = (e: React.ChangeEvent) => + setCreateReportFormValues((prev) => ({ ...prev, year: +e.target.value })); + + const updateFrequency = (e: React.ChangeEvent) => + setCreateReportFormValues((prev) => ({ + ...prev, + frequency: e.target.value as CreateReportFormValuesType["frequency"], + })); + + // const updateIsRecurring = (recurring: boolean) => + // setCreateReportFormValues((prev) => ({ + // ...prev, + // isRecurring: recurring, + // })); + + const createNewReport = async () => { + const { frequency, month, year, annualStartMonth, isRecurring } = + createReportFormValues; + const response = await reportStore.createReport({ + frequency, + month: frequency === "ANNUAL" ? annualStartMonth : month, + is_recurring: isRecurring, + year: isRecurring ? new Date(Date.now()).getFullYear() : year, + }); + if (response && response instanceof Response) { + if (response.status === 200) { + navigate("/"); + showToast("The report was successfully created", true); + const report = (await response.json()) as ReportOverview; + const agency = userStore.userAgencies?.find( + (a) => a.id === report.agency_id + ); + trackReportCreated(report.id, agency); + return; + } + if (response.status === 400) { + const responseJson = await response.json(); + showToast(responseJson.description, false, "red"); + return; + } + } + showToast("Error creating report", false, "red"); + }; + + const { frequency, month, year, annualStartMonth, isRecurring } = + createReportFormValues; + + return ( + + {/* Create Report Details Panel */} + + + navigate("/")} /> + + {/* Report Details */} + + + {/* Create Report Form */} + +
+ {/* Form Title */} + + navigate("/")} /> + + Create Report + New Report + + Report Parameters + + + What reporting frequency is this report? + + + + + {createReportFormValues.frequency === "ANNUAL" && ( + <> + + What year standard do you use for annual reports? + + + + + + + )} + {/* Disable recurring report toggle for now */} + {/* TODO(#13229): Create recurring report flow */} + {/* Is this a recurring report? + + updateIsRecurring(false)} + defaultChecked + /> + updateIsRecurring(true)} + /> + */} + {createReportFormValues.isRecurring === false && ( + <> + When should this report start? + + {createReportFormValues.frequency === "MONTHLY" && ( + + {monthsByName.map((m, i) => { + return ( + + ); + })} + + )} + + + {createIntegerRange(1970, new Date().getFullYear() + 1).map( + (yr) => { + return ( + + ); + } + )} + + + + )} + + The {isRecurring ? `recurring` : ``} report + will be created for{` `} + + {printDateRangeFromMonthYear( + frequency === "ANNUAL" ? annualStartMonth : month, + isRecurring ? new Date(Date.now()).getFullYear() : year, + frequency + )} + + . + + { + e.preventDefault(); + /** Should trigger a confirmation dialogue before submitting */ + createNewReport(); + }} + /> + +
+ + {/* Create Report Review Panel */} + + + <CreateButton + onClick={() => { + /** Should trigger a confirmation dialogue before submitting */ + createNewReport(); + }} + /> + + +
+ ); +}; + +export default CreateReport; diff --git a/publisher/src/components/Reports/DataEntryForm.test.tsx b/publisher/src/components/Reports/DataEntryForm.test.tsx new file mode 100644 index 000000000..9c3673e0c --- /dev/null +++ b/publisher/src/components/Reports/DataEntryForm.test.tsx @@ -0,0 +1,228 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { render, screen, waitFor } from "@testing-library/react"; +import { runInAction } from "mobx"; +import React from "react"; +import { MemoryRouter, Route, Routes } from "react-router-dom"; + +import { rootStore, StoreProvider } from "../../stores"; +import ReportDataEntry from "./ReportDataEntry"; + +beforeEach(() => { + const mockIntersectionObserver = jest.fn(); + mockIntersectionObserver.mockReturnValue({ + observe: () => null, + unobserve: () => null, + disconnect: () => null, + }); + window.IntersectionObserver = mockIntersectionObserver; +}); + +test("display loading when no reports are loaded", async () => { + render( + + + + ); + await waitFor(async () => { + const loading = screen.getByTestId("loading"); + expect(loading).toBeInTheDocument(); + }); + expect.hasAssertions(); +}); + +test("display error when report fails to load", async () => { + render( + + + + ); + + runInAction(() => { + rootStore.userStore.userInfoLoaded = true; + }); + + const errorText = await screen.findByText( + /Error: No auth client initialized./i + ); + expect(errorText).toBeInTheDocument(); + expect.hasAssertions(); +}); + +describe("test data entry form", () => { + runInAction(() => { + rootStore.userStore.userInfoLoaded = true; + + rootStore.reportStore.reportOverviews = { + 0: { + id: 0, + agency_id: 0, + year: 2022, + month: 4, + frequency: "MONTHLY", + last_modified_at: "April 12 2022", + last_modified_at_timestamp: null, + editors: ["Editor #1", "Editor #2"], + status: "DRAFT", + }, + }; + + rootStore.reportStore.reportMetricsBySystem = { + 0: { + "Law Enforcement": [ + { + key: "PROSECUTION_STAFF", + system: "LAW_ENFORCEMENT", + display_name: "Staff", + description: + "Measures the number of full-time staff employed by the agency.", + reporting_note: "DOCs report only correctional institution staff.", + value: 1000, + unit: "people", + category: "CAPACITY_AND_COST", + label: "Total Staff", + enabled: true, + definitions: [ + { + term: "full-time staff", + definition: "definition of full-time staff", + }, + ], + contexts: [ + { + key: "PROGRAMMATIC_OR_MEDICAL_STAFF", + display_name: + "Does this include programmatic or medical staff?", + reporting_note: null, + required: false, + type: "MULTIPLE_CHOICE", + multiple_choice_options: ["YES", "NO"], + value: null, + }, + ], + disaggregations: [ + { + key: "PROSECUTION_STAFF_TYPE", + display_name: "Staff Types", + dimensions: [ + { + key: "SUPPORT", + label: "Support", + value: null, + reporting_note: "Staff: Support", + }, + ], + required: false, + helper_text: "Break down the metric by NIBRS offense types.", + }, + ], + }, + ], + }, + }; + + rootStore.reportStore.reportMetrics = { + 0: Object.values(rootStore.reportStore.reportMetricsBySystem[0]).flat(), + }; + }); + + test("displays data entry form based on reports", async () => { + render( + + + + } /> + {" "} + + + ); + + const reportDate = await screen.findByText("April 2022"); + + expect(reportDate).toBeInTheDocument(); + + const displayName = screen.getAllByText("Staff")[0]; + const metricDescription = screen.getAllByText( + "Measures the number of full-time staff employed by the agency." + )[0]; + const context = screen.getAllByText( + "Does this include programmatic or medical staff?" + )[0]; + expect(displayName).toBeInTheDocument(); + expect(metricDescription).toBeInTheDocument(); + expect(context).toBeInTheDocument(); + + expect.hasAssertions(); + }); +}); + +// TODO(#13325) JSDOM does not recognize `.animate` as a function. Will need to refactor toast or this test. + +// test("expect positive number value to not add field error (formErrors should be an empty object)", async () => { +// render( +// +// +// +// } /> +// +// +// +// ); + +// const labels = await screen.findAllByLabelText("Total Staff"); +// fireEvent.change(labels[0], { target: { value: "100" } }); +// expect( +// rootStore.formStore.metricsValues[0].PROSECUTION_STAFF.error +// ).toBeUndefined(); +// }); + +// test("expect negative number value to add field error (formErrors should contain an error property for the field)", async () => { +// render( +// +// +// +// } /> +// +// +// +// ); + +// const labels = await screen.findAllByLabelText("Total Staff"); +// fireEvent.change(labels[0], { target: { value: "-100" } }); +// expect(rootStore.formStore.metricsValues[0].PROSECUTION_STAFF.error).toBe( +// "Please enter a valid number." +// ); +// }); + +// test("expect empty value in required field to add field error (formErrors should contain an error property for the field)", async () => { +// render( +// +// +// +// } /> +// +// +// +// ); + +// const labels = await screen.findAllByLabelText("Total Staff"); +// fireEvent.change(labels[0], { target: { value: "" } }); +// expect(rootStore.formStore.metricsValues[0].PROSECUTION_STAFF.error).toBe( +// "This is a required field." +// ); +// }); diff --git a/publisher/src/components/Reports/DataEntryForm.tsx b/publisher/src/components/Reports/DataEntryForm.tsx new file mode 100644 index 000000000..63efe69a5 --- /dev/null +++ b/publisher/src/components/Reports/DataEntryForm.tsx @@ -0,0 +1,450 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { runInAction } from "mobx"; +import { observer } from "mobx-react-lite"; +import React, { Fragment, useEffect, useRef, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import styled from "styled-components/macro"; + +import { + trackAutosaveFailed, + trackAutosaveTriggered, + trackReportNotStartedToDraft, +} from "../../analytics"; +import { useStore } from "../../stores"; +import { memoizeDebounce, printReportTitle } from "../../utils"; +import { + BinaryRadioGroupClearButton, + BinaryRadioGroupContainer, + BinaryRadioGroupQuestion, + BinaryRadioGroupWrapper, + ErrorWithTooltip, + Form, + FormWrapper, + GoBackToReportsOverviewLink, + Metric, + MetricSectionSubTitle, + MetricSectionTitle, + MetricSectionTitleWrapper, + MetricSystemTitle, + NotReportedIcon, + OnePanelBackLinkContainer, + OpacityGradient, + PreTitle, + RequiredChip, + TabbedDisaggregations, + Title, +} from "../Forms"; +import { HEADER_BAR_HEIGHT, palette, typography } from "../GlobalStyles"; +import { Onboarding, OnboardingDataEntrySummary } from "../Onboarding"; +import { showToast } from "../Toast"; +import { + AdditionalContextInput, + BinaryRadioButtonInputs, + MetricTextInput, +} from "./DataEntryFormComponents"; +import { + DATA_ENTRY_WIDTH, + ONE_PANEL_MAX_WIDTH, + PublishButton, + SIDE_PANEL_HORIZONTAL_PADDING, +} from "./ReportDataEntry.styles"; + +const DataEntryFormPublishButtonContainer = styled.div` + position: fixed; + display: flex; + bottom: 0; + left: 0; + right: 0; + padding: 0 ${SIDE_PANEL_HORIZONTAL_PADDING}px; + justify-content: center; + padding: 0 24px 8px; + background: ${palette.solid.white}; +`; + +const DataEntryFormPublishButton = styled(PublishButton)` + display: none; + @media only screen and (max-width: ${ONE_PANEL_MAX_WIDTH}px) { + display: block; + flex: 0 1 ${DATA_ENTRY_WIDTH}px; + } +`; + +const DataEntryFormRequiredChip = styled(RequiredChip)` + margin-right: 16px; +`; + +const DataEntryFormErrorWithTooltipContainer = styled.div` + position: absolute; + width: 100%; + top: 70px; +`; + +const AdditionalContextLabel = styled.div` + ${typography.sizeCSS.medium} + margin-top: 40px; + margin-bottom: 16px; +`; + +const DataEntryForm: React.FC<{ + reportID: number; + updateFieldDescription: (title?: string, description?: string) => void; + updateActiveMetric: (metricKey: string) => void; + toggleConfirmationDialogue: () => void; +}> = ({ + reportID, + updateFieldDescription, + updateActiveMetric, + toggleConfirmationDialogue, +}) => { + const [showOnboarding, setShowOnboarding] = useState(true); + const [hasVersionConflict, setHasVersionConflict] = useState(false); + const [scrolled, setScrolled] = useState(false); + const metricsRef = useRef([]); + const { formStore, reportStore, userStore } = useStore(); + const navigate = useNavigate(); + + const isPublished = + reportStore.reportOverviews[reportID].status === "PUBLISHED"; + + useEffect( + () => { + const handleScroll = () => { + /** To shrink the Report Title on scroll */ + if (window.scrollY > HEADER_BAR_HEIGHT) { + setScrolled(true); + } else setScrolled(false); + + /** + * To sync the Report Summary metrics list and right panel Helper Text + * to the current (mostly) visible metric. + */ + const threshold = window.innerHeight / 2; + const scrollPosition = window.scrollY + threshold; + + metricsRef.current.forEach((ref) => { + if (ref) { + const { height } = ref.getBoundingClientRect(); + const { offsetTop } = ref; + const offsetBottom = offsetTop + height; + + if (scrollPosition > offsetTop && scrollPosition < offsetBottom) { + return updateActiveMetric(ref.id); + } + } + }); + }; + + window.addEventListener("scroll", handleScroll); + return () => { + window.removeEventListener("scroll", handleScroll); + }; + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + useEffect(() => { + /** Runs validation of previously saved inputs on load */ + formStore.validatePreviouslySavedInputs(reportID); + }, [formStore, reportID]); + + const saveUpdatedMetrics = async (metricKey?: string | undefined) => { + const updatedMetrics = formStore.reportUpdatedValuesForBackend( + reportID, + metricKey + ); + const oldStatus = reportStore.reportOverviews[reportID].status; + const status = + reportStore.reportOverviews[reportID].status === "PUBLISHED" + ? "PUBLISHED" + : "DRAFT"; + + showToast("Saving...", false, "grey", -1, true); + trackAutosaveTriggered(reportID); + const response = (await reportStore.updateReport( + reportID, + updatedMetrics, + status + )) as Response; + + if (response.status === 200) { + showToast("Saved", false, "grey"); + if (oldStatus === "NOT_STARTED" && status === "DRAFT") { + const agencyID = reportStore.reportOverviews[reportID]?.agency_id; + const agency = userStore.userAgencies?.find((a) => a.id === agencyID); + trackReportNotStartedToDraft(reportID, agency); + } + } else { + const body = await response.json(); + if (body.code === "version_conflict") { + showToast( + "Someone else has edited the report since you last opened it. Please refresh the page to view the latest changes and continue editing.", + false, + "red", + -1 + ); + runInAction(() => { + setHasVersionConflict(true); + }); + } else { + showToast("Failed to save", false, "red"); + } + trackAutosaveFailed(reportID); + } + }; + + const debouncedSave = useRef( + memoizeDebounce(saveUpdatedMetrics, 1500) + ).current; + + /** Saves metrics before tab/window close or page refreshes */ + useEffect( + () => { + const saveBeforeExiting = (e: BeforeUnloadEvent) => { + e.preventDefault(); + saveUpdatedMetrics(); + }; + + window.addEventListener("beforeunload", saveBeforeExiting); + return () => + window.removeEventListener("beforeunload", saveBeforeExiting); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + const reportOverview = reportStore.reportOverviews[reportID]; + const reportMetrics = reportStore.reportMetrics[reportID]; + const metricsBySystem = reportStore.reportMetricsBySystem[reportID]; + const showMetricSectionTitles = Object.keys(metricsBySystem).length > 1; + + if (!reportOverview || !reportMetrics) { + return null; + } + + return ( + +
{ + // When the form has changed, check the changed element for a `data-metric-key` + // data attribute. If present, pass to the `debouncedSave` function, which will + // then only save that metric. If not present, `metricKey` will be undefined, + // in which case `debouncedSave` will save all metrics. + const target = e.target as HTMLFormElement; + const metricKey = target.getAttribute("data-metric-key") ?? undefined; + debouncedSave(metricKey); + }} + > + {/* Form Title */} + + navigate("/")} /> + + Enter Data + + {reportOverview && + printReportTitle( + reportOverview.month, + reportOverview.year, + reportOverview.frequency + )} + + + {/* Metrics */} + {Object.entries(metricsBySystem).map( + ([system, metrics], systemIndex) => { + return ( + + {showMetricSectionTitles && ( + + {system} + + )} + + {metrics.map((metric, index) => ( + + metric.enabled && metricsRef.current?.push(e) + } + notReporting={!metric.enabled} + > + + + {metric.display_name} + + {!metric.enabled && } + + + {metric.description} + + + {metric.enabled && ( + <> + {/* Metric Value */} + + + {/* Disaggregations */} + {metric.disaggregations.length > 0 && ( + + )} + + {/* Contexts */} + {/* TODO(#13314): display multiple choice options as drop down if there are >2 options */} + {metric.contexts.length > 0 && + metric.contexts.map((context, contextIndex) => { + if (context.type === "MULTIPLE_CHOICE") { + const contextError = + formStore.contexts?.[reportID]?.[metric.key]?.[ + context.key + ]?.error; + return ( + + + {context.required && ( + + )} + {context.display_name} + + + + + + { + if ( + !isPublished && + !hasVersionConflict && + (formStore.contexts?.[reportID]?.[ + metric.key + ]?.[context.key]?.value || + context.value) + ) { + formStore.resetBinaryInput( + reportID, + metric.key, + context.key, + context.required + ); + showToast( + "Saving...", + false, + "grey", + undefined, + true + ); + debouncedSave(metric.key); + } + }} + disabled={isPublished || hasVersionConflict} + > + Clear Input + + + {/* Error */} + {contextError && ( + + + + )} + + ); + } + return ( + + + {context.display_name} + + + updateFieldDescription( + context.display_name as string, + context.reporting_note as string + ) + } + clearFieldDescription={() => + updateFieldDescription(undefined) + } + disabled={isPublished || hasVersionConflict} + /> + + ); + })} + + )} + + ))} + + ); + } + )} + + { + /** Should trigger a confirmation dialogue before submitting */ + e.preventDefault(); + toggleConfirmationDialogue(); + }} + isPublished={isPublished || hasVersionConflict} + /> + + + + + {/* Onboarding */} + + {userStore.onboardingTopicsCompleted?.dataentryview === false && + showOnboarding && ( + + )} + + +
+ ); +}; + +export default observer(DataEntryForm); diff --git a/publisher/src/components/Reports/DataEntryFormComponents.tsx b/publisher/src/components/Reports/DataEntryFormComponents.tsx new file mode 100644 index 000000000..c5fe4d754 --- /dev/null +++ b/publisher/src/components/Reports/DataEntryFormComponents.tsx @@ -0,0 +1,277 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { observer } from "mobx-react-lite"; +import React from "react"; + +import { + Metric, + MetricContext, + MetricDisaggregationDimensions, + MetricDisaggregations, +} from "../../shared/types"; +import { useStore } from "../../stores"; +import { formatNumberInput } from "../../utils"; +import { BinaryRadioButton, TextInput } from "../Forms"; + +interface MetricTextInputProps { + reportID: number; + metric: Metric; + autoFocus?: boolean; + disabled?: boolean; + updateFieldDescription?: () => void; + clearFieldDescription?: () => void; +} + +export const MetricTextInput = observer( + ({ + reportID, + metric, + autoFocus, + disabled, + updateFieldDescription, + clearFieldDescription, + }: MetricTextInputProps) => { + const { formStore } = useStore(); + const { metricsValues, updateMetricsValues } = formStore; + + const handleMetricChange = (e: React.ChangeEvent) => + updateMetricsValues(reportID, metric.key, e.target.value, metric.enabled); + + return ( + + ); + } +); + +interface DisaggregationDimensionTextInputProps extends MetricTextInputProps { + disaggregation: MetricDisaggregations; + disaggregationIndex: number; + dimension: MetricDisaggregationDimensions; + dimensionIndex: number; + disabled?: boolean; +} + +export const DisaggregationDimensionTextInput = observer( + ({ + reportID, + metric, + dimension, + disaggregation, + disaggregationIndex, + dimensionIndex, + updateFieldDescription, + clearFieldDescription, + disabled, + }: DisaggregationDimensionTextInputProps) => { + const { formStore } = useStore(); + const { disaggregations, updateDisaggregationDimensionValue } = formStore; + + const handleDisaggregationDimensionChange = ( + e: React.ChangeEvent + ) => + updateDisaggregationDimensionValue( + reportID, + metric.key, + disaggregation.key, + dimension.key, + e.target.value, + false, + metric.enabled + ); + + return ( + + ); + } +); + +interface AdditionalContextInputsProps extends MetricTextInputProps { + context: MetricContext; + contextIndex: number; +} + +interface BinaryContextProps extends AdditionalContextInputsProps { + options: string[]; +} + +export const BinaryRadioButtonInputs = observer( + ({ + reportID, + metric, + context, + contextIndex, + options, + disabled, + }: BinaryContextProps) => { + const { formStore } = useStore(); + const { contexts, updateContextValue } = formStore; + + const handleContextChange = (e: React.ChangeEvent) => { + if (!disabled) { + updateContextValue( + reportID, + metric.key, + context.key, + e.target.value, + context.required, + context.type, + metric.enabled + ); + } + }; + + return ( + <> + {options.map((option: string) => ( + + ))} + + ); + } +); + +export const AdditionalContextInput = observer( + ({ + reportID, + metric, + context, + contextIndex, + disabled, + updateFieldDescription, + clearFieldDescription, + }: AdditionalContextInputsProps) => { + const { formStore } = useStore(); + const { contexts, updateContextValue } = formStore; + const getContextValue = () => { + if ( + contexts?.[reportID]?.[metric.key]?.[context.key]?.value !== undefined + ) { + return context.type === "NUMBER" + ? formatNumberInput( + contexts[reportID]?.[metric.key][context.key].value + ) + : contexts[reportID]?.[metric.key][context.key].value; + } + + return metric.contexts[contextIndex].value?.toString() || ""; + }; + const contextValue = getContextValue(); + + const handleContextChange = ( + e: React.ChangeEvent + ) => + updateContextValue( + reportID, + metric.key, + context.key, + e.target.value, + context.required, + context.type, + metric.enabled + ); + + return ( + + ); + } +); diff --git a/publisher/src/components/Reports/HelperText.tsx b/publisher/src/components/Reports/HelperText.tsx new file mode 100644 index 000000000..8bb372b1e --- /dev/null +++ b/publisher/src/components/Reports/HelperText.tsx @@ -0,0 +1,144 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import styled from "styled-components/macro"; + +import { useStore } from "../../stores"; +import { palette, typography } from "../GlobalStyles"; +import { + BREAKPOINT_HEIGHT, + TWO_PANEL_MAX_WIDTH, +} from "./ReportDataEntry.styles"; + +const HelperTextContainer = styled.div` + height: 70vh; + overflow-y: scroll; + margin-top: 24px; + ${typography.sizeCSS.normal} + + &::-webkit-scrollbar { + -webkit-appearance: none; + width: 5px; + } + + &::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: ${palette.highlight.grey8}; + box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); + -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); + } + + @media only screen and (max-width: ${TWO_PANEL_MAX_WIDTH}px) { + height: 20vh; + padding-right: 7px; + &::-webkit-scrollbar { + -webkit-appearance: none; + width: 5px; + } + + &::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: ${palette.highlight.grey8}; + box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); + -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); + } + + @media only screen and (max-height: ${BREAKPOINT_HEIGHT}px) { + display: none; + } + } +`; + +const HelperTextSection = styled.div` + margin-bottom: 31px; + + &:last-child { + margin-bottom: 0; + } +`; + +const HelperTextTitle = styled.div` + margin-bottom: 10px; +`; + +const HelperTextContent = styled.div` + color: ${palette.highlight.grey10}; + margin-bottom: 28px; + + &:last-child { + margin-bottom: 0; + } +`; + +const HelperTextMetricName = styled.div` + ${typography.sizeCSS.medium} + margin-bottom: 6px; +`; + +const HelperTextMetricDescription = styled.div` + color: ${palette.highlight.grey10}; +`; + +const Term = styled.span` + font-weight: 600; +`; + +const HelperText: React.FC<{ + reportID: number; + activeMetric: string; +}> = ({ reportID, activeMetric }): JSX.Element | null => { + const { reportStore } = useStore(); + const currentMetric = reportStore.reportMetrics[reportID].find( + (metric) => metric.key === activeMetric + ); + + if (currentMetric === undefined) return null; + + return ( + + + + {currentMetric.display_name} + + + {currentMetric.description} + + + + + {currentMetric.definitions?.length > 0 && ( + Term Definitions + )} + {currentMetric.definitions?.map((definition) => ( + + {definition.term}: {definition.definition} + + ))} + + + {currentMetric.reporting_note && ( + + Reporting Note + {currentMetric.reporting_note} + + )} + + ); +}; + +export default HelperText; diff --git a/publisher/src/components/Reports/PublishConfirmation.tsx b/publisher/src/components/Reports/PublishConfirmation.tsx new file mode 100644 index 000000000..de26b031b --- /dev/null +++ b/publisher/src/components/Reports/PublishConfirmation.tsx @@ -0,0 +1,567 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { observer } from "mobx-react-lite"; +import React, { Fragment, useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import styled from "styled-components/macro"; + +import { trackReportPublished } from "../../analytics"; +import { + MetricContextWithErrors, + MetricDisaggregationDimensionsWithErrors, + MetricDisaggregationsWithErrors, + MetricWithErrors, +} from "../../shared/types"; +import { useStore } from "../../stores"; +import { printReportTitle, rem } from "../../utils"; +import errorIcon from "../assets/status-error-icon.png"; +import { Button } from "../Forms"; +import { palette } from "../GlobalStyles"; +import { showToast } from "../Toast"; +import { PublishButton } from "./ReportDataEntry.styles"; + +const CONTAINER_WIDTH = 912; +const CONTAINER_HORIZONTAL_PADDING = 24; + +const ConfirmationDialogueWrapper = styled.div` + width: 100vw; + height: 100vh; + background: ${palette.solid.white}; + position: fixed; + top: 0; + left: 0; + z-index: 2; + padding: 80px 0; + overflow: scroll; + display: flex; + flex-direction: column; + align-items: center; +`; + +const ConfirmHeaderContainer = styled.div` + background: white; + width: 100%; + position: fixed; + background: white; + top: 0px; + z-index: 1; + padding-top: 88px; + display: flex; + flex-direction: column; + align-items: center; +`; + +const ConfirmHeader = styled.div` + max-width: ${CONTAINER_WIDTH}px; + padding: 0 ${CONTAINER_HORIZONTAL_PADDING}px; +`; + +const ConfirmationDialogue = styled.div` + max-width: ${CONTAINER_WIDTH}px; + width: 100%; + display: flex; + flex-direction: column; + text-align: left; + padding: 0 ${CONTAINER_HORIZONTAL_PADDING}px; + padding-top: 176px; +`; + +const ConfirmationTitle = styled.div` + font-size: ${rem("64px")}; + font-weight: 500; + line-height: 64px; + letter-spacing: -0.02em; +`; + +const ConfirmationSubTitle = styled.div` + flex: 1; + margin-right: 16px; + font-size: ${rem("15px")}; + line-height: 24px; + font-weight: 500; +`; + +const Metric = styled.div` + display: flex; + flex: 1 1 auto; + justify-content: space-between; + border-top: 2px solid ${palette.solid.darkgrey}; + margin-bottom: 40px; + + @media only screen and (max-width: ${CONTAINER_WIDTH + + CONTAINER_HORIZONTAL_PADDING * 2}px) { + flex-direction: column; + border-top: 0; + } +`; + +const MetricOverviewWrapper = styled.div` + flex: 0 1 330px; + display: flex; + flex-direction: column; + justify-content: flex-start; + + @media only screen and (max-width: ${CONTAINER_WIDTH + + CONTAINER_HORIZONTAL_PADDING * 2}px) { + flex: 0 1 auto; + } +`; + +const MetricDetailWrapper = styled.div` + flex: 0 1 534px; + display: flex; + flex-direction: column; + justify-content: stretch; + + @media only screen and (max-width: ${CONTAINER_WIDTH + + CONTAINER_HORIZONTAL_PADDING * 2}px) { + flex: 0 1 auto; + } +`; + +const MetricValueLabel = styled.div` + display: flex; + justify-content: flex-start; + padding-bottom: 16px; + align-items: center; + font-size: ${rem("18px")}; + line-height: 24px; + font-weight: 700; + + @media only screen and (max-width: ${CONTAINER_WIDTH + + CONTAINER_HORIZONTAL_PADDING * 2}px) { + border-bottom: 1px solid ${palette.solid.darkgrey}; + } +`; + +const MetricValue = styled.div<{ missing?: boolean; error?: boolean }>` + margin-top: 8px; + font-size: ${rem("32px")}; + line-height: 1.5; + letter-spacing: -0.01em; + color: ${({ missing, error }) => + error ? palette.solid.red : missing && palette.highlight.grey8}; +`; + +const Breakdown = styled.div<{ missing?: boolean }>` + display: flex; + justify-content: space-between; + align-items: stretch; + border-bottom: 1px dashed ${palette.solid.darkgrey}; + padding: 4px 0; + font-size: ${rem("15px")}; + line-height: 24px; + font-weight: 500; +`; + +const DisaggregationBreakdown = styled(Breakdown)` + &:first-child { + padding-top: 0; + } + + &:last-child { + margin-bottom: 24px; + } +`; + +const BreakdownLabel = styled.div` + display: flex; + flex: 1; +`; + +const BreakdownValue = styled.div<{ missing?: boolean; error?: boolean }>` + display: flex; + flex: 1; + justify-content: flex-end; + font-style: ${({ missing }) => missing && "italic"}; + color: ${({ missing, error }) => + error ? palette.solid.red : missing && palette.highlight.grey8}; +`; + +const ContextContainer = styled(Breakdown)<{ verticalOnly?: boolean }>` + border-bottom: 1px solid ${palette.solid.darkgrey}; + padding: 8px 0; + + flex-direction: ${({ verticalOnly }) => (verticalOnly ? "column" : "row")}; + + @media only screen and (max-width: ${CONTAINER_WIDTH + + CONTAINER_HORIZONTAL_PADDING * 2}px) { + flex-direction: column; + } +`; + +const ContextTitle = styled(BreakdownLabel)` + font-weight: 700; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: flex-start; +`; + +const ContextValue = styled(BreakdownValue)` + justify-content: flex-start; +`; + +const ButtonContainer = styled.div` + padding: 16px 0; + display: flex; + flex: 1 1 auto; + align-items: center; + justify-content: space-between; + border-bottom: 2px solid ${palette.solid.darkgrey}; + + @media only screen and (max-width: ${CONTAINER_WIDTH + + CONTAINER_HORIZONTAL_PADDING * 2}px) { + border-bottom: 1px solid ${palette.solid.darkgrey}; + } +`; + +const PublishConfirmButton = styled(Button)` + margin-right: 8px; + flex: 1; +`; + +const TopPublishConfirmButton = styled(PublishConfirmButton)` + flex: 0 0 207px; + + @media only screen and (max-width: ${CONTAINER_WIDTH + + CONTAINER_HORIZONTAL_PADDING * 2}px) { + display: none; + } +`; + +const PublishConfirmPublishButton = styled(PublishButton)` + flex: 1; + + &::after { + content: "Publish Data"; + } +`; + +const TopPublishConfirmPublishButton = styled(PublishConfirmPublishButton)` + flex: 0 0 207px; + + @media only screen and (max-width: ${CONTAINER_WIDTH + + CONTAINER_HORIZONTAL_PADDING * 2}px) { + display: none; + } +`; + +const DisaggregationContainer = styled.div` + font-weight: 700; + font-size: ${rem("15px")}; + margin-top: 16px; + border-bottom: 1px solid ${palette.solid.darkgrey}; +`; + +const DisaggregationTitleContainer = styled.div` + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 16px; +`; + +const LabelLeft = styled.div` + display: inline; +`; + +const BreakdownContainer = styled.div` + padding-left: 20px; + margin-top: 8px; + border-left: 1px solid ${palette.solid.darkgrey}; +`; + +const DropdownArrowContainer = styled.div<{ collapsed?: boolean }>` + width: 16px; + height: 16px; + border-radius: 8px; + background: ${({ collapsed }) => + collapsed ? palette.highlight.grey2 : palette.highlight.lightblue2}; + display: flex; + align-items: center; + justify-content: center; + margin-left: 4px; + flex-shrink: 0; + + &:hover { + cursor: pointer; + } +`; + +const DropdownArrow = styled.div<{ collapsed?: boolean }>` + width: 6px; + height: 6px; + border: none; + border-bottom: 2px solid + ${({ collapsed }) => (collapsed ? palette.solid.grey : palette.solid.blue)}; + border-right: 2px solid + ${({ collapsed }) => (collapsed ? palette.solid.grey : palette.solid.blue)}; + transform: rotate(45deg) translate(-1px, -1px); + transform: rotate(${({ collapsed }) => (collapsed ? 225 : 45)}deg) + translate(-1px, -1px); +`; + +const ContextDropdownArrowContainer = styled(DropdownArrowContainer)` + margin-top: 3px; +`; + +const ErrorImg = styled.img` + margin-left: 4px; + width: 16px; + height: 16px; +`; + +const InnerErrorImg = styled(ErrorImg)` + transform: translate(0, 2px); +`; + +const MobileButtonContainer = styled.div` + background: ${palette.solid.white}; + position: fixed; + bottom: 0; + display: none; + justify-content: space-between; + width: 100%; + padding: 0 ${CONTAINER_HORIZONTAL_PADDING}px 8px; + + @media only screen and (max-width: ${CONTAINER_WIDTH + + CONTAINER_HORIZONTAL_PADDING * 2}px) { + display: flex; + } +`; + +const Disaggregation: React.FC<{ + disaggregation: MetricDisaggregationsWithErrors; +}> = ({ disaggregation }) => { + const [collapsed, setCollapsed] = React.useState(false); + const { display_name: displayName, dimensions } = disaggregation; + const hasError = !!dimensions.find( + (dim: MetricDisaggregationDimensionsWithErrors) => dim.error + ); + return ( + + + + {displayName} + {hasError && } + + setCollapsed(!collapsed)} + > + + + + {dimensions.length > 0 && !collapsed && ( + + {dimensions.map( + (dimension: MetricDisaggregationDimensionsWithErrors) => { + return ( + + + {dimension.label} + + {dimension.value?.toLocaleString("en-US") || + "Not Reported"} + + + + ); + } + )} + + )} + + ); +}; + +const Context: React.FC<{ context: MetricContextWithErrors }> = ({ + context, +}) => { + const [collapsed, setCollapsed] = React.useState(false); + const hasError = !!context.error; + return ( + + + + {context.display_name} + {hasError && } + + setCollapsed(!collapsed)} + > + + + + {!collapsed && ( + + {context.value?.toLocaleString("en-US") || "Not Reported"} + + )} + + ); +}; + +const MetricsDisplay: React.FC<{ + metric: MetricWithErrors; +}> = ({ metric }) => { + const hasError = !!metric.error; + return ( + + + {/* Overall Metric Value */} + + {metric.value?.toLocaleString("en-US") || "Not Reported"} + + + {metric.label} + {hasError && } + + + + + {/* Disaggregations > Dimensions */} + {metric.disaggregations.length > 0 && + metric.disaggregations.map((disaggregation) => { + return ( + + ); + })} + + {/* Contexts */} + {metric.contexts.length > 0 && + metric.contexts.map((context) => { + return ; + })} + + + ); +}; + +const PublishConfirmation: React.FC<{ + toggleConfirmationDialogue: () => void; + reportID: number; +}> = ({ toggleConfirmationDialogue, reportID }) => { + const [isPublishable, setIsPublishable] = useState(false); + const [metricsPreview, setMetricsPreview] = useState(); + const { formStore, reportStore, userStore } = useStore(); + const navigate = useNavigate(); + + const publishReport = async () => { + if (isPublishable) { + setIsPublishable(false); + + const finalMetricsToPublish = + formStore.reportUpdatedValuesForBackend(reportID); + + const response = (await reportStore.updateReport( + reportID, + finalMetricsToPublish, + "PUBLISHED" + )) as Response; + + if (response.status === 200) { + navigate("/"); + showToast( + `Congratulations! You published the ${printReportTitle( + reportStore.reportOverviews[reportID].month, + reportStore.reportOverviews[reportID].year, + reportStore.reportOverviews[reportID].frequency + )} report!`, + true + ); + const agencyID = reportStore.reportOverviews[reportID]?.agency_id; + const agency = userStore.userAgencies?.find((a) => a.id === agencyID); + trackReportPublished(reportID, finalMetricsToPublish, agency); + } else { + showToast( + `Something went wrong publishing the ${printReportTitle( + reportStore.reportOverviews[reportID].month, + reportStore.reportOverviews[reportID].year, + reportStore.reportOverviews[reportID].frequency + )} report!`, + false + ); + setIsPublishable(true); + } + } + }; + + useEffect(() => { + const { metrics, isPublishable: publishable } = + formStore.validateAndGetAllMetricFormValues(reportID); + setMetricsPreview(metrics); + setIsPublishable(publishable); + }, [formStore, reportID]); + + /** Prevent body from scrolling when this dialog is open */ + useEffect(() => { + document.body.style.overflow = "hidden"; + return () => { + document.body.style.overflow = "unset"; + }; + }, []); + + return ( + + + + Review + + + Take a moment to review the numbers that will be published. Click + the arrows to show the data for any disaggregations. + + + Back to Data Entry + + + + + + + {metricsPreview && + metricsPreview.map((metric) => { + return ; + })} + + + + Back to Data Entry + + + + + ); +}; + +export default observer(PublishConfirmation); diff --git a/publisher/src/components/Reports/PublishDataPanel.tsx b/publisher/src/components/Reports/PublishDataPanel.tsx new file mode 100644 index 000000000..d2d8b56f9 --- /dev/null +++ b/publisher/src/components/Reports/PublishDataPanel.tsx @@ -0,0 +1,65 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { observer } from "mobx-react-lite"; +import React from "react"; + +import { Title } from "../Forms"; +import HelperText from "./HelperText"; +import { + FieldDescription, + FieldDescriptionProps, + PublishButton, + PublishDataWrapper, +} from "./ReportDataEntry.styles"; + +const PublishDataPanel: React.FC<{ + reportID: number; + activeMetric: string; + fieldDescription?: FieldDescriptionProps; + toggleConfirmationDialogue: () => void; + isPublished?: boolean; +}> = ({ + reportID, + activeMetric, + fieldDescription, + toggleConfirmationDialogue, + isPublished, +}) => { + return ( + <> + + + <PublishButton + isPublished={isPublished} + onClick={() => toggleConfirmationDialogue()} + /> + + + {/* Metric Description, Definitions and Reporting Notes */} + + + {/* Displays the description of the field currently focused */} + {fieldDescription && ( + + )} + + + ); +}; + +export default observer(PublishDataPanel); diff --git a/publisher/src/components/Reports/ReportDataEntry.styles.tsx b/publisher/src/components/Reports/ReportDataEntry.styles.tsx new file mode 100644 index 000000000..b150e7734 --- /dev/null +++ b/publisher/src/components/Reports/ReportDataEntry.styles.tsx @@ -0,0 +1,99 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import styled from "styled-components/macro"; + +import { palette, typography } from "../GlobalStyles"; + +export const SIDE_PANEL_WIDTH = 360; +export const DATA_ENTRY_WIDTH = 644; +export const SIDE_PANEL_HORIZONTAL_PADDING = 24; +export const TWO_PANEL_MAX_WIDTH = DATA_ENTRY_WIDTH + SIDE_PANEL_WIDTH * 2; // data entry panel (644) + side panels (360 * 2) (each side panel includes 24px left and right padding) +export const ONE_PANEL_MAX_WIDTH = + DATA_ENTRY_WIDTH + SIDE_PANEL_WIDTH + SIDE_PANEL_HORIZONTAL_PADDING; // data entry panel (644) + left side panel (360) + right padding from the right side panel (24) +export const SINGLE_COLUMN_MAX_WIDTH = + DATA_ENTRY_WIDTH + SIDE_PANEL_HORIZONTAL_PADDING * 2; // data entry panel (644) + left and right padding (24 * 2) +export const BREAKPOINT_HEIGHT = 750; + +export const PublishDataWrapper = styled.div` + width: ${SIDE_PANEL_WIDTH}px; + position: fixed; + top: 0; + right: 0; + z-index: 1; + padding: 112px ${SIDE_PANEL_HORIZONTAL_PADDING}px 0 + ${SIDE_PANEL_HORIZONTAL_PADDING}px; + height: 100%; + + @media only screen and (max-width: ${TWO_PANEL_MAX_WIDTH}px) { + display: none; + } +`; + +export const PublishButton = styled.button<{ + disabled?: boolean; + isPublished?: boolean; +}>` + ${typography.sizeCSS.medium} + width: 315px; + height: 56px; + display: flex; + justify-content: center; + align-items: center; + background: ${({ disabled }) => (disabled ? "none" : palette.solid.blue)}; + color: ${({ disabled }) => + disabled ? palette.highlight.grey8 : palette.solid.white}; + border: 1px solid + ${({ disabled }) => + disabled ? palette.highlight.grey3 : palette.highlight.grey3}; + border-radius: 2px; + transition: 0.2s ease; + + &:hover { + cursor: ${({ disabled }) => (disabled ? "not-allowed" : "pointer")}; + background: ${({ disabled }) => + disabled ? "none" : palette.solid.darkblue}; + } + + &::after { + content: ${({ isPublished }) => + isPublished ? "'Unpublish and Edit'" : "'Review and Publish'"}; + } +`; + +export const FieldDescriptionTitle = styled.div` + margin-bottom: 10px; + color: ${palette.solid.darkgrey}; +`; + +export const FieldDescriptionContainer = styled.div` + ${typography.sizeCSS.normal} + padding-top: 16px; + color: ${palette.highlight.grey9}; +`; + +export type FieldDescriptionProps = { title: string; description: string }; + +export const FieldDescription: React.FC<{ + fieldDescription: FieldDescriptionProps; +}> = ({ fieldDescription }) => ( + + {fieldDescription.title} + {fieldDescription.description} + +); diff --git a/publisher/src/components/Reports/ReportDataEntry.tsx b/publisher/src/components/Reports/ReportDataEntry.tsx new file mode 100644 index 000000000..207559d06 --- /dev/null +++ b/publisher/src/components/Reports/ReportDataEntry.tsx @@ -0,0 +1,165 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { when } from "mobx"; +import { observer } from "mobx-react-lite"; +import React, { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; + +import { trackReportUnpublished } from "../../analytics"; +import { Report } from "../../shared/types"; +import { useStore } from "../../stores"; +import { printReportTitle } from "../../utils"; +import { PageWrapper } from "../Forms"; +import { Loading } from "../Loading"; +import { showToast } from "../Toast"; +import DataEntryForm from "./DataEntryForm"; +import PublishConfirmation from "./PublishConfirmation"; +import PublishDataPanel from "./PublishDataPanel"; +import { FieldDescriptionProps } from "./ReportDataEntry.styles"; +import ReportSummaryPanel from "./ReportSummaryPanel"; + +const ReportDataEntry = () => { + const [isLoading, setIsLoading] = useState(true); + const [loadingError, setLoadingError] = useState( + undefined + ); + const [activeMetric, setActiveMetric] = useState(""); + const [fieldDescription, setFieldDescription] = useState< + FieldDescriptionProps | undefined + >(undefined); + const [showConfirmation, setShowConfirmation] = useState(false); + const { reportStore, userStore } = useStore(); + const params = useParams(); + const reportID = Number(params.id); + const reportOverview = reportStore.reportOverviews[reportID] as Report; + const reportMetrics = reportStore.reportMetrics[reportID]; + const toggleConfirmationDialogue = async () => { + if (reportOverview.status === "PUBLISHED") { + const response = (await reportStore.updateReport( + reportID, + [], + "DRAFT" + )) as Response; + if (response.status === 200) { + showToast( + `The ${printReportTitle( + reportStore.reportOverviews[reportID].month, + reportStore.reportOverviews[reportID].year, + reportStore.reportOverviews[reportID].frequency + )} report has been unpublished and editing is enabled.`, + true, + undefined, + 4000 + ); + const agencyID = reportStore.reportOverviews[reportID]?.agency_id; + const agency = userStore.userAgencies?.find((a) => a.id === agencyID); + trackReportUnpublished(reportID, agency); + } else { + showToast( + `Something went wrong unpublishing the ${printReportTitle( + reportStore.reportOverviews[reportID].month, + reportStore.reportOverviews[reportID].year, + reportStore.reportOverviews[reportID].frequency + )} report!`, + false + ); + } + } else { + setShowConfirmation(!showConfirmation); + } + }; + + useEffect( + () => + // return when's disposer so it is cleaned up if it never runs + when( + () => userStore.userInfoLoaded, + async () => { + const result = await reportStore.getReport(reportID); + if (result instanceof Error) { + setLoadingError(result.message); + } + userStore.setCurrentAgencyId( + reportStore.reportOverviews[reportID]?.agency_id + ); + setIsLoading(false); + } + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + const updateActiveMetric = (metricKey: string) => setActiveMetric(metricKey); + const updateFieldDescription = (title?: string, description?: string) => { + if (title && description) { + setFieldDescription({ title, description }); + } else { + setFieldDescription(undefined); + } + }; + + useEffect(() => { + const firstEnabledMetric = reportMetrics?.find((metric) => metric.enabled); + if (reportMetrics && firstEnabledMetric) + updateActiveMetric(firstEnabledMetric.key); // open to the first enabled metric by default + }, [reportMetrics, reportID]); + + if (isLoading) { + return ( + + + + ); + } + + if (!reportMetrics || !reportOverview) { + return Error: {loadingError}; + } + + return ( + <> + + + + {showConfirmation && ( + + )} + + ); +}; + +export default observer(ReportDataEntry); diff --git a/publisher/src/components/Reports/ReportSummaryPanel.tsx b/publisher/src/components/Reports/ReportSummaryPanel.tsx new file mode 100644 index 000000000..9c2b9066b --- /dev/null +++ b/publisher/src/components/Reports/ReportSummaryPanel.tsx @@ -0,0 +1,412 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { observer } from "mobx-react-lite"; +import React from "react"; +import { useNavigate } from "react-router-dom"; +import styled from "styled-components/macro"; + +import { Metric } from "../../shared/types"; +import { useStore } from "../../stores"; +import { + printCommaSeparatedList, + printDateRangeFromMonthYear, + printElapsedDaysMonthsYearsSinceDate, +} from "../../utils"; +import successIcon from "../assets/status-check-icon.png"; +import errorIcon from "../assets/status-error-icon.png"; +import { + GoBackToReportsOverviewLink, + MetricsSectionTitle, + PreTitle, + Title, +} from "../Forms"; +import { palette, typography } from "../GlobalStyles"; +import HelperText from "./HelperText"; +import { + BREAKPOINT_HEIGHT, + FieldDescription, + FieldDescriptionProps, + ONE_PANEL_MAX_WIDTH, + PublishButton, + SIDE_PANEL_HORIZONTAL_PADDING, + SIDE_PANEL_WIDTH, + TWO_PANEL_MAX_WIDTH, +} from "./ReportDataEntry.styles"; + +export const ReportSummaryWrapper = styled.div` + width: ${SIDE_PANEL_WIDTH}px; + height: 100%; + position: fixed; + top: 0; + left: 0; + z-index: 1; + padding: 96px ${SIDE_PANEL_HORIZONTAL_PADDING}px 0 + ${SIDE_PANEL_HORIZONTAL_PADDING}px; + background: ${palette.solid.white}; + + @media only screen and (max-width: ${ONE_PANEL_MAX_WIDTH}px) { + display: none; + } +`; + +const PUBLISH_CONFIRMATION_BUTTON_HEIGHT_AND_PADDING = 128; + +export const ReportSummaryProgressIndicatorWrapper = styled.div` + margin-top: 28px; + height: 37vh; + overflow-y: scroll; + + &::-webkit-scrollbar { + -webkit-appearance: none; + width: 5px; + } + &::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: ${palette.highlight.grey8}; + box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); + -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); + } + + @media only screen and (max-width: ${TWO_PANEL_MAX_WIDTH}px) { + height: 30vh; + } + + @media only screen and (max-height: ${BREAKPOINT_HEIGHT}px) { + height: calc(55vh - ${PUBLISH_CONFIRMATION_BUTTON_HEIGHT_AND_PADDING}px); + padding-bottom: 50px; + } +`; + +const ReportSummarySection = styled.a` + ${typography.sizeCSS.normal} + height: 24px; + display: flex; + align-items: center; + justify-content: flex-start; + position: relative; + text-decoration: none; + margin-bottom: 2px; + border-radius: 2px; + color: ${palette.highlight.grey8}; + transition: 0.2s ease; + + &:hover { + cursor: pointer; + color: ${palette.solid.darkgrey}; + } +`; + +const MetricDisplayName = styled.div<{ + activeSection?: boolean; +}>` + ${({ activeSection }) => + activeSection && `color: ${palette.solid.darkgrey};`}; + border-bottom: 2px solid + ${({ activeSection }) => + activeSection ? palette.solid.blue : `transparent`}; + max-width: 238px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +`; + +const ReportStatusIcon = styled.div<{ + metricHasError?: boolean; + metricHasEntries?: boolean; +}>` + width: 16px; + height: 16px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 100%; + margin-right: 8px; + + background: ${({ metricHasError }) => { + if (metricHasError) { + return palette.solid.red; + } + + return `transparent`; + }}; + color: white; + border: 1px solid ${palette.highlight.grey4}; +`; + +export const NotReportedHeader = styled.div` + ${typography.sizeCSS.normal} + color: ${palette.highlight.grey8}; + margin-top: 16px; + margin-bottom: 2px; +`; + +export const EditDetails = styled.div` + width: 307px; + position: fixed; + bottom: 61px; + + @media only screen and (max-width: ${TWO_PANEL_MAX_WIDTH}px) { + display: none; + } + @media only screen and (max-height: 750px) { + display: none; + } +`; + +export const EditDetailsTitle = styled.div` + ${typography.sizeCSS.small} + padding-top: 8px; + border-top: 1px solid ${palette.solid.darkgrey}; +`; + +export const EditDetailsContent = styled.div` + ${typography.sizeCSS.normal} + color: ${palette.highlight.grey9}; + margin-bottom: 18px; +`; + +const PublishContainer = styled.div` + display: none; + + @media only screen and (max-width: ${TWO_PANEL_MAX_WIDTH}px) { + display: block; + position: absolute; + border-top: 1px solid ${palette.highlight.grey9}; + background: ${palette.solid.white}; + right: 0; + bottom: 0; + left: 0; + margin: 0 24px; + padding: 24px 0; + } + + @media only screen and (max-height: ${BREAKPOINT_HEIGHT}px) { + border: none; + } +`; + +const LeftPublishButton = styled(PublishButton)` + margin-top: 24px; +`; + +const ReportStatusIconComponent: React.FC<{ + metricHasValidInput: boolean; + metricHasError: boolean; + activeMetric: string; + metric: Metric; +}> = ({ metricHasError, metricHasValidInput, metric, activeMetric }) => { + return ( + { + document + .getElementById(metric.key) + ?.scrollIntoView({ behavior: "smooth" }); + }} + > + + {/* Error State */} + {metricHasError && ( + + )} + + {/* Validated State [Placeholder] */} + {!metricHasError && metricHasValidInput && ( + + )} + + + {metric.display_name} + + + ); +}; + +const ReportSummaryPanel: React.FC<{ + reportID: number; + activeMetric: string; + fieldDescription?: FieldDescriptionProps; + toggleConfirmationDialogue: () => void; +}> = ({ + reportID, + activeMetric, + fieldDescription, + toggleConfirmationDialogue, +}) => { + const navigate = useNavigate(); + const { formStore, reportStore, userStore } = useStore(); + const { + editors, + last_modified_at: lastModifiedAt, + month, + year, + frequency, + status, + } = reportStore.reportOverviews[reportID]; + + const checkMetricForErrorsInUpdatedValues = (metricKey: string) => { + let foundErrors = false; + + if (formStore.metricsValues[reportID]?.[metricKey]?.error) { + foundErrors = true; + } + + if (formStore.disaggregations[reportID]?.[metricKey]) { + Object.values(formStore.disaggregations[reportID][metricKey]).forEach( + (disaggregation) => { + Object.values(disaggregation).forEach((dimension) => { + if (dimension.error) { + foundErrors = true; + } + }); + } + ); + } + + if (formStore.contexts[reportID]?.[metricKey]) { + Object.values(formStore.contexts[reportID][metricKey]).forEach( + (context) => { + if (context.error) { + foundErrors = true; + } + } + ); + } + + return foundErrors; + }; + + const metricsBySystem = reportStore.reportMetricsBySystem[reportID]; + const showMetricSectionTitles = Object.keys(metricsBySystem).length > 1; + + return ( + + + navigate("/")} /> + + Report Summary + + + {Object.entries(metricsBySystem).map(([system, metrics]) => { + const { enabledMetrics, disabledMetrics } = metrics.reduce<{ + enabledMetrics: Metric[]; + disabledMetrics: Metric[]; + }>( + (acc, currentMetric) => { + if (currentMetric.enabled) { + acc.enabledMetrics.push(currentMetric); + } else { + acc.disabledMetrics.push(currentMetric); + } + return acc; + }, + { enabledMetrics: [], disabledMetrics: [] } + ); + + return ( + + {showMetricSectionTitles ? ( + {system} + ) : null} + {enabledMetrics.map((metric) => { + const foundErrors = checkMetricForErrorsInUpdatedValues( + metric.key + ); + + return ( + + ); + })} + + {/* Metrics Not Reported */} + {disabledMetrics.length > 0 && ( + Not Reported + )} + {disabledMetrics.map((metric) => { + return ( + + ); + })} + + ); + })} + + + + Date Range + + {printDateRangeFromMonthYear(month, year, frequency)} + + + Editors + + {editors.length + ? printCommaSeparatedList(editors) + : userStore.nameOrEmail} + + + Details + + {editors.length === 1 && + !lastModifiedAt && + `Created today by ${editors[0]}`} + + {editors.length >= 1 && + lastModifiedAt && + `Last modified ${printElapsedDaysMonthsYearsSinceDate( + lastModifiedAt + )} by ${editors[editors.length - 1]}`} + + {!editors.length && ``} + + + + + {/* Metric Description, Definitions and Reporting Notes */} + + + {/* Displays the description of the field currently focused */} + {fieldDescription && ( + + )} + { + /** Should trigger a confirmation dialogue before submitting */ + toggleConfirmationDialogue(); + }} + /> + + + ); +}; + +export default observer(ReportSummaryPanel); diff --git a/publisher/src/components/Reports/Reports.styles.tsx b/publisher/src/components/Reports/Reports.styles.tsx new file mode 100644 index 000000000..73c1ff2d1 --- /dev/null +++ b/publisher/src/components/Reports/Reports.styles.tsx @@ -0,0 +1,254 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import styled from "styled-components/macro"; + +import { HEADER_BAR_HEIGHT, palette, typography } from "../GlobalStyles"; + +const COLLAPSED_INNER_COLUMNS_WIDTH = 846; + +export const PageHeader = styled.div` + width: 100%; + background: ${palette.solid.white}; + position: fixed; + z-index: 2; +`; + +export const ReportsHeader = styled(PageHeader)` + top: ${HEADER_BAR_HEIGHT}px; +`; + +export const PageTitle = styled.div` + ${typography.sizeCSS.headline} + margin-top: 40px; + padding: 0px 22px; +`; + +export const TabbedBar = styled.div<{ noPadding?: boolean }>` + ${typography.sizeCSS.normal} + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + position: relative; + padding: ${({ noPadding }) => (noPadding ? `none` : `0px 22px`)}; + border-bottom: 1px solid ${palette.highlight.grey9}; +`; + +export const TabbedOptions = styled.div` + display: flex; + align-items: center; +`; + +export const TabbedItem = styled.div<{ + selected?: boolean; + capitalize?: boolean; +}>` + padding: 24px 0 16px 0; + margin-right: 20px; + color: ${({ selected }) => + selected ? palette.solid.darkgrey : palette.highlight.grey9}; + border-bottom: ${({ selected }) => + selected ? `3px solid ${palette.solid.blue}` : `3px solid transparent`}; + transition: color 0.3s ease; + ${({ capitalize }) => capitalize && `text-transform: capitalize;`} + + &:hover { + cursor: pointer; + color: ${palette.solid.darkgrey}; + } +`; + +export const TabbedActionsWrapper = styled.div` + display: flex; + gap: 15px; +`; + +export const ReportActions = styled.div` + display: flex; +`; + +export const ReportActionsItem = styled.div<{ + disabled?: boolean; +}>` + display: flex; + align-items: center; + margin-left: 16px; + transition: 0.2s ease; + color: ${({ disabled }) => + disabled ? palette.highlight.grey8 : palette.solid.blue}; + + &:hover { + ${({ disabled }) => + !disabled + ? ` + cursor: pointer; + opacity: 0.8; + ` + : ` + cursor: default; + `} + } +`; + +export const ReportActionsSelectIcon = styled.div<{ + disabled?: boolean; +}>` + width: 11px; + height: 11px; + display: flex; + justify-content: center; + align-items: center; + margin-left: 4.5px; + border: 1px solid + ${({ disabled }) => + disabled ? palette.highlight.grey8 : palette.solid.blue}; + border-radius: 50%; + + &::after { + content: ""; + height: 1px; + width: 6px; + background-color: ${({ disabled }) => + disabled ? palette.highlight.grey8 : palette.solid.blue}; + } +`; + +export const ReportActionsNewIcon = styled(ReportActionsSelectIcon)` + &::before { + content: ""; + position: absolute; + height: 6px; + width: 1px; + background-color: ${palette.solid.blue}; + } +`; + +export const Table = styled.div` + width: 100%; + padding: 212px 0 50px 0; +`; + +export const Row = styled.div<{ + noHover?: boolean; + selected?: boolean; +}>` + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 22px; + color: ${({ noHover }) => + noHover ? palette.highlight.grey9 : palette.solid.darkgrey}; + transition: 0.3s ease; + ${({ noHover }) => + noHover ? typography.sizeCSS.normal : typography.sizeCSS.large} + ${({ selected }) => + selected && `background-color: ${palette.solid.lightgreen};`} + + &:hover { + ${({ noHover }) => + noHover + ? `` + : `cursor: pointer; + background-color: ${palette.solid.lightgreen}; + `} + } +`; + +export const LabelRow = styled(Row)` + padding: 10px 22px; + + &:hover { + cursor: unset; + background-color: unset; + } +`; + +export const Cell = styled.div<{ capitalize?: boolean }>` + width: 100px; + display: flex; + flex: 1 4 auto; + justify-content: flex-start; + align-items: center; + position: relative; + font-size: 1.2rem; + text-transform: ${({ capitalize }) => capitalize && "capitalize"}; + padding-right: 40px; + white-space: nowrap; + + span { + padding-right: 4px; + overflow: hidden; + text-overflow: ellipsis; + } + + &:first-child { + flex: 2 1 auto; + } + + &:last-child { + flex: 2 1 auto; + justify-content: flex-end; + padding-right: unset; + } + + @media only screen and (max-width: ${COLLAPSED_INNER_COLUMNS_WIDTH}px) { + &:not(:first-child, :last-child) { + display: none; + } + } +`; + +export const LabelCell = styled(Cell)` + ${typography.sizeCSS.normal} + color: ${palette.highlight.grey9}; +`; + +export const AdditionalEditorsTooltip = styled.div` + ${typography.sizeCSS.normal} + padding: 10px 20px; + background: ${palette.solid.blue}; + color: ${palette.solid.white}; + position: absolute; + z-index: 1; + top: 32px; + border-radius: 2px; + text-align: center; + box-shadow: 2px 2px 8px ${palette.highlight.grey5}; +`; + +export const NoReportsDisplay = styled.div` + display: flex; + justify-content: center; + align-items: center; + margin-top: 50px; +`; + +export const EmptySelectionCircle = styled.div` + width: 16px; + height: 16px; + border: 1px solid ${palette.highlight.grey4}; + border-radius: 50%; + margin-right: 8px; +`; + +export const SelectedCheckmark = styled.img` + width: 16px; + height: 16px; + margin-right: 8px; +`; diff --git a/publisher/src/components/Reports/index.ts b/publisher/src/components/Reports/index.ts new file mode 100644 index 000000000..f8bb9cc3e --- /dev/null +++ b/publisher/src/components/Reports/index.ts @@ -0,0 +1,18 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./Reports.styles"; diff --git a/publisher/src/components/Toast/Toast.ts b/publisher/src/components/Toast/Toast.ts new file mode 100644 index 000000000..8143141fb --- /dev/null +++ b/publisher/src/components/Toast/Toast.ts @@ -0,0 +1,118 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import checkIconWhite from "../assets/status-check-white-icon.png"; +import { HEADER_BAR_HEIGHT, palette, typography } from "../GlobalStyles"; + +type ToastColor = "blue" | "red" | "grey"; + +export const showToast = ( + message: string, + check = false, + color: ToastColor = "blue", + timeout = 2500, + preventOverride?: boolean +) => { + const animationTransform = [{ maxWidth: "0px" }, { maxWidth: "100%" }]; + const animationTransformReverse = [ + { maxWidth: "700px" }, + { maxWidth: "0px" }, + ]; + + const activeToast = document.querySelector("#toast"); + + if (preventOverride && activeToast?.textContent === message) return; + + if (activeToast) { + activeToast.animate(animationTransformReverse, { + duration: 600, + fill: "forwards", + easing: "ease", + }); + document.body.removeChild(activeToast); + } + + const toastElementWrapper = document.createElement(`div`); + const toastElement = document.createElement(`div`); + const checkIcon = document.createElement(`img`); + toastElement.innerText = message; + toastElementWrapper.id = "toast"; + toastElementWrapper.style.cssText = ` + position: fixed; + top: 0; + left: 65px; + z-index: 100; + overflow: hidden; + `; + toastElementWrapper.appendChild(toastElement); + + let toastBackgroundColor = palette.solid.blue; + switch (color) { + case "red": + toastBackgroundColor = palette.solid.red; + break; + case "grey": + toastBackgroundColor = palette.solid.white; + break; + default: + break; + } + toastElement.style.cssText = ` + width: auto; + height: ${HEADER_BAR_HEIGHT}px; + display: flex; + align-items: center; + background: ${toastBackgroundColor}; + color: ${color === "grey" ? palette.solid.grey : palette.solid.white}; + padding: 20px 24px; + border-radius: 2px; + white-space: nowrap; + `; + checkIcon.src = checkIconWhite; + checkIcon.alt = ""; + checkIcon.style.cssText = ` + width: 16px; + height: 16px; + margin-right: 8px; + ${typography.sizeCSS.normal} + `; + + if (check) toastElement.prepend(checkIcon); + document.body.appendChild(toastElementWrapper); + + toastElementWrapper.animate(animationTransform, { + duration: 800, + fill: "forwards", + easing: "ease", + }); + + // a timeout of -1 keeps the toast from timing out + if (timeout !== -1) { + setTimeout(() => { + toastElementWrapper.animate(animationTransformReverse, { + duration: 600, + fill: "forwards", + easing: "ease", + }); + Promise.all( + toastElementWrapper + .getAnimations({ subtree: true }) + .map((animation) => animation.finished) + ).then(() => toastElementWrapper.remove()); + }, timeout); + } +}; diff --git a/publisher/src/components/Toast/index.ts b/publisher/src/components/Toast/index.ts new file mode 100644 index 000000000..f4affc669 --- /dev/null +++ b/publisher/src/components/Toast/index.ts @@ -0,0 +1,18 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./Toast"; diff --git a/publisher/src/components/assets/check-icon.svg b/publisher/src/components/assets/check-icon.svg new file mode 100644 index 000000000..c11f1c863 --- /dev/null +++ b/publisher/src/components/assets/check-icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/publisher/src/components/assets/cloud-upload-icon.svg b/publisher/src/components/assets/cloud-upload-icon.svg new file mode 100644 index 000000000..0ef5b8f92 --- /dev/null +++ b/publisher/src/components/assets/cloud-upload-icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/publisher/src/components/assets/dark-close-icon.png b/publisher/src/components/assets/dark-close-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..98f9ced50025f85c919b46fea0142cb2f3f380ac GIT binary patch literal 1758 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 literal 0 HcmV?d00001 diff --git a/publisher/src/components/assets/error-icon.svg b/publisher/src/components/assets/error-icon.svg new file mode 100644 index 000000000..201a33330 --- /dev/null +++ b/publisher/src/components/assets/error-icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/publisher/src/components/assets/file-icon.svg b/publisher/src/components/assets/file-icon.svg new file mode 100644 index 000000000..33ee84c52 --- /dev/null +++ b/publisher/src/components/assets/file-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/publisher/src/components/assets/info-red-icon.png b/publisher/src/components/assets/info-red-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..09d581df14fecd656ade72e6b7b406f9b11c1702 GIT binary patch literal 441 zcmV;q0Y?6bP)M3wj3O&*OJ$O>N9D44Udg2%PtMIHiy zK)k%V1mA2F2)y@qm`(l+hvzr%?=$N~l6w6Fv)jK2Qjzw)bKw;LM9vKj2BqmDy(~Ns z08Br*S0&*6hI5y}>7VK+^?F;<^a_z?F4%06Rx0P;CodELJiw-^woRmk*%8@arpTk1 j#oqhTF?{3>@vrj600000NkvXXu0mjfX2ZkN literal 0 HcmV?d00001 diff --git a/publisher/src/components/assets/jc-logo-green-vector.png b/publisher/src/components/assets/jc-logo-green-vector.png new file mode 100644 index 0000000000000000000000000000000000000000..b9cb71a0db6da8427003aad359a66ac1cd48b293 GIT binary patch literal 3652 zcmV-K4!iM*P)BoR6N3x;#52W0peJ8L{+gX9y_a& z*h!U^KrB#|k5%kSt4^tW0vtnt$Xm}hGjD(Hj(00*1$cnfa^JmuJ2P+o=gCps(2iO( zLkr|+nV%LZr9Jv0-l_EN)o6|XUFCNU_#X3nG1Uw+R40JgS$f2OwX!isy~^*W%p^yV zTtr*UfP~J_Me4+TstFoYC+rAf!vscD6&#%(8tKPV=9Y%Cjh;+0~FgU?lyAjkOk$7Ydn0hU0 zkBnc9HVnVcsrVJ3Iq}y(Yz`5<=M(xiIV#P2kR3nJPDE^YJ`fHU ztnffWOb`|E*fd`p$y^w(Ytd~BGXo40w$Hym;`!LgUJ1V@y+0{fnJm(W$ukzMTl9O6 zJ%Y&Yf;7TzG#SA^`dbw9oB;3mCp^Bv^FAhss1rS2mfsxxKq|5=LlSpSYN4NI>Y(p@ zD(_wP5r6x!eS5)(f)sqf&u^1Pai7Vz5b(S~f2P03PbQI6%}Rd}cbKEt>F)}o3+!LP zfEA0OcLf26d?O1dVR>Ux#O6(B{m|-`#h7-wY@!U80UNnN(fQyV{ zrI@{0Ws-<*lm5*ggAO}1tMGWO($y8dzsL4I>9MDCQSl-HZ~wA!#oqSm$`=25P@Y@J%fc_5+nyq zK(5zC3)(MyCpL?o@cbj5{~h0ZGRI|%RK12Y{qE%wi|IQ2AnEaSQ!KUWA{_l$f+cMT zGPg)YbB-BsPsU(5VRfCPclhn0J@-lV^O^1X6H+~e?%yL=X7$?}@^>Rk57&%XxVs+- zdVI|9e4E_M@I(-D+3#}Tu}~Tx0@Wl~*_{fB_NQ#TPK1En!e}CTJuv-sjF4K_Ekho= z+!te&a`rS}U2J4AcAuY7jGPzOb{c3Mtj+HwL?YIG z`$n78V6Bt7tF4Tvloae>j{d%E_T7|qY)6(@;!LkvQIuw(tPAzs*B$6Ot7 zzyPb-V0}u3%iCtHmq{}wVqM#*T&7V8YFk*U`b@IU4O<(c9`fZ4QiHi^1P2|D3C2+i z5x{k!@Z0-M*3FM85BkY|yeC%ivR@P3MFfRl{j$GJxetsa+BxP>&e6MtT=p9?EW{~Z zrxb}zga7b19wc}9o0r6&!$&&_EL88G(}!$zKC(zIsKuPwkt3cDyq}6MZ*X#=^X9Vk z`L`x3`9DZQz5t2roU;JKaTwQRuD|E8AcBR5rum)_XE*3i;+LzIX2-#U z+dAW`hfC~6jJjwfA=BZ@7gXyzb_e)_l$R1fN(?qCrBJ5Oma0i+av$BhS{LB)Fx%`S*R&%~%xCP9*{?CnqqLYCM+; zqb)b`A*5D6iM92li948pfZ=_ zg7pS*s}zcSIrIBgEji$MG2=;`G4&=H$(b=DfpZHMEiE$x5~56;l@TCLf8Vnhd*1wH zeV`T4MI)|fm*&9mzdLn=mZ|8*@R%=*Em#t8kmH4JX*j8KxD6}JSde4f;B zC02Y>$F9B-g|u#MdZ&pET%@-VO&T;K1MWR$M6Xh&XD~DL0WbGi5!FSBk2UMbeP5c* zZjqLIdJ+(5X=aOq7BHwob-=9n-tElog~C1xcX<;IQqU!>ex9}91g)B}r5`8ho>mt< zsblZj-%(*+-*VfKy4|$5VZHBDo{eZv>6ph~Rs8axV=Mbs2!cX|G{A7iq+_vdgtum% zNCS2_gpUCtOVXnf0!~UWD>i@G-dQAVfS(s1tVwvp9YnyZMO?FzvL>Vj!7b9`5J>iS z3gf_G$z17hEPX^;EA!+mO5|v4#_C5=VX8OIk}l;a2QP*AEG=rtYYtej*6ww_ENLp68C_*S7_1G>TFwnyN zOy(8HToZI#gC2A<(7@AvQ(hZStDVi99!nPi2S~~RMW4m!ERVyjMfTxs3qU*-LsGT2 z`1`38|BhvcLg66vrw$69As8^Cyna@!XNBl*Nxp^7e}(2+b&*zaDZ3VY@Ja-PdrS;m zQ6lc6$o0So-Sv)0#EEqgoD|r-&54G-2&TpM_ntJ*l;9vGEqi}o4xm=-Bu*D;bx*fR zL$qxZvC!DUNxONu(0#y%|DU-mJxwr%tdvFJ0-ppP=Jv?iDB(f z1!znm)|=0bNTZ!qBYMxGtfB>%GN=Ut>*k+x#7-k#cQ~=9Rq@HG#q9&>NyVl4>Nzmh zm+v?^Q-Y($qX%uqKyw1I*xCP5xhtXKbSxp{4i&9#lM#f!1Hk9K;}ag!vsexKo{@ix z@|KPUCkmMJgGF%ry!Kc89y$yV{}0&DK4m|9Si%j*ES&gobWOaCp5ynH<+sD+RLPor zY$+W%z6&DOCG~@mpe)JQ9?_v05wTt2zQ(nWEV0>rV-KEt=@d?Y$s&!GV`^PMg_Vpj+^@$t$F)AT6`G%&49K?4$lMUUMS>2-b%e2) z6H$I#qIl-IML&-@fTnn?l*Wo}(oXU0_##zi-3(S7#phK@`O!}HQ^1xp;n zvTvy&jrlg-TbI8p5UZ%X4)}ztDCHDxlk!H~Xi5jT8l{D&SRyP~;5RDtmr+K(UhOnb z{RhO`;x-U(uS-r{?%quTAe>NY1&1>)PzC<7>a?qw3ED(SO+Zj0sb5VBp zjj;v?2C|g}BtMNwT55p$cbE$2rj-C~(R9ZCkCz-Y0Ex0^4Np5%Gt|4o>iDD5nD&mR z!)VvSSIK@}6zV0oX{D4hRMW3FWLi1mOC)z~B{@J1lxh$04-h1)E(-wE#bZ5uLI3$43+`pxSq&bE4M}Z^zeB$!vz7Il zKEIM^o%H)6Sx7*jqE7QL8bZ=~y7xzcX`3WfQ+qFN@}$dGf#>h>P6cy)^jY_ zQztl)CzuVh^Z@bW_K2`F3Czz=qYu|KNI7G9U~{TU z2}=5(z(|r-VIx{uy0vLLramfEE`w!LeYtm8sU$1Opyo((s*+)eP10hxNK#}WA6^2= zS4alxEHcRlO-~j!VTMf*_6WeaL}W1rVA@TYH}c~X;TFEW!P$enSq*kd!CTIv};`m!CNt8mj zgj26;S#g7T+l24r+@G_}&5dKTjAKAUU=^;{u6jUTLi?HdO79a{dOA8Z!2Hj7?hP@d z6l&UzT8R$@F)jyaKozP??MPlX?x>k(g9ggAA`l+lS1lY8aR-d!1D zZM14EHC+fa!}yt}KOu{taEDFVhbOn8JACan5T8j8P;=qP+Qru|(9$R{JpSxp{{jEq zr1t26*gN4`?kxLZ$1riCo}Wb{3`j%(WH&%UWCS{|Hk)Mj$D8Crh|#r&{x9FYY%SpS z8mdIP^{AI-&D`;u;-v697>aspWt1Owvno?VjRf{yu_N1k_4h68bUGxIdg7R-1WoE0NZxn(d(o;ATNy+#szT!wYVR_#Q(;l8#% zSReS~$Hx^kMyZ9q3XPccYfDaHyR8HriaFt&$P4>$qZMSdpxNP86bOeHH~s8|;WA8< z+e_kjZOt!tB*;a!K?YE}Q6tx(KXNAUVoec!2uY@m;*$_pJz#Q}PonX1*0jD}AXYfo zC1UZTZr0p`o?!NYhO&^!K$Rs91gn$4kvQuWrPCU0*P8BdWeD-J40eU**o-PXeZyEo^>?x$Bt^n}@w^gs zK_h3nMZ6K7)R*#T4w@S5kW`dt&g^2iP%X?k&+2X4jjrwj)yO%V-(WruDlr9q^@=Nd zj-*k?NXvc6CrppPHt*uA!)(vXds`#X1`XzaIH8+qsc9tf7;AzJi=L@j1Uf_H%CE1+ z?My!X^2Ic!PQSlxc1EnrbbGV^&po6DQ9rLHfu?=;%u>;8TVT|$&qXbWan$@9na=-7 z;3f42CMgt0Q4`1aueQfk#T-hv-5ujx%MjPRxvC|Ce}jE|fPH3O(+H*LX=Kth_2-@YT-AJqqu0Dc zSk6;SDxRWlm`&j zOZW)&>7MEM7e4WmYe?`m2oYP)Y#L z*KY13ujk~{P)2w?U-+tk;?VgBA zjWNphI+UEccS3W{XHg+r@}y0yq#%@qH@wHnnVKW?hP-t;b`j`;sj-TZ3Mz|ZoM4zc zq}Q20mvsyKHkRDU)AQ-hef$+N@72@y|i(Po(I{}!y?!ct&~csp^mlTy98BF zC*s*!KC(IDRqY~^()f|8w^1*8WE{da`v1HWw-g^dxjno!B=XAhHgnHII*DvSkxPW~ zx5y3OcetCT4_J&kB&nKgV@Y;^HtyLXZWjRTa)|56fB8GXvY{??1K(o#{yPf_l{uGu zJBbKQb7o}LTurjl@=PsFqTX#*=MWgzQi9_5z@%Qk?sg6Kc}_6N@7o?y{qTaLBlD7d z!J$`1x$loT`m+x7+TnP6Sjc2weXasjaWDefK)w@y06z{!xbFS&Z1hFx3U`}oLmA1H z+-vnXu4Z#CS+(5#qmX}}%ogQXWzZdbIw4kpOM!bt2!w(sH@l@yGUaxekQ0P~TL3!0 zN8z*#UNptuSdcBb8E3j4y)H{Zv!KPs3~U=MxPOnqUg`d!Zf)k>@P5c;M+2&_)IHq+ zNu&STM3wWOiWaaXT{a*u9yBWZ+LTUbE^o;A#1wfM-uXFy8 zQ<(^tPhaie8^)o7Ra%NS5K(q1gE$PZ>*_od#>YoHP2#wO*d2@*gXT-LAv^>Xz@u6m zaP!&W2W8Upq4`+i>^Xg}FW+k}JZN^EclqKiRS+_BbX$ZY93C`nxpemB@yvt7MiI^e z^0r=a>i2)D_i=ocG^xv3@bRKk43{s9?g@G2i1j_9H`?^O!&H`y4g?zR61>M%^Pn zxu2!nbnh@@W|Nc>KxYWTr~CBWw||O^zP#9`bM{W$tBzG&#m~+vXFEQ$Ze%|i8=0C4 z_556FSu>buN=fl6MQ5rI=q^(HA*m~~%HbU-Z+*Tj-bHumm17>X&%f4PDvzE2Rk*YZ zmwSfSvQmPPjmg3mMq$fxraXKt^%NQ+`*6$&8fHq2u+wqM-uj@EN(f}FujWvkSru2< zo$`9v)g3(=fqQGBJ>)2)h1W=XuC~>0KIHjE8Wb;(>}%RB)TICYd;$Rgo>BN`r-)fi zpTTkhA)Ml}YiMg8bAQN_N62Y?!|(f?mbZNRpdR-cB<1?5{Bb@k<&3^1x3SQ+zP&#A z76}Dyx0s`~BFb;ZMQ7QI#-?#5)cZ%iWs9~C{K4Q0f_k967$H|6_=_ZJjYE#WJE}pL zSamW62fH(P6iR^3L0`U?SF2L7a;G)D>+lUVvVX)O;B|?e=;9^on$O~rFkftdJ<$Pn zur~Ofg*@ID_lYKK@%HuL1P^iWGwN-jput;Ug78t%-kjpgWTInM2C5JIOHTfTgL$C_-}L z-ht{YGN14{1Umdc(`wY446(NVHN4(&)NOd54co7~ZVG}2*k4yO*#S%Y=L{(XFyj%7 z#_#B%*UlNMH2nEzjI8^MnocwDq0wtaeGlLjEdIcQ(^kH&HUSYX3D1U6jlBbSIi%Hx z1EA3@zoT|yw4-p0bQVxzs*H5pzJqj+zYARqsG1|xoS^kPn)qL4xQ?8qdh?cSXx;KN z^hxj5K3M;nWJnKXJ9;UK&SJ9R&PP+oM(+9T%Sj{}@IiCJI>vcCL}D{{03pu+?iNYfh(N@`p9b-Hl~#8> zjqe@v?kFcABzY3j^bIkZZ^P5vdaq^CVdUzZyY^slD~T+hXcc$fQFx#uR%fsSH;#J528UKoN!lx!Hwp4*~W##6cm$IqCNL2D1M@|8Mj9{tfd=q*$^PqHh zT0*LK5gyJLb%;iIfo05kZC9u}>e}8_)gJLT#C4@I6h`T&p>@m;rWN)KJJ~>owoTBdzHq?SI%nVw}j_1 z$!u0~$#|2t?Y|T}>z+bCUG50Ct$(bsbh0^;Kw`Cfvcn{nU{zI^0eLKu_z)R48V_)D zSru7#plv$Ez;ZvWVv2&qquyqneUWlYdHNC=hmM}@9(fCS;|J(?<|0GCo_>=cFvii- zX(_B?wb#;AN2Tt~POm|c5kk^sQf;{~Cu8KqZ#;438tN=xOASfx;rQ4h{q>h8mx)#p z|M%5MC#g)!vt=gw0=sIg?V3twOvuS-Z+(8bR)dSWx^WRUStW~s!Rpc=neDw6k+SWm zU%r)auh%YSi$@imoaB${f)L@1r5@@oGj0YAKey-#esE0Dx)SWgb0Zg8I-q|4K74HQ zj<}K4c3SC0rqQ2w{1R8INT<(2f-Q!0XB1xs(_s`BhIWY){&6m)?ASUDe;~-+X)3tD zxHZFEuGGgd(Vss&x07Vx7^nZ}TauBEbz`B#=Ra;?xUUti97iDcGovr`Y+|pkUX_%! zIp14W5{{Ch3(dL28c*RE5y;hvbO}S+&4WiG@^x!MLyj50y=KszD_4$jQD!Wk*=-iz|Q;0IX<+4trACYZ+EYw=c-cC}n$8&c?z{_yZm*|lRh>^}0 zF=1EZ(bOu1nSh;e?#E1PZyu^1s*=>r*X~*ZR}+P?^^T%ve*O6&Ua~ zp%{yE4%6ly6i5t!EH$le_IrPmsO)ni>}he^kd!<*5||gy1i$nt?(&@7!GI6Traf=D z#Q`YyV;5D6#cN@j@NA={fv_R_Y-!W4Z(KpID`VL}c6qGc$hXC%OQ!*yXC1%6K)-yL z#3_}HG(Lzd8-?NH@jJ|nTb|`+CjK5@LZZt|`aFA%B+~`GtR0uVimistrc?}sEC!ZS zHC5$Qr@Md2!8_pDIW>Tr7|pK13m9fRCOy_-rMbn;*eS0({IL>E-GeYt7l(*^EpK5n|W;4CDK=l+xuoXguREf`fnCBoZY zcQzjv1bX8-8vhxtICJ+nWuJny;;phwt@yJ;P zuPO}|WAD)O(?u|WxSU$c-4dd2DG@wOljfjW5|SQr@e|2pm6CFC)Oeark}72}Hfu8z zQoey5XoxaKk1jMUD+)`3j?3syEEWAHy&Dvnn~l~<>Qfv_h$6g#1ypjKO~?EUSr+{4 zOLHjVDyVm0dn*rJNsZOhzQM-zGveOiJ)?s98e&z4lguxN&I+CXk#8>y0-gJGc}>NG z(5c}NmTJl-L!RQtaaF2@>t--ik~Pbf!C}!1S z-f>p<3|HfVbllreZP|vhh9kZ6OcRO2Ph@S9{xfZgr!N*%b!9P(!e)nrxDlKHEA+eb zF#Sayn~AE3Y>{HkyiZQio6|Q*t7v&ixIX!WHz2dk$AoL4{jc7u!}c>%dHODNu=~5T zLC)R2fO|LeoUR`{eS}?vDe)FC4uZ~O<{+*2D2O^%f39PnN2hyy_-GH^;gSgXeXiF4 z3RJg=`?JXCE3mo^FXd+nN2}4o*9wd7fImQAMvra*P16cZ5y;`+6c1@Wsf-PhRG+-| zp4H;`RxIUEj@H*3p5GA#P(hM97U=1>oOR!#4&dcGp=h2#kxQwOgDREkF)4N*C`uYpxMSrZm~2KQq1zsj7_~Z{FR&bi0 z^Vheu$fGL3cm{e&aWg2_XMFUp#X|~XL^e)Kb$3BY%T>aK9g)*Z)~J~AuXVL9vgSk? zJYPiV!D?CQcQw*7bM<~HmX2GLqlc46aU6%-uw>Zb9FOQV3gP`H?fLbX-z-;5p^(bP zh43c$1vj+Y2Ulv98HcY51J>_M90@7=8fI8X;^PDQID%j1=3Z%TxV>pr)YnNcP6Vdwsj6H9vY4mg)|P=4sz%YC8f zd@MAh><@{#6ZPj!RE|XlFj58z25!0>Dh;ZJu6Y*L@+4g00;Pno4J&7I$--WT4I@1KQ@HF)z&CSc7fU9fT%A zO}RBAm}L+h*zQbV#BSy;M9Y1PWEzI}1>Mni7u%5YPZT|X(}lKD-riPM)^*7Ea@DtN zcdIE^f$jo6907d$E&SC%16cGyW7%h^PziLy5uu&=5=6DTpN5WH>ib}Rt$>b;rABDR zp-@>rz6J2!E$c%$wn|b6b@-KunukPlM+-D5{F~tEx~;Oe!u^p^21k*meag`}G7lS1 zLqN_eM00h&Myny=(vc&lI`B#G@(@qP0Zi=7)qonE_dQI;6#IV5~qoJX+gWLSoL6r%HfvxOILK^?zotfMd#=b)MBeG=RNP| z4cT$zZbfolBaLeZ%>E8&YHS^xXd>V`Y6&YJcj6Qa`LWk^@0t2ZNIaa-l(ny|)?5Q& zA);$V95koxa|jTaUdFRCUx;9oSR=^*rV7zyt_4ScGb7cQ62b*Ooj zkKpLv1+MAd!^Lwh@O6kOblqy}^Bd#yn~n25#x5@_LVeW$mMAu>N%C;>Q;-f1l(5c{ zi@(+hGtp6*wc<?M1~rNgDX_g%#vF#~o*2n>mOG zdUD%w#Fb%RJy|7y&+$_ z^2ou6y02~V%^aLNm)s0Ps2opFosmvg<}5aCP?5quD#!Z*8-Q5U(kiP&^Sk%9!TIL} z{IWP06%82O2`cSaP`$j=3X@X0XIITnc^chxgY(AL)#%BhS)?j6+N1hyq-E`^0|Uw! zMlD7*L7JIFmBwwYyCAcRdzTfBhYk^T(QCi==mgIP{=;(d1J8*u+>RRfB1(zHZos}$ zMZA|`?#M`l^YiP<9(WFh-44sz3MXHuPHtxw4CQTm;nFJi#ke1L=>5*(GMXb;S?OSx z)K+r4I5uv&LP9`13}Nm@9u~>rRE3DRrpeHivgyn4DCe-EDrgI$n|`{M$jj)xMCAxF zH~ipB=g8^vyha=dCqn<$Hc32BiL`W&zXeq9F+-A3<`7&7Ai`KPyWR~jv?WG^v0rqO zRrk4p0omE>YG~Ql;hEVednB^>*odw^v^c}$}s*0OwOa%ll zA!ID)BGwkZvy+@dzl&ZDah8=PkHK>079EEy{>g1nX|v#fejA zBP-z%ceZpqgV zL$?z1RBUQksyInR9m{NZyg|D-C#AOKsmcr!7gtZBJ;mZ29jhoVKm-N>NF7|v{V*@K z&s8J6ll<+bm7-c&>#7Z{2L-Y@2W54D+fl<%u7)EwM%Yu;}pLEZl}Nz{_zfS)UKNN6kIUfKomdBtd*CRs)BQClbNj?eVH)t0saw{QI95b zKOEKG>gYUpKSPD8yyn2PmyI^MIDcs3EnFxnKD48@tdfM=Ato?C0i)*16nI@~MH|db7M0 zYf(PUiSK6BXG~*0B`*(X?!l>glo9WEVSV5qkXC%2l`mQ|x8dmoZdTbaK3~9R`sZGs z`xC>;+AO8rXGn3iHh5ldB2Uxq+3!&wZh0>_GlNpytbJvX z$zg`K>oQ-j^G=vwJi!Hu*CJbYMDXJ7tG$7d{dD}XqTs0}gC2)iB=uXHBe(HbQgq_F zG*NT%vorF_=T5jLKq4nr?IJ1SjdhZrkxU(;>B?CRU08pl>J7=@mDtzOi6B)e33D7YN2Udn77ZQy7^vFCvXxf0$o5o zzV`1fE-1N(m9GVoeDht`E4LbEolt0&j+1}Ra@KXO2(5iH7)@cMW9|Ds3LE3McLASp zj6HP9vXQ?_X4TRyu-HPE@ZzwW%@19G*ZczYR`mxH1Rpb1iYGU0-H?mZ*&A5`rQfjN;nrNz6bIbF8&9RhcMT^TdJ;vh3N-;MrtC+|Pr zUEXZ?Dw_)-JoWk@P{B<3Z6hh+D(&)Ypu-11_IISFvG8RB{m>r^JNhy_X`=+cFCM*hwyXX4VGMSj4 zZqQ&@uG3B__daB;rN6$`q)gkrdivv2-2 ze^{i-MP7ODNz@jZ4sJeYL@eW!(F@>p2pmF7o}p;tq#!M9s6>k1seP85p}S8}MN zNMsTwSeR;!L|uyits}8aj}a%1+yM3Ue5>(UsYe~kXLv7A#qn@0-6wWMSEtWSNCD4`5*c% z#NbUc#8vN~FTIXlUN)WU=%BT(jmh10i2Dp_9qiK#4(sD5Oe_2s(j-v~z!8DZe=-rawXNg_MSlXT73)MCo| z>pxAU6pT*wpURWigQW|g{Vv-lm!YWU@T;a+>kuh3ur)P;l=P#Zb?7(m)ZIdYy9Qwm z#=y-x5x$SYh8g;v8XX3guawRUD0wx9E6H@3I;oIt)Wg)#`O*FexeZs%q0cl})$i0V z=ZxQd;^6zwf>8i!6(@oHXw4!cJWZRrW2BVwn(c61upKzB8ZbFD(K~0qXC7rkXiQeh zYU%NPG%dykrO={Ko)4I61LY$mUEBb%z`9$nLF?rH+~q2g+KyX=0%l3r>r~MaJVx1)rt1^qR0y07EFQ z>R~~@We|fFy1_$#(Lz>NzK0iv%^gh@51$>7$t_H$)ij+rD+{R5481QRWtz>XVz8`C z2Mkl!-+9TpyDV|$N3FC4J_m%S+eQFg&$9|DRv50bn_SD4DZW<=`qmH5= zCelZ3tzz+)Ev&>uL+Hg?z&nIW&M*UT|Dj6E0c1=()K2Xp2;0zM^mrz#d{dJ4l;w5J zpnL2lqEMFbhpPTb(TPxlVTogBKFHoE&rp4Sd>kT7`|?xQQoKksSLC;c#(A5V83y)* zvn^b-ZO>wOquRp8DLffv`H%mdR;c+>VTrh4?7^0QLyBo$DgQ*NQ)5ZksZjcb6md#8 z9SeLYHFOpyq?RUlkG^i1lj;C1+D^w}W$`ao?pW0h@`i_tmlY_|4f($4FysENuG)8u z&71N+Gq9BVGf+%i)><-dHudzybD0n+20km#tbWF3&Wk_DK$NlfuN<1_4?3F)$oa05 z7icMjeuZx|*^J73KhpF6;CysOk6M@u^O=SObjifI3h9?~l7(fQPBdwIY%EbRlWjL@$UOsaTl@P-Io6qi zo}>CvK>n@=I72zG%df7$gSi9$nPZ`TTKtga-9-h8xPyotg4Qhxd{kPvZAyK(voncV z{#XPrP2~)$xbTF7arteVH^ez7sI<{bzhgilOP}1Of|ZmlE4NfAxl+%*gcu9J`iowO zg(YY#zGBWTQ`E#nLvt3z8p3c4-c#&{;mn1P#@1!|MEc7y!#z$uNtqR5aL-Zw)Quqx zKfgC%U`x;1ac@dD+^hXK=4*_omXCtr@=YG4_gnHqub&SY6QSXa=NCTQQCTC7qS#7x zL2%Cp9I-rBv5W$$x68W(fPVM1R9Vxyc!Ch=keiJ6S4Arh+{TPMe8!RO$NAOp(;?%) z(%d>b94$#|?P$3gP6U7DOrAZGrKkW!JJ1r9(e*v1T$n2#GEcXhIBDHtv*6;M;|&!`ePIM3UvIP3h$ zc4u^N0~#P|$(cD`QJ(@!`bCZmc6RkI;=C}SjPIiJ+`(s^aX6+~<=1*dmAleehnU}*X zxuWFH#RF;a9DXE-D2D+3tSCmZ|C)lrXH?PG?Idt><2Ti4x$>G&EXsy4wx9{S=`m9y zhs=W++h)K`BEbwcEwwCN{xhXzL&1SmJG~=rjb-Mw2(V5r)V0F1V_|Ei6dDxBBn~cw z|8Q@qQfC24~MV?;T}q+T#?g`VEz!`8GOjU7rcC1cwIgic+0ik$1&p1lokA^71%$QgR*ZAUrxSLsKU=t z4J65EzP6fvm`NG8h$JKlXa)twV*ISskccc;YIUr@ILT|K-ujxIs^ z84yzNn)Ns*{YB|_aSV0Su$mdF1Z%mqNg#-|*8Dh~qL8`be%SuX(#EgY- zFQl{W+iWVcb(de)^?%o)G95m;-R#!w^p>{|Yb(+bC0H+2cH^bMeAS7ykbd0jd1FVF zQ)ADbmb1&mY6#1Pf9!ORV2=SJE#vy7pbwEk%RT$Suva=(EBcjlX@@=Z zv$%LEWitlm(b^g}2yG(xvli&OCI6EnA+|!SiV9ocj4OW}JR!nc%3AW_#@uJo%%v(n z^vX^*nXWFwmlPkk4OPgJESdXyC#w^s6riiE7BN0sp~bOYCRFk>1!^zJkhs? zV|Y1Pj^N$(JgMD2o5b z_94t}TuDW;%>4)4i&67vEB9*&PsVo#A8YL)h$Lq`X4W|cscfrDCd}p?o6x+F-`kPj zbkvI7;)sQlUzlWr!&#dc8Uw9^5bPfC0b#=2Io_PRnzQ${HDj0K>-JOJmG8*Kf>>{G zeo}>@@LD-*W$5xj^?v6090z^4pdM1!qpd1#+{;8*t2F#dV?kQ@m2EHhsQT{-w-%Ps zj*y}7N>N->yR(df1ht>{MsB5E%f!xO!!YzYdz5>F)MmdhSnGVJ@S}?!mBU#l4O|bz ziu&F+5_B1>v$#Re=Ecx%hOj<tB20Hnmbh?QF}_XD28C4i1l zBUUEu*l$v1Q0wrhisld}zj59^pseZXI^@khd0{xDry+OrLr3o(p%qDtz^V{#{SPpu zMsZvHT-$t=&4QY;mJc(P-#9RJ*}_K=+s zu$_gepoJ;DBz`tXU#J{ zSLMFraKaxy!cOazQzLoIIJH(@-q{$IALRGzC#0tZe4;mE(Ny`LZrRg*5!-S%0^(=Dhz(hHU%UJ@FYTPfYP|e;q0yP8 z`Vl|HFBb3fU>y3Hko6`I=URP@%ut^Mm-UJk8YzCY$_M~_Eq0lKja=E-Tx@qhHRu{D zAmXNf-0Z(r!AD#bb;yI=<{QhaYFl%hEpR!%iG2xa@fV?=5wyn6OTu8dHcaLjD!}0`*ZiY)a?nNTPfua1-ZsY8J&-)~#q~vv}uy0d;xE zZ&Sh*bi==O%IZbuy2F`%JBY-KjY%00SXlOk=d4O{>AD{wr*o)yIws)ZVw+Nu`z39ozIDyyAeZ_*&MfJ~$CM)8nsFLe9V3xA9bBgcS)&_cBwau^g zx4z*i@UY73JRy@-rA+l9tK~Z`%0z7K!!M zjkWJuzIL>*Y+;L(rLcXNTw_(kGM7Zd2_dtizOB)vpGB}FR#}{Q_EXlMRW<_vl(&KIX;fFabch#HlK58^XI|PX2 zBBC#)9W7T`)GCP0))eC2PP^X!QS7p)Ux<}Vou$rKlfLeg6$1uOsdnLVBq5Z6RhGbR z@NEa&-x8r0AqJzR6~@}y8VP8I@2w-nXr_(zt)5e9L{Z~^xu4UEOAr4WK=-O>6`#-l zovp|>qEBM8LR7}&2g1=7ztOWhuMd%SZNpLFeueeG?FJ_V3AI_^e#D)>)wMo}7KnX7 zl-|RQtH#niNPq#M$pN6==mUfqWD8Bd$fS#P0<6JC;pC03EfAH)PsY~5J zqN3GtxN+K>a<(-r0eo}r)$;gP1%4mbw6ZXzQ{@@WTGykF`>c&V*6Sc-2sIu1BUNtE zEBjRvQG&>_H>k-9)I0Whh(K|wCc`J^)XPpGlAJKL>6kh5ocU(&tVbcpa8y^jTt^9$ ztY{u{M%A&}q&8==B`<=a+3e`cnihIk?Y7)a$BmOYXe>RabpT)8>n^sh!ryf2`=i$# z3y2d{b41t9CH?G5)P>LY>|gntau%x)#E9!8yAIxaBq8GEuMVGxBpQu$Bo^h{#XrD; zJ~}&cV*M56V9$B6^(@rG7*aj29%jWd3y{}^LPl?Wr3p;o=HFs)Zvv`2pYe_R2>K?e zYY$9K&l;8YriOjJ#EbuXUE|lV@)m!aV<1?A(8H>eeut@oU`g{58Lq< z6%Uuwc^uO~@Ff1sja!Uz9HBtjU;K7iZqqEamOUb)RKYO{^0|uV`{ztQp5e*) z%p}P13i>tqpe+Zosah@Aonq20i-@>z;OU0%iP~kN5f;|Tl5)N;` z7y~m(!DI?G8>Xr}_VLSx>!7Sclgu>Q*|DVB6dr$!4b z+A=d-EIznRm)*LKt5%?Xhv`d}4@wIk@S}7{M&m$_?2o?nGz-#z? zW1=Sk3>4UYBF96_SyI(X+NQRYo&TZyIP3V-r#)%}U`IsC4USc(a7LcrV@>0ZY~#Q@ zbw(E%Gf_9Q=18XO?J>#8<0|g$fqUzi+whyVQBl{y=jSJY2Y%UbFf?8DV}j4#!fN+{ zude1LHm&aK5RnhddAQtUjHy`~0%WAm`XQsIg@(C;vI|UfD@tzRBCG)a(z?BQzm^tV znz=VfsZN{vZP_~+Q`?pdF~JJ*hD3AW938i(XlrP?9^RJi6EGnjA%%X}F-N@}r^^5R zwDZ^BD`pq%_mX~1zBY-h=p=`}34=Gx^C!X|4JWQC67A2cA$-+l(sVw94QeA+QpU;-_ zPTBmO5$w;}ps+U_XSqGkI<2GU!rWMDS`E+Uf1<0jd{PXTo`nOE^-uUDOlFc)P=+wm z&SmVjpERXVnwL6>WO#Myp8KvZrAo{RN5Q%ol_Y*D;qZ}ay;@RL(TnG&Uze9+CN`j5EtK#dN!TD zH#uQ;rBk>P_^TT*MOKNSZWG`smTg*D=+K{hmAC7mXN$J&aBu|(af5gHJM5r+7uCN< zrFt80v7pFTGyUDaYEE^yDL~!%|8Mu<-^CAIVrEdIN|J_(P$Ue3Xj>;av)|8&&Q|?fWNb>Gc+?($fA< z!N!CmA2l04pgCL**OlE?mh)4~EgsY56^IY*xwr_nlHIF9*X7r#bR?_@Qn2hEOP`IT zP}ptI;5tmI4^!oBzPg;k!3fw-inZo~DP_z5zs>bSY_8zgAE`$hT@0i(bv9fm)bgx- zWnt6D!qzg1fy~R7>gQ!{`B3T$pN#TEAu}*BPTLuBYJtiGmA}t?3P<@Y`@e69DVV#W zdO^KXrU0e7Pv*V9W}bmEVjAdyR)-O}i^I>in3up=lxDax3+N=-EqWuG z;Hw$8!~Uy0L}SD|&=STfVTz`-vDOoNXZRM3O7AYj3(g})^hU8eKk~q`EeSO-$!5q% zD6MM5e39YXo9xRb>;a#ui29!D7^Bi$JznKAL%Zuwh$o+OTu#?B0v7UFTO0fJUl zi=)G!Bu@FC6iE`hswL1i&y6li=F~Ogl2Ume^=r>0tiUHp^7riw{e7rL)a5pY%VXB2 zR6_fV68f6=HksIAc)Hhf5JR`5H5=oP6kcOsJv0-oh-Y3zlouoJj<~BkeX^}4%T&Lr z{dHYwdS6gTQD&zo81V>y_v{@Oz@Pk0EYgoTKwaUwNWV&1jBt;0uL>1b*ebY^!cSyv z0*pwd$;3V`ei6grLX7X*e4N}aEu286=-W4%4l`8eLIo6WhQ*e{p+x?5} z&Hp`g>N1Tn-#+s_!j~L_T6=nWo=Gc_wkUp_+obsQn(&oDfw8J6+m6eLJ3)3C+XlNK zVk>ggjU~q6cZ3;)FO&rQ2s9c_XE#K4eBDVM?O|&tj2)RsfPz01pI8zY^6|bhX4%MA zJAkG}pg2K0cJEx_tsF4WrxKxp9I#|%1F<&DbMAjn^&g>r0%#EJXl~$k97{^p*1X@= zhiR%+5tw8;+7iW_Qaw_0)UZ$3N5tFkE;XFYgT3MGq|gRO^{VTZ>Qan`0DEL*M8@XM zRCixVDn!3jNcxrW?LSG%I$3c7Mi`1G%UhN>k)d@GJNTot3J)a9tGK{qM4Wy$d7F2+ z$%t!e!DK3?He|+M|5NGc(myYpwB|?M_oqT8sqKmeSoem`omw0RW&ymdB7*tD9U{Lw zF@H3rf8H3C5^vbTY5tL7!TnD8=06Z9r1m&Pb)hK-n#XC`&XNjVCrUE|Hy_T3$Gx>Y zuJ$7cW*%tQ?xut(b*{M;#y)D6Fa;j>cg8h3F;|L1IbZrnM$IKSd+fWC92NnO$XoZ+Lgea>RAA^L$dk~p?BSHyRf}9imQ6lrE^gInc zPvK#DQ6n>cq$E)ek#-g%Ps-Ck9E?bmgGQItEB$J_Us(8CFN@v(B)5t0wdvky-5r>j zs*0F}yINU#UTm;@+tvi(Uu>*3)JsL9f0MKykM>b}l7A*fm{{}HYsq6NCw)@}kkn80 zqEgNzo6#Xp_nw-af<2hPO$oO^zT1kaFDF)?YAzN>dV8XL^0^`efISy|9&3A=(^Y}* zL~*QHQjg1~gu?(jF`%g0ui6Gld;WUlnJ|~-2h2H)xYRdAhNT99ma{Chnr9^xDbd!0 z6ig-H%+n6uD5mAZm9etRe2o9c)LTbI)qm~7LntLJAkrY6g2d3>Eg_9ccS?6jBO%?O zgn%;C&`86;ASpRCNW;+i9`5h6e(U|41)MYUiM_AdlX@SZ24nVU+DUe$b~bLjz#*Ir z9APm79BzbhX!)=+exlx7P6+J}t*1>dhaJKd>c{q_?gJp^xk}tG`e!?Ri;aQ2glT^> z{M$Bn0q!n}Ot{tPsEj)d9g+UDZRSL|kBU3nuxjw(2YF(VQ$2xuJ1vLw+k+bRN2cx= zW(Qb-K8NwhOIK*P08JHHoFs28v%vP~ieKO8VO`pWz0)EvCT}?9lr|DKJw&+CNF*e;g+ z#YSm#&@|d5CD9-0-?FNdbi0LO$?>DQ47SqLjY08F=PnY{^{Q8i*@P%GkDg=hP>sgC z?D};na+F!t$49R+ST8c+Q3J( zbJ<1;^Qtb%;_{{Fg`7D6^FLWUoklin9R3LHi{v6dZHm1-w-z zl$3OGsA0y(8Mw_Ely%f-pU*bbOiYOLF0(_<7~RW+6?%I@LK_G9Z{oK7HA4PmQ7b8# z*~leUe6bU2xhYTsk=MdKDiSg}hr*{<(TGJcYm>RY99z!lGUcF{UGleJoo3TM2>TH5 z_s_f*Iq=?GynDy#eADt>IWK1#fu`m*j&ju(b;g7_pya}QSGmwEQSU@o!#g9(_%%C& z3`3le3aLK2z1M}2N6ei1j>V0i^}k)=o#R?r+Rj*4Mkpyfr{pX%_wCtHi0K8hgzfj_ zCw2loX-yNq<&i8!Uw-)itN$RFMP;9qltGRZZpT;1rFnK1s-jU=Af;J2S>nj|@7;9N zzHz`S#YWYmeH?e8i|u9SCErw~Z=#*Hu+(39;hMnpUa7>{kTAD4e`x&2Ll3z+CWfw^ zVntuA0W>B$CB|&s?$7_*Ft`vULmqCgI=7Izj4)HNHFtSA%p$9R?%OAviwO?E7fd?n7t5SK*jiFdr_R+D7WbsiBc!h6PXiCTkpGK!Y$Pc* z`e*WfcWh7rFjMx~qLd-y#+YfxnOZd)jw48YSHW;1zz8LMMg}W*;^+SC20GSVG}CLk zTm1uHTYLK@GYxDLIr?xcP5*z4l3J1Gn?6_KWt(7y4E*!jHy09V8vRUlsYVj_tIcV* z7B<3_Y~IHBNnaX#B+R~v{;SW+CC=I$CT&f?1c3@v+XI`w(}*ulKFpNfY%U+ngre6@ zcd|q1vOib13jUxDykKTay0=2oU_E`!QDhL}84$Qq- zA9o1oS?G^2(Ku!IwA$WnNM8=V-DokUin@al!m_r{yLLu}eLh%IeYtc-=U%x>Y;uc+ zAy;uu;t*FS-Cphd@b9dUzNVBPd$(v}M~zG3>f8o|Hw*(kKbuYt@JDA3^IUkNXN&Kg z-Qo9hqC87Q$%6_J#vgyk|9Vjv+USo83O)r4X(go++y2d%Xz5?BeB^EGj==BpL`9y0$ouScz*vUr*>vKU(Nf!A(FFHx!n3PzfFl#&<2d_Q+haOUOC@A&cE~$M?7XrVS*e1!~%-awjR?e3hg+AgF*dUhG5u9hPwa z9@yw#{a!nj-j{jZ>uVTC9+Y^P8C~JnkH=9W=$G!cUS-0%Z^IO=3#Vk?r3nKuKk;e6 zw4e3yts_jNG^g%ITy^V(nc8-e(cw{F{5<)a^)waS*Vol!K@a)&%87G-Q&B*jvjKM= z8Ue^fnzJdd10^-*>|PH-YgDNhk(Q~da>a+Dqn0Z5z?v>e>R=Y)b6R1jX`PwI@9U;d=v!?`}&%j)y! zS6(WTE#8W`Cfvk#Uh3kQ=MEuTJprd)4|2-CoJ?c9t03sU3lQw_4GkdG)rM1`$ul3|jE)E{-=sShU)Rev1#n}{Yk#n)({@0T}64>R) zOXK_|>f8(Ga`Z1B#cktYy{Ybs{Y^_C!2va+9b_!?6jZq4$NPnNldCn*7>AWc7ZTy5 z&)VZ#ds~_>Fa^<9px0Vt^i~V9LX;$8AIbpw0jaVRp{fNhEFY5QNXf6>rmI~M-gN7u zg#Oj?(g^93-@Bps1B08Ft+c;{jvhkD#0(evTOZjC?m&!8!3|1O_hl8QP&b?2RT(x6 z;blHp^ZJ{h{c2~a3(a`$@-Mg~l-mXUXl4 z{=Avqx&Q?yf~lo&mOL z30S7P3M0947vWaAw(_#{-~1wNcatU8dO^e5`C2fB$Fq<_&=4Zk`H(l zgXJh~LhyK*-q>#K5FbbkNCv4d(&{uc~^62^lw*`6@J40R3S`$Mec8)sIi6mB^^q2SibW1UC|pTO?k~vuXL+t3Y|>q@OPFCx}0!kE%@O90%1-9SMAwR%h&en zQL%F1!vjfCsJO@{U3yL%6fgKDhQDK0#0@$WuV^ssk!XCp!EWuf1~bD7@=vS_X~aE^ zdd-*cH}Bib1Mjieu<7is$qo@xUW6bQx%-pF2ZJ6v2F5k5>*jq%R)*{CaiVidZpglr zoT$=6@y0$S_x1MSefrfxtj-nnGgJ0K_QU#-ysg(yVp<|xj*>vyo%^f|;}5An_TKm( zV418OgcZ3R8F?fMx0zcHSPGRjI35JgD+xNiUjpEqXQ5$aY((}MaP$O6rd)5P%2_qz zUzVgZrWK!;6-8_8Cof*s@dCG5)Vng@6CoP4r58ckC0?OS0dK4Jp4YZff=c3yI!K(C zn3%bLFb|vgmQM~H`E$JUcX323psrN#U8E<7J9g06Ik50Lt5kSSR2}!@!1=lBC}X%1 zX0y8sohjxg^##JCK;i6QBRyXr1SrF>qjZCqn%9Aw14+vSGyn{gKpG(cSwbB?Me-SL z3!pT;wwz{Yv7*v0es;9dGE1Adnx#JV^J=uwzeem)$?e00(&fSk6lCeIi1%v(^qz)) z)4&9EhA7VYe2e%n&lFS9@#$Q8tEk>Ai+;S3FpfR^JwR?4?0YQ@j6PdH$noH5zdyH# z{`M!#5+X5dz>_d5F!EPF&oBc8EFO-z(si-Z3U)%EgFu--yFZ|1R(U=LtW(=ckcwsn zkkh0^YyNDj(Wu^r{YxpR&Xj|EwY8F$%}a#6b6|d=46XVk%g|rL_CBQTKD!8MA1p36NmYRQUSIXTeo$u!ZSfJ2q5h!@Y>~6_i5G?f+Hk zMhfGk()oP!=Zdi<>k>K|WNIc{)FWHf%I?$$$tlaKs>q@w>vM4?739Co5c>F0HfEd8 zbz?jgILq4aZ!RvjwM06y9RWr6*|oNWvooK=65-pE^uwuB?xi5gJ>Ka`mw~=42tnu;vD?3aQIwpyn5A5jBfjaSbyoR%l`m>fDD;a;eXj^ zW&^1%cMh``O&cBOz%YBqaBS6G)z_{o=(Qobz z3g(T?TGL3FdtqDjWGebF)7m*3RSy8!V27RwC+C4-swJ<>?tfg*@LFY-gd1gEj^?d@ z>NE~f-I!L_Yv4|?kH^Zxu~~ZmUgG8|lVOlDa?o3>XA2MXT)zex(VjQ#qqgb7Z*V^j zhiOt!CTn1FWS23mD&-%tK>7kKmZE3~N|b>Dc%*_s(K)w|2qg~UyiVZgW?cZh<{uHl0WQ~qG(;hk|}I}!~#TKfdVLgz&F9xo=yZ}MR@ z4TD#?>BAL<*=#viSrnrFbjs_VmcPw0aK^^(S$~Y;LyF=3jD&XZrQxO>J*O>dT0UTY zRDSGcE`L1TWE0hq82<@K69r}jp{Hecu-5$h+zYJd1%b2&9n55FL7ES@TM|#TzTkjL zfA4w$4U3;uu7Bdppif1XiiPO@E|fgLBid-|eXbmwc&abp>6%52u23j1Ypp#&X`uVh z>*b5oFFR8YaCrS^QW!ph9@KyNax35tXjZl=&|ilRrF8@tUyrh*VOL9Y*(KCuBc?ss zA{)T6wv0DZ^M(3OKuqkvQ%9LOCFZwWL=hVZeIAvA4+$oApP!5vw3k@H-TNfS+MO36Gs8C(Hj1kds+%!KN zxWiw>t)YjP4eg&k$7DSqs}rWH@F4|f_nX?G7xkQl z=!=l3{tSE!kdMWZ+7}`mtEyvHfPZ+vT?Vu!H${qHO9c3;pbldRUDZ=^GhA;ngkZDjaN`N zYE4(G-JQ`_P^ahfxg9p-IZzp5veID1}K5db|?VH(x zvC*{6@aCVvv05Q0IRCeepYuX!66Hrs`*Qveb%L5!`JgW}=FdLasA{SPJ~nsqA5ty^ z6z=S^*5PM@8jB5)>bCF{>lK}Wk!b~bsTTCxTHl_#*c7LQBG0-sl;D$N!`GZZGiKIC zb&X7mQps*SrQ|(Te$NL)mwqdf{ABy`yyQS#7;fb+H&{tMuhdW3TrE<~u{Lr%c3+)- z6SmcD8z2HtYXB_jz^%K9;(b@P7xdkm=GX1UGavH@%1~p*SDSh-ITtLEb49ediJ2qd z^!~56t@wf=_j0I0%FFgn!2PN2a#4yhf9(5jGK>xS@yS~{=Af$sXF2ZT=2O+w)9(#g z49c6(BAGz%f2h_Wgdj=srm6(L6hfqbE-!qVMmn%zCrX26yYg@;J!?t+n}h4DT1DJL zm-SPZou;`7;})i6p7%3vmb;A%Wjm%jydT=(6^Ov8wT)!)ut>SoJ$od1k_vF0=2)9u z;61VW?_%`Pr2$DUJM=CHY8<*+LayfLT+={X*Pfrx{i|nTnSbTWh2^QF*!ZjT?x*Id zt0amKX|Qhjc8NV*ZIbU5c56}@TJay-nU!4w)T>@UFJf4}lAhN+>j1wXJi5ircBDsN zeAjD(LI+pZ?H~3x>1tj-M}3@lwEp7yk>P>}A9s+Z2P>S|G23!##KO`#MY@kfLD|WC zz~lH;mb|TJ%TFaiptDV$ZGsVccbSmrFz0!g_MXvKZ^wujF$Uc4G3H*@Cc*&(6(Q`! zkHNMI0-3&jjgf5l*{GU*)4|VGgD=#9Ka6x`bXqwY4$oL|SI2KW5qY;X>P%7uPk5Rn z(gn9X7@^sy7=|W z)Yo}=tVLdOIGZui?A}IJ+#~W)DRBMzPtRhQGkFz#br$353EbW7R4l2X=h}bJRPmYfFr3cvjdL z2@+ujJ=Wpw!RhE)bXz5sI6u{pPg@ULd!7Stxo~JW#5rU-FRJ2<@xW0(Me>2J_dIV| z(Xe~O=Zku(L+erEoVM5ZmP#|r33>=jSFfBP-eN27hjwlR1zTK_zcIOcB@b>3a|NkA-I}f|#0q&YN_91jf(84!r z<3srm(&CwD)a3sjq>rMz$72dkPx1m0<~&o{C%{C5zv!U>!D z+8&q#Bx;ne?|d>VJ5BdViEfvHN*ncs&HkQ!g3ZH>AWk`WQJe|vq4I}o#vTrvdbbJb7WvsTp6#FqDfi(P6onr}V+7~Hk^Wjr(F zU#T+QVQadjDIIf7D>88tMOb=ymdy+82Y9t=zXQ++x*P3_N#-$jEL=C9*G** zg)e;TVhBM~!;Ti{bhB((jT#Gd7Dh+|fy;ggtIhkX#8Xts4cV79Kvb_2($`2N{{0ejkGhh`aAmtRT$)C5!q zL4T9_rLV4Rwd&YqZSh43F^@7;Kb(wz_4#@?{U@hMs+B};hZETL5?^F)M@c&T8$;Nj zc_6m+zWjo8cP0Vi@e7+?1S%%ToR&_%zYPz$v8+0tRcVe-QzxX>aihalkwBllhP2We zy<7jq<28(E&6e@c5UT4is;yXP3rsW4rmW2JlVZQabO(;b+DFAf>ex(v$IP3NOG9LO zo7=EoKc1O_$#)WP+N6}|u*Rp{xh>qElDnKO8%z4x~@n5;su`&p0Lv*9K_<~JkXC-Y8h z@(cxrDb_T89>RranXPwKP?0jyebS+47BuQRtfp2fiQBL-e7aG_q z@oHa&lC5JsEUXT-NF3G3ZD>s(MB5aAZ|eJdyc5Rg2W7_7)_|J_o4Yho;IwIZ@LW3M zp_D_sC5sB&Mc()^WP4=nWtcB4-=NWX=bg~_=UM_4(F4&V-U)MrV>oHBz6r?tajFxojNP>yeu0Z1#SueVTB!mhGm6~VUTH4fE zW5qi@pSKG#N+efz+WE2xN(LE9GetQXYhiPlEMkw3_^;N7!XIdxCVt`!-AE?dQoC13(-}S`J;%yFAEsCl znZLgV9f^JLG@n8{U}uL4>q>_mJH?A}hrLfh0e8Mlm?NZcOdB{V5-B?;^L zq^5zaNd6N7Fh(%y$~4{vX5X)@0Pz!gvGtf$pxI|y9_L}N;?-^R26(@ezJ;b#(o?1~ zdI8?b%QrJj`fgeF#O@AMN4cyHnTM(@{A!GZx)&;955Niq z=|3%_S`RgO{_%S&x*T;7(P~P_Xb<@u74P^rT+1JJZ*o?*ntl6vM z`R-DZjU#H4Z{J?q;kUpMJV_w8GDX`lD|iK+L`E$Lc}fi~dAPr805jjfZjU(GGF1)r zi;l6{>KprKi6nZ)uJno@ z6DnnrPe)YQ;x7Fq2jbss+S($mb*LZWY)mroM3~igvoqs$grcF}*tNMbtyeH~ctrCP zt(lW$#`nnNx-Md!lLIC3qJC{e0_|35q}-0m+-Bj61L+e2j7>m^bGUB-fH{8o6f-}Z zGde65uUi~L!6|@G`>_=P!W=t|q3$XhesNiAn^`2i_WE$hbH#;{seJ_iGCz8{Np)G` z&q;Dt2fxE@)DpzV#6eg88!jz3VerGcDRkh+*2FW^Yc)moS;~z%*PmuYi&z4LqfDd9 z>Xe)Z8C*1w^_Rp8deg1!!=8u|>ZB9^0;01?C|G#2|K)l1Bh%jh#}kD4oQQWx_4AoU zhp)&f_J`4P~70ip*LKL3Yt{^rsYUtz>7Gwi@3tTQ^${?Fj#R%~2Ie zj78DbSyc;vzF7M+*|xR>EUpRvmuYzhGHE#!tj1AhbY}}ZA2J>0c4FT%7jna~+^j^^U;1af2YH(2d!8+|xg$JQ*=mg) zdILL^&ogDh{+s)htkH{A5b5^<*tIJw7x~E)a!ShJ1Okt(M+0zh#LRD9s8J-^VX6ZY z*;?i#d%X9Z=^|pF_9o`A-uZotj76a!^TD}PK?G%6L(jEdIa{F? zob%0MS1UL;vJ=1;)th*9xA@Krin4Kq}m0F zMPy29Q5hRE=JE>xch#|%9j)HesUrfQ-~~RM!zZCqlY4wW4T3(9p73K&0ZfKF&!QsR zn~Dghx6xQ~jcxFF$VFnAR>5PqLGaSZPS(b>qG(C(GOUTjZnAZgzjJAW3)67p*l$jU zY;72`50Et&xYp(p`Hug{x8D^?m&PB>eM8(vIKW5 z)E?=s`zG0b=kA~0aSCFM5$>LT&aRb|~fel~r2nqc2 z0?iZSMY!WelcSJNGK7n8WmN{5|4hyLi^VJF$&q?BT zd}{#ucm3TSYvNj|vQtC*E9InhDlKII=``dq)78v&8W4nlZp*J~SjicYCqt!#S1YAB z0E^VxV1ODt5e<+z;Xo{0_j#sup4TJ%N#i?-2XR|_q?%SH)R3z8dMaY{iqE-QqK$NY z@dVClm5}qRJ*~yeKrdGUV4hD(<7>K{^Oj-(tfU8m75aANEbYfD34X+4z{!TzO(sAT z=fi6FNnm`xDc_abYzx|5nLQ{1dzV!cA?mpMKa6g4B5%-(CjtL=X=;aH$CweiwH03d z;VX8L2TA-nIEz|*^vaMz&_(C%_Dm`U)AEP&nG5d#<%G-^ znN?nr)djd@3synMhA4b-XP>T@bQB-X45?QO?C1b+I=?LcpHvp>T!o&c0fCrR&QWuD z<9eHJjWn=mig)AD+$~GH*%yUak>h|A@!x-tYzYDI;k2LemR z0?Sa#jU1najw0+;7IP1(1Jl%wGHS#)8)CG}GmFHKZEDx|OSR<|lNZUcGDriM4j@4j zQvYmiW9t$9Im$<6TAc_#&$=c?qbP-&9;YYLGW>WTA3qHSNMV&CDK+ExQ#jNOS+PZ6` zQGep??I$zJw8{>|Z7S3DwIICt0QtnK;2oCzxnkx#pv~*;dqK3vaIS_3ThhxpV&7z9 z4@~usfBl^)+Vj~(qaumFvpi`FLkR#NcUxM3fCABJ1AJ1nPP&XCH@n<~IGUKKL?&Q2 z63L73>q1Yd#q2xY+r7nD`wI*^F=Nn3R&@Vh?K7R{uQud8Ihy^=gLmGd|?2E(e9|a@4?!fY2=8%5Zc$uf5m$Xv>!<2gTS4?R5 zt`+oYT5H+ZX@=Oix3O!?_>l__WNuA;%q+Xo-0C^otdHf-(FaGcLEoO3(vkHJqNAXH z<^u$+Xf8Eo8*do~;=p63kHmhVKAL+2rS*f`t`IhPW5p?X9AA;0kHC|=-IU5|-pmxQ zpUsW}zje0bMDSHRo7Ol#UMB7Iq_kI{T>fOMgt-C@A7s^2i+&+pCYb6sk{!nt+oOxc6X?NHoy}1I#VmQJ?Z; zKEaP{R64au(!)b&sW~!9<96}rn!?gs#jE9)b_*4ayhaGzws^+I1i-Hx`L~ZZUN5ad zPGfKr>&089&Xn1DTchtudEa>Juz(DPyVmRh_Zl=nu$Ioc)}&q=%MZ%-r8 zji^@lr~ExnogppG_@vUbr5;b4<(}(eKN>AiUT|~v#%dry6@;P;BtU_dpI5B?{)no~ z@F~!08Mz@8tIm07jOW;%qvZ4de7 z1f05uioOs4{Mxr0e*C}{LX*9vpAj|v2(=^pFZ_V|!MT2tfypMt@KZJx`obi8kkc1# zD+n#a7vJp6q|A}U@K!h59^;gtq1D`qN9^`bn#yLQ6fg_QM@4=x^{V>d>bCk)h0TIkJ31lr7`uL=P2qMAXK+IzM|eBb+b}?KwzpzgwbNK z&p#;Iu1y!|Kb!|;n=d<;=R_7Owv|5W!rfE@kahdl_h-tVJsAOs#Bk732}Ve6&`C~H z;{8E~BJ1?XA+fdgY{ft4JYmkz*M6f4R)?AQNH~KOaHBLc1&_HTe&nkB^qG&Rj-Wed zFxO-4YxFW898lepbh-)$RO7?GQULm1DAB?;avi$)zH1%2kKR~ed_QjA_hFJUD0HWZ zp*}@jG;`|ArahY#xp+kDRVN6Jj^dxP_YM=Q>tL@d`=iv64%BqTY=D??DAFh>o0d#J zH`jiD9RHdli5oB#xNKl|bvDtnCVN2qW}GSR1Z(~LVOJj)^8TpEW#pFrU2#u!xuCL& z=d5d|vXG-Z_W7}Y3;8^qx^m>&k#XoV;oqOHDRpUY@Xx0Ky>k}qq;E^gx_R^|G^#x- zs{3V!s$=wyW$-IE8(s47mu88NqkHPa zH2}ximGCgqIBGKEEU_l!0$v5!oZT4{^Qby8J`3=CHV5tiAgszq{BSN}p3WDy&(%d? zE}Z#=X2(eoZ?-w$$*34I*)#CXLuX*&>u$Aoo>)+EpT1rAuDPUlh6D@xL?rk^%+ zIf+FChMZa<-Z%qFbbs()hNc2>3zWREsnIj{h2VnPE@%bT=weetB#8g{ON>$_W9EUD ztNA&~}U?a?+HS+#SGXyi=xv*j_}f~k zmCl0{i<)0v}Xp#p3Jg$c_qf z#;>p_K-&N+o!T)Kh2;25gm{x8jvBc3`pu&%v8hF;BX@qpVln=q(58r@~$K zLRcd+zJk$j5>*D;C(sU~Ed6JhS|X->Lg)Wx@223;BoR=HgC||{ehyZ>EvLPOC3SPq zVWx35e)9h7+h=b=EcUw<%z{3T^rxxfh_Q!@)_k2D`t%nkAE?(z7%4U{e5*TgoyGl~ z{C&_ufWGiGN`7gW`k6qZXW_HcEixWU}%%xOlK( z*%9>YZL2K}w_zhKh5?)<3e!(*L5W#shvgv1Qk%{|+ph>3NszX!J~&u#G#hQ8uxu{# zcTw3`d6R+j=tEYw%*Avs1Tpavl$H2q(bxLy00$EhW*=@*UkKlc zq~~gB-TcP<`QbvIo6n6~QkM`{=rZ41Ck>?{`6T9U-cM$X*44Ap9yP~PwM57@T2b4^ zO3KNVR_N^Y1<+YS8Q!qT53RVgFUV7G4(B$+Gg_lxFWt)jde=i4>0Wt;CeA+uf_nj6 zMGVxfze4Fg0a)3ze*JZbO&M>zxi8F*QsnJtuV2gy=m1ffPEV1|*T_2<-310Z+6r64 z&fXNEo8x1s{d_YoiS!s%9x>TEht+)E$z0LCVkFoVYI%?bc8f!sc`ofY;~q1Bb~UW> zFmb!ViHaH1RMl}cx+rN3arr_5m956~gU2b-y#)GA`O{&Q^eOJ82OKfGt$Qi7UJLeb zurp;%CW&+{UhbeP)Bmu~Lh<}dgBrl`zyMI)VLlD_#z{f~1Xf08{`-gU@ecj_FP#zZ z-Ep%n*8PH}9-S7fZy%L5fIZ_dd!%<#X-3x|6TbQVPufM~RQKV%Eb!t9&HNP}(b>}*6>j71UE9;yykxWAN_HRf_u;4;`7v-(xS>LoLdxmGQj-O zMUF;-*7Kep;B-8_c9=thQK^C17&)#P9OI9oUb{!0*fZcQ-t*cQE7$~i^E#1d=~hZQ zJ^4HvsJ_QY1xYvdqS4#{d;b1I-95_u3Q$bHHa&qJit$nOq*E$%URH*#S`f@gEys7V*2W3|L22m`qe=Cz&vOu z?!a-k*nz(WDC9MF!7!JZWSfs2!gJHrXp&DT zHzM3$;6@Jf6p^VuaR>)Ve>9anfJlXA<(~O3QR!4sja;W_Ght?2pyM&}zJ@un`*w{z`#-Pp z_eG&}6u47dq_E8{@KtKQ@fR;j(QL+uu$vgI8ZB@%|KChKf;eQQUUZA;IZgDWD7#-l z1wD|Z-u%Mspn8u(%jW-}&#mCE<)s$qVeZvvGZn;9URC%k^if6Zhj;o&tcO$(YO?IH z8sJ;_!6DFmy_5uXCQ% ze+BjggBN@?Nsh*Z7e^+f8io9I>>U<_i3-4NZiq|w0T3wO3(Fh#NA89d;wa0{nThBzLT`@;{A&J%#`#dd(gy#L z&;5DroJ2IA{biQUaL|1K>CCLsqlklb>KoPzb%NAcBYNRWFNl7iWOYVc2ECzE6fpn^J2t_R+tu1c^NZy(A$*YVQJ14?! zoP;Ycavc)jI8N`;YW^oBTEuyLViN$&V_8DiUxL-qd~ima3L zSZid|Rh7xbFY}A`s{oo`C7w}q<;Ofi^fg}dQEV_>qG(cd9{BcGTl;4xcZx}X@-zO~ zy%jH@NDtWO2NoDe{HnL{5NJLN&Mnz=%%{L}$q&+fcQ?i+@eXudT6hG5DEpr&3hBKn zN$+J$Rd;Tul<>m-N-&mf!eoa|SDtyX;FS7Dq`KvLih=R;Rj3;`xn5CoNH{G3T=?%a zN;?p=Mpk}Jg|TRU5J}%Z%nBaCK+hz2D@ak@f^-st3u{9g{AF3F|>=|$NN1R zU5Vh``qq*`jG^#Hd-RLF;d=E=OiM83pMG=#0w>*#_cl(i!}JUV>4_*Bfbo@sRMs4l zD1Ub}ufsvcD_iOdKH5O~IY&=dD^vm2g&sQno;Ul$uRk~$R?9$kHpa#t(@TyKHRS6N z03W3F@}_?7)kf=`Yq0A&l^o?>mg4Fsi5H$!MrdK%MC8@B2Tlfh9l#$mica>qc&pkRYqIOV9Rg&rj}y@ezFOV^$_eQ2S?aWsZTFDN z!hs9-M;?`+_z?T<;^AM-X<2S121OHDfX86#GP+@02>wT2ch#2_6< zh#nhN7|WhM@B_EKpzhJn36PVf9vehaMNDN20#m)0f~OLOL5#qX97v1=-^7MbaLLNi zp)UgZ^!pI%x_qr6Aw{-`+ctwe`bE}fAO9bvTKcTIirAI*a;TKw9Syd29fs1zSY(0t z=X3W+#OA$ms_x2vt1eWY#HS@jIWFy@Q@Yz^V)@;HlgeH?Mh=!87I=lw#QG z4r{};;kkZNa+5lNs7U`<>qIRuFvX8N?@E%fH|QJykcE3-robZ#Ma~k-|5~E;j(-(^ zH1`onQ73OZFQmUS@O0tel>N08gG3g9+nu(03dI<6l4ps9osC%QhNj%dbcdB;d7%X^ z2q$1tS~WZ8kYDb{CFAn5&_94={(cJZT8_;7gALMzat4Tz>U@U~AWG4ylvfRGU+GFM z>Tjx?_3v&LsBvk%9#;seU9J%?|$xm$1Be4{p>w^X3eZMzMLAGG+ttasMgc&Z(x6Q5%cVjdRW)iG^dyS z@JZ5zsJy&`Sp*rj*TUD=q|4wB{R5-lDooy-?N=REV_smd^(_N-Wih%w=kz5^=6p5I zbE3H)l4qxD!oQBzIRd6JBW5g_uBy77VRS8MsW9ZQkvAoL-);myq-a%_$8&Eep{2D5 z$x8YizDGnhr3OzZatVa>@3fh(6EK?~lVCE(>fAvw{2ogju{&MJY9iDnn=`(m7?v@? z{kuPGtQziiE4X4cEfz#?gi<5}WOxFM0J4y!=lV?c*XRSc2mr{&%%wwGMIgE#Vk*l* zjP(3)l$QHu*gaBK9>bRVX_3wV>`Dx1Fng>IcJY>L#=#z-4JN||${~`F_=|+C3bzak zK6BchdaO({=Q`_c3K;$Z+KT#x-@7|@WWezQqm1N%Qq9|n*{}E`Pn%g3VDeD zfe7(Wg7~dWj~k$cN84;C`kUDU8+CIuh9+zb1~|kYN6ztPO9vt=Y2)>nb70|8U0$-m zpdwIvgkT#+(P~}wZm2%pb@_C|-=R$B=@80Viw>)d7NvdgNb1dMMLDR-HR^Vr2QY*& z$-i;KB*jdQnk^lW{n^%Atrvy+dO3Cv%4gVrswLZt0q^sZ_$vQ4|+apzVYDWg^ z?4kJEW5n<-Fn|GV&@Q(*@uRPwOIr53?(#OKYrbM|DgO{Ea<`_vcQb%}zqOr3YKop4 zZfrA~(^RVh%wZeK#%?xbjX!8Ru6eX z80gdnzSPFu$7#htFX#35rArqqiZ-P05sIf-#Uhd|Iq&Q-4v+^Ws3;LhKBu&k++xJp zmCoCmhqyUH*KVMMd;|!?CKWT`t##FPfYRC;C89O}hE!NZm^$9sFTzlpB4{d3OGD-p zKu)g~aJzZ18qJW*D55UE0nu8lTN43E$SqR~%|KI447XSj(A;~3Ok(;^K(>h5zFd&~ zuGujSl_uUoVUvst;eM;7aTG!Alds(qz(#U8MXNG70!SA=pU(p_iTw-mr1@giHXgx5 zUIz#d`{t=6jzFq5Kk9O&1Tz@?4ya5*Vj7^##l&mDpNjzrRa$es8GtHRd4ju${AO|t zIiM-3yJC5`<-!-^6)~_d+;f(Yi_QS>sXiHES9#+XZV&{zPXbGUDxQQeH)zgu*h`C6 z8!PLs>=GLbe;+wNT-gB^vWVJw)E4IP;%Ql#IYadyLa2W#147bNMSDqHx{^+Q?$?Bi zdPkb$!{GsF!RCyDYeLjz0tsrl7Er-OK#>_EDi5n;Y)O3=(R3g+afVDVh0&JYk^+Me zX_?$Nt(wjl;I1giDyLk-%QT3>!Z_-$upWhdNIVLg`K?RY_(g!=mr@FaxfA}GC17h6 zgvwJ(@3Q`bmQH=VCmztU55)b=8KtD9LWRXf{I|6UP#GX2waF$!gQ-a@v+9sR3-ZqJ zxk-p`ySInhnrz;CsFF5&2qdwdI2ao;@xr^>pTcjAU-p)kH!;v>NV(ayZqMC{*-ZF3gifT(G9 zz1e~Ih%g>Xv@TA>QM*3-Gzq64^Hf#OS7GB?q^3I9C}fjX+Fz(-SRl0`uz`m&AjY7- z=}QyhA=_c-N?74BNR`nzm#Q7Dlo>vkhpTCVrSl0y6$e$6fi={r=X@6mJYd{8F zL5tcSc)%bAMh+ul-7T?lAZw`pDCe-X>2Ob-*R=L`-04ekvz|jFk>fE^GCpLfWm2n& zPW-ja%)Bw?ukK=0+sScsE?Hk2)n|qK-&WOiSH#UgYMV=N%2qBPtAn0h+U?l#rDvrl z9k=h6OG4S|3IchU&O%m(jYl?hotOmXi`p>udWTkvgFL|(k>{j8>yXIdAMMgrGXl!?#&`lJ2Pfu7(ZsC&s5lJdYI4?qB5laAhmB|KiYLken>F9RGv9P4qegf0h z{FOrT%rFGj5vz3u^#}j~lXQUNJ!)a|(V7-EuULN_)B>rvzPW>vh}~B$FD5`loM!ol z%yp^<&bCj#QT;q-g!6AwgcTX^5Z>$Gq#YV~F6prNA?$o3yM}?@odDt$SF+-@ew2uw zGhFWpdnw7&&F`yM+tN4=r09JCm(@Kki2x~0c#wh$(He~^e^EMSmndjemISUr`-i6x z6i8|Du!*Cpb_8w=i4F+t%_-AenM)6k0Z=U(5Lfin!SghmgLIk#I|g+Sb*&!8%dg0q zt`ZY%1z?+i0Gb$T;eZOg#s*q5@7_DWE#%W`tiq1RT82kO%rPiR6`YNBZcEX=XCQdF*ibgQ99YYIbb36|ia8V6M}*kWnI- z?lGp?7=d~H@eb^IDSm)}N90}exr*qJy7#}$@ma*He#?1NI=;gN z_Nz1ac)!EMDqc!9wgnwf;mn_vfbGmi^40-n#Co?2S0wATsXkDsjZ=)Q6lPGlJ@}^W zObhxt&K&ZASv85fj_kT$C;OFEC=iH?Y zQG4M#G|llP;hVWM$~>Sp(F#Wf_4F|Tm^4EWBUwKPUy;N%5xi^g#Ex(@*KwTYma$t5 z>i{&RWlL}g(>aJEcRw}x_q2i&uT3aIKSJ+@3>JK0Vw_<%3~uxK+3G>|Mo10E&Ha=>5=Tha}G5XTOqJ8pFBBxnFeqwX8a zu97HI>X0c9363MmWJU=$xR0%Fe1G$t5a;qH8O7yeVFqdNy*&oDqwvLBLA0%p4CM{? z>zc-C9HuZasr%NOe}fPrD`aLBF!k1${y6d&-NJORtDe@(L{1JfxQnB@L)`P%~xPc9M<1sdz^TC;it z!tn&V(GIKG3KI3++Z}(mwVL8j%rgO_R0h4c*t>$~;4lyua4;L3vO&J&zQPS<>Z?-C z_B5rE2>-_p8%>oN8ECJ;g4UAE2DmZ+OmwVfd$0{U&pi6XJcZws8KB4B;ZC8xB;h72 zxnXL^R@^tAwcyX&ig{r~ais#-nUy9B)&WV(AAJB&3JO*>ME^dz-)Qu`LFO`Un7~Ix zJ4w!3T-lvW<=VD4#h3X0x@piFw|}*%3=Kj!v4u*j4lCO`8QI0qxa~q>$Ex5PI@Du> zS8z--{c)(Kv{TAgnQ<*rgF903> zOiU6H%M2L6_J-)f2}|3}_8afhsa#wG0Nd|_UxI%Rlgsv|avthp<-H0rydJ>wgZ2HERJu}@L|2^2m!Tv1u zaS?7GSN=JL&L%{E9dAZmn?=m2WfPV*Lm1NX2KAu?kV|?%Ex&ff{RRoWYdTFOglzP5 zv|QaCw|~nnpZu2XbGCSA*$|&WfyMfl^%hX-j^g)_pllz#`dX~_2K|4mU5uXq*7uzS zLyiO>$_PyoK&Po7?T@L9ng~lxO@8Kk_ia#c*mEobkW@H2Kvv!}gNzn?lWon88>_C( zu!>0?9ZzhE`hff$;wjPu`_jgKLr<7kjadKFY?nAd1~|CmWyLi}aNQE@V=osbRVRxw zzS8}Kj?a@%C|z2W(1@ck0j*Pcwk2gTbUZPzuVF%R7y@6cHhbtKwhdu8(Z|g&>-yEj z{&hp84yb<7icbOFY;1J3Io6#W9XOyrpY^;Z84%SN*Jdkl>RG+jGzq|Z+W)~qKX*B9 zT=8=nfRbzESr$eh=vdDGp<_O;tL>Cv`8Em2Uiv}w+KG)ahmPKJzp|I=rKvxDdXGnv zfmJwb1U#CA7K{w8!DhEh5hsIo9TYWdxISZ;`Am7}w_5r}M7XK@ z8}z%uP@vuBUyo%c!%(vG?0$i&F`sXXiUI<_I67pM@=maPfL`!zbAy}M+ReO0FL_<{ zXc~K}U44yLYRzQQ`+~+%Xn`X29>6Yn9W7qgx(<)sml(}~S3vD9mOb$1c3zzoq3^A~ zo?X3>$b&P-uEocdb>-EXp;a-!%XOlRKA$^JEvuptMOj9q>IDIMh)`O@qYloGzC(K1A_JX{C)3P?he=>dDzwkje6%#XpqkRh4#16Y5(MaylWR*cg$&Ww$Q4puX= zyoG0IlOe(NyR`D8=q?z@BMDt?jRaxi3l~8J%>p2RP3=!uN%aoG73>n*%~l6x!dtG< z!~p0d;dHSQEIB+jb;u8I(z<&{R@>j*0?qiN)L9?*tyt&rzo;T2s!4toW&x#QaYR9g zB0K`|1c4DWI^&^D6|$Dd&Q}A40=&a0MrsmT9!v#(OA}* zHNqQ|!Te}JG)5Al@x#CUbqo?lCzH}V)k$_S7y@`hnWtvHA1@))|N8jGHK3;?8G_X!fvOR<*NnZ;^4XmLcwghCwmF*90m+J zL#~;#CyMo767hEbchEKE(NoiyIto>XO$&?qYw3r;sO3vOYssVX8ChD1<>>J0d;vY~YizYwgO>!Y#br%hD}g|S~{exE4bq1&-mseh0sg5`zC_K zWz9twB9W&v-~XdiIDX+0gMt>PUQ>8TZ&}g+EGTjnuLeR9X>y=DkSj;Tc-<41IG4K6 z(-S_=nyny<4Oxzx!`i}nQ>%>Bkdw_CD=u|Zm>dEq3sfxK>(=e%P9wd!@|4vYEI;Nn z)0DC2&ol2=(_;qYR6cECrm^@LmH%mfNX@>UuFC^t(DrrGKjt-U?jnQgt^x$^5al=f zV6&MQ9tj=Wa@D*x0Bw-fO7blx6h_Fd@0mk9dO9b~MTKC!G8CE_c(Se@wo2yf$c0*6xYx)SopQ*97Kinv|+R-R)djO0a#!_~J{t8IxE%gCsU zrehdT53rm6Ep$AXhTsQR7%+pH#K|*>IJ$l9Eokf4M1N2djzDMV%3|b05?weoh?A{c z)8x#D;a;LuJv1Q>VCm!)d2g3+-7Na1K`K+2VQ?5w3pm1VC2_tE7b?*DwJ)q*setg| zl*v27hPvKXFwA+}Juqe{`$WX0kP7_-`PI=&gu)&6HrplDM3`^KP#ALJ<&nbyazR2W z#h1U(f`@@w+z5EvL3Rhd_8!Bhbb?$-3S|2lZGe;%-XN^PNTze8XZ?gFwpYaQnD z&l0B!Q#uu^LJZMZJS&ojA4w52E8FjCoocgkw5fl-c!IgR)WqyHmqf->UG50{7_5t1 zX4ZKAb@4#Kbvlnv4r%yyB?#^8N&(467W(zcZ;EQ%OLfkY-A)d)?qpvDsV`22td3hB zucL=C*y?hQ%vp(Y+I z*&o5DS^v0qI8Uoo9RPL$N))2Ko%~EPFHKd0!!F|DZ{s*%x~YQob3}}BSTmmB>tkHn zJl+3YJ;k~_Pd^Y#3iAO@aX4o&!8N~#y;I;9QeO-Lg4R9OD@|lxdm+Cs0u(V{Y@#hq z>_K`S^C?jVOrhLitlaB0uo^8FCZs0V0H(xlTlePm+-{w~A67p)<&^5uxAN7%d%;t; z5-3rZZ?53poblIoS!RdlQ~GC`2lhbxgzu-peSq@clZ>E>EL29L&{lr>rdbW>DC2V6 z|8D1Z8Q?Q<1puAN6F$do7|kK^KPc7`_Kz#c<{nsTZ3|;0f&A6+mP`GGjBoQfF*m*mm8AbVJ2AyTxzs$X8J}h~ zk0)KVi7TidZ$rQ8I|}M+7XNcBPIS$WI8BTp09A*f8)fO)=USf4dxj{}2ht z`t8hzO8%C(O1=3zN`seg_VFJ;=gU#G<9g#_|0XU%$3xO9_I9z0=r2$Q1%$d*npry> z;jH5c+_JcsT-Ls*v~*81`Z-+b&H$Lty`Gx~QCCx5|2Ud? zye1sRdj=e#jD5cpyxvdQe`Ke_HAPc7To$J>0bF&boU5Xh_uP?9SC$&AkDK=iuF!<9 zaRnjcM>E9t?P~l}OXw*}vVdD(axw?n8n%VT>c7Slq?PqLZpnt17Vn^CX1b%#c7RBN zec=NQ{{zIj!{Gg~En0@VtWtVjAHkeY{Q2t#h5SsFBUCW_O>^6qi7dNab8ym0Rq8{Cmm#bUhQ^y&Z#Fsot`aO)I!3Q0r}r zrtpewiHx$$Oy10Q$XtB;=eJ79G@)XN${;modm+u^ThiZH3+47R7Ml0{3Gs@^MpVM@ z>%2uGl2fk@VGw1rPN)%B`UE=;=;-(fQ?vZ5=;+j(3&8pL>T{!JSeqnvlINa6=vIvJ zz(h`Il#g4el{|GRdmb`COZon&hCkNDYLiGm$3M5d{u35wbuOqAMJLihj3)IP0T802 z$ZkJt*A5IGl{FbAcXkon+W{ST3+ot{LbuDmY%Y0=0SUf+dg>sQ{)=bN+;&_QZn;40 zu+`9SV$m}!6Lo;NakbDmfq`|(Yd!&s8j0C>EwB4tAwX%+yPU0X5U{Q#`KFeBr!%FY zaZ}UR3!|aIwOPy@r(#lhVv!xK_cwQ)7hFT=-C61riBpvR%Q2)tL1XPJq_YC5)82hf zLDMYqbX@;hX3}~F5K>iPNHB2DD)>OW7V4hMGs(-~DrzeM@^BIfJ)|5^Zfdq(OHo`I z=0Mn$T;E3O_Pe*2N6zra?5g`+m8`O@Gab(1^_OE}`pV4_$k3Eqe{rAjSQDL>@vGYG zk6b+GlU4udyd7cWfV?T2*zPB{&Pb2-j#%Ar+w{FCTfnq4D68895?;Bzseg)h2mm;z zO68vd$^`_hL53*qCOdAelQ9liM-vxd#gEoBy6A)1{)pXM-rlPKbz^nXTe2B?d|2(P z(oY;A9)@3<*tq52z1Lg0UvpWEH3JR0xG-$&a}s#12}WU%=Ts;+MSM>uQGvOxzXnPa z0h4@l0I(gH)o`|S*k?SSRbk2orT{!G(rJxC=X@Ncz0T;Q>3{%Yw-*+aW-|3}h}dtD zBjmODjJZ8uJTXgf7CqB+s*5rx3h+sRHoyR=n*FUwq$NU(9GHeu0+E%~uyPTn)5$}% zK8uzcKv0h8Csn8!8g!r`ps|ATx{Qv3Fmzkm7=S*S9d69!rWsQ1bYbp@>;8^qkn1NP(1#KLos;*sqw3uXJfc6(P6Bb-J8E1HS2 z;DI}l%x~6{ra3^&;u2VFxE@0~Z8JB>K@kD1K%(36 z-Td%;h?L2lP7X|^wzcS=AlJI6rD({Pr0U@TbFf&B4=^iSks`nzdqr$CX*e|gt-B2G|)W&!q=-Hd(VW% zj=;mRE>Jn9J9H?)_&}N?-~vXF-RS`rFdM_1d(>-hA30$VoCxD!_6H%`&RZ`mKm$=; z@lV9`S-ZOkJx;dvUKZ!0ROw?~O|66|vn@Lz5au(Nh8&4%o-faPjI1OM!PZTkS6H`q zrAnZkHs*{bUb%HZ?1|IdNRN5H13 zbEk2r`EL3HO`THtD#LUvHBS5yDzT?8Lp#s4I?^GI|Su%wOfu?Ulf-0nIgSWYe z<5m-Jk)d6Z1hw%OMw0Ud5f3JRKvs$`JMk4~qTk=PJ_ncsnxlSDU8 zqFd+eon=E5NQ@;QFq+dL3f#PrZ=}jB6XB5JzC!IwFPgiJ^lT9#08uzXNdZq=LNm7o zQPgeSr1dcA`V;xuqLh;g_SF-kIQ)jC$tP8yg9`P5kL4Dv(H$6FIC}eb54EvG%ojNsQvia9;9|D9j1

>id=3u+kVHbxb|eN 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 z

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%0A}rw-^8W@uBU)%bGq}8MaNl*-D4x@hrg)>PT_h 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 VwN8x_{}}n?9VN|Mg$foy{|_~I0WJUl literal 0 HcmV?d00001 diff --git a/publisher/src/components/assets/jc-logo-vector.png b/publisher/src/components/assets/jc-logo-vector.png new file mode 100644 index 0000000000000000000000000000000000000000..331e8a6320bafc5a3b570db9beee3a18e92b6d41 GIT binary patch literal 79735 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

L|#Aaf1RCS!2Y-YQPe*z3ghys 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

    Z8>vZM5wtZpRSBQ` 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

    + + diff --git a/publisher/src/components/assets/jc-logo-vector2.png b/publisher/src/components/assets/jc-logo-vector2.png new file mode 100644 index 0000000000000000000000000000000000000000..7783d3679c442c557edef4807dbc5951ba01b965 GIT binary patch literal 6911 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/publisher/src/components/assets/metrics-view-downright-arrow.png b/publisher/src/components/assets/metrics-view-downright-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..05abd7efe1e114ba1bde21ce6adbcd7a3a6b2148 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^%0R5b!3HFm?=(LIQk(@Ik;M!QVyYm_=ozH)0Vv2= z9OUlAut% literal 0 HcmV?d00001 diff --git a/publisher/src/components/assets/microsoft-excel-icon.svg b/publisher/src/components/assets/microsoft-excel-icon.svg new file mode 100644 index 000000000..1677c9172 --- /dev/null +++ b/publisher/src/components/assets/microsoft-excel-icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/publisher/src/components/assets/not-reported-icon.png b/publisher/src/components/assets/not-reported-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bdc7c3f642e589b22a314be7b37af6be5b6de10c GIT binary patch literal 2388 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 literal 0 HcmV?d00001 diff --git a/publisher/src/components/assets/status-check-icon.png b/publisher/src/components/assets/status-check-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d053cf583e8848c37f456d2241f45e50b87ca851 GIT binary patch literal 2211 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 FV1muP0ww?e literal 0 HcmV?d00001 diff --git a/publisher/src/components/assets/status-error-icon.png b/publisher/src/components/assets/status-error-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..daf09513ee3045434fe9ab445887817edf5bbed1 GIT binary patch literal 1968 zcmV;h2T%BkP)@~0drDELIAGL9O(c600d`2O+f$vv5yPFI7 zWI+{&f>Y-o2(WeRSPu<;t8SyG zfnq$tTKDLu;qVF6Ol<0npt9qSd;KKK=?E1{mvOuwJhsSQ{5$tJ}RA32_ga<8Ja& zNo_DDfb2MNehYp5Z*Z95{2t%kT{qRSGa>-F9Bkpdfad!8qEHX}q6wG8K@&9o3L5`4 zEROLBS>XOSetZQq(Go!V`#s|yHh-Uopfw)9CL4eTr3H{}dm;L;;E)a8EiILfd!=H4 z>R8%1q_6<0nb`-=6r8cO<>ByAk>4pKKqBCJQW&>d7k>WqX(R9bxnqE8 zYW@zMOfWFNAY0|VKUWP_EcLf= z(i}WSKsTORkY@@YOTTwLCJEBUi)OkYymV}raV?nq`?_~{;O9?G46+d?8&XjQo zx<;k;$l0?{mNetX&;Rbh1F!+vS}tS*C4f!$^UbA8sXx;ZA(teQ~N_#anStr}mk!chgQ0uWT9bwns* z{4a0bfNjw8tWXRHzyZpN&{X3Sv;m#r0NfKM#40!f8I_Ei*PuibjZa{I;3>x{V6QDU zgQ7K|sm3R;M|_H_{0mM|M1*;`YJ5e9Vt|vID@=&sxbX>h1t4@pXn^sFj`kk0swpEv zLyRwRUH}Ozv5`jzXadd)P^6t7V`3<~E=T|;Gf5F;j33hw5k}4mpkw@)28b}?%s~N6 z7(d2k5h%YMj~IIo4pDS$M|Tv}CQ%gaaLOzQj!9`287@MWk)r2hq7(5 zmsXSW+w?heve56X3mT7W&lnq% zwJu0!R5OnVHrEAF%4GRU|Bx@TRSW*Uc5SASObjV!i9pweH*bOs$ky@Z?fubEnji)X zP%DI5Bmb$=NQU|U)hl_;#CSf5koJ6AEg(u79=}g+(6HJZT_n_Q$xyzJFWPiNiv)R^ zWbTLq6Eb7Q*1=OPocEL8PR;fCP1=MlE;4wo+>oQeXaK^^k7||i3 zpLOU%=E5u#;08FnZm0oJ{?N>Lnkj(nu`zZ7Jmo;wGw+axxl0qN`Uu}QD2!n2exCDY zeCpzAFq^tq&Rs?kC71B=U_SBrGP!K!)7KkDm3;H*>k0W_#(e)E4YW-W;}eDV2dKc} zTSgN^bc9KXL*7bkJ=sGgBE1V9Y5X%K&W|BV3qbh%(jeWA&hds?0uU-N)6pgYEEXfx z+R<8Dt1STGk1{NekxhE^L8$q)2t8)%;m$jhp$JB5KoS)f4&#|KBN`WT_Bh)l?LhTv1#-q&Im9G&B9SmQ%b9eVgy`>Q^0vg zrC960^vXRl=t!ns5F(@u0Bo-nv(et&-EhU=lY9j+8!y(iKFHeu0000 literal 0 HcmV?d00001 diff --git a/publisher/src/components/assets/todo-icon.svg b/publisher/src/components/assets/todo-icon.svg new file mode 100644 index 000000000..de53d405a --- /dev/null +++ b/publisher/src/components/assets/todo-icon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/publisher/src/components/assets/upload-icon.png b/publisher/src/components/assets/upload-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1b49f23909670c9c0c2b28679578285b63657fc0 GIT binary patch literal 3296 zcmeH~dsGuw9>;%ooX7-F8Sp`{2m~bE^%WAapddkmKv%#wrIbgMhc2sxvM4XjAmyb9 zbbTT!SgW+vR$LHVwGfsy9t8~*@qx7on{`>BqFJD%WSHzl|L*^LPJ7RpGoSg~Z|3~w zH#avYCF{b2r&&8$1HiP<5cviG0wcOjO~t1>d-W;!#8-wyr32VFOdbeMo^qUwq;Cjb z1>f9%rypOC$$?>k09VRwSOpKjHX~FXxG598d_IvjGnmly{;t-G4>@Yt&y5-1ZMZY+H zR5%van>R8cRm7!O=kYnC_u8}febvW3?koS{#qJ#Li@vdYN$JtRtnBVpMQKNs*DMdy z*8{Wf`+$E2d~9;biPL5w=-Far?o;F*=fU=k&I56U{pE0u6GEP^2CrfW^%Ub`a_jyu%)@J4c1=~CBYE;3bY#Rwn6V4l2+=&`D0-Ub= z*QldWCxu`dC9pWtFwG9?>gpzCofv_QwezI3v4^^f*Ked9mSQf>4%Gnysg#SbM`9@^ z38%&6j>(J5p^+HBUa6R~!ZZbegOm%#fg^5V|fAu)|f%$>uZMF`xb++pk_ zm?Yd`?1Y%SxO(jDF^Rc)><9!R33t#ADeX4(@*s--04<{RU9H0WGG&)29n z%fT-Y)b1M9QA|S6BSXs{g)k3yE0J|Ch9~y0u2khnLl7`Vtp`yog5o6hTnT)}hphtD z0m}7>&YJwN)nr-UleTd@{S9qOEc)B^%bRtfwkAL6@9EfP62L_pn#8da1KdOYES z`3Buo8eZDNr7~mcL5f+%hb^~EO`)VLhlGm?_L(P9vxs0ei@Ck{cGHn;tW*_;ZxRTd z-UgkBhIR+|bGvB_x8koP#7MY7S0dh*V1^tm8MtM(NETUYSzZDss-b4CM)h0{9e;pM zo}oIBROga#Ps&AMwHi8?8mdD{^$1oH?x`Hs;*^I$>rX=$4NGsEhASv$2L&g$vRMZx z#>j`03O1{ZV$v|hvrmh#qhNM2>-!0Im=amvLW=3)!|ZLWZviIk6s#bhVhnspN@fLz zF;S3|$X4#Bm^SRTv6X+pgq?z|#JLGRcqX%zI5$CoXCfPgbFUm=t;SUEL4y|4-%VWv ze(#>(c-mMyUkGO~9W~Yl385L&A!BVKCJ%5dFxFZLVWk6{>M(UV(BQ&{@U3kBrxYMH zzcj$#0e$WO@7yxgPZcr=1d}gNJ(80Z?}O6Lpmiz%dp`V>#70SJnG;gSmImB;Tij}rUY{jbzxb)AFoJ~gnC|r0@dUPVZ6B@NGCn=W z(-lk!W~w*te1xX@PR2Ym=L}EphSaMgC&kl|d5G6Y!i$wKuVFwx1*z{x_2(OF zeNP9e%XtT&W{IXc>1%xvk6r_vHin2{Ip8Jn$PTuU(0O9%htuJFWcwdv+VoUqPe7cz}CeQ z7BSJx3}(m9WUh2qwYR?v8@TMB8Z!23Pojs$n_{}1Ru-wv{sG+B<0qF#Z!T0aVR`O5 zQ+>wDm)#%y+1Q%;+_LA~m`;{yI3L{gq-@Cips>Zf=ZxmH@jG_NuUWHe@aL`>W4#{` zu-pTfjajqsZ?ZjrT?l{-@1u}M{w99q{TM$B{?{+|ZQjuqgBQf)xGuGAyK#0}BoEeX zYI>2qy)CFRFB1K>V18BKml~J%s}~n3t}O)hdcP_EM?1x`qMO5F+vL%EQ3x)4-1PKM iLz90}era@`uuM63V_k`F+Lw~aOlVNJ{F_zr`~L@ax~d)k literal 0 HcmV?d00001 diff --git a/publisher/src/components/assets/warning-icon.svg b/publisher/src/components/assets/warning-icon.svg new file mode 100644 index 000000000..9759aa5c8 --- /dev/null +++ b/publisher/src/components/assets/warning-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/publisher/src/index.tsx b/publisher/src/index.tsx new file mode 100644 index 000000000..55146997f --- /dev/null +++ b/publisher/src/index.tsx @@ -0,0 +1,124 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import ReactDOM from "react-dom"; +import { BrowserRouter } from "react-router-dom"; +import { createGlobalStyle } from "styled-components/macro"; + +import App from "./App"; +import AuthWall from "./components/Auth"; +import { palette } from "./components/GlobalStyles"; +import { StoreProvider } from "./stores"; + +// load analytics +window.analytics = window.analytics || []; +const { analytics } = window; +if (!analytics.initialize) { + if (analytics.invoked) { + // eslint-disable-next-line no-console + console.error("Segment snippet included twice."); + } else { + analytics.invoked = true; + analytics.methods = [ + "trackSubmit", + "trackClick", + "trackLink", + "trackForm", + "pageview", + "identify", + "reset", + "group", + "track", + "ready", + "alias", + "debug", + "page", + "once", + "off", + "on", + "addSourceMiddleware", + "addIntegrationMiddleware", + "setAnonymousId", + "addDestinationMiddleware", + ]; + analytics.factory = function (e: unknown) { + return function () { + const t = Array.prototype.slice.call(arguments); // eslint-disable-line prefer-rest-params + t.unshift(e); + analytics.push(t); + return analytics; + }; + }; + for (let e = 0; e < analytics.methods.length; e += 1) { + const key = analytics.methods[e]; + analytics[key] = analytics.factory(key); + } + analytics.load = function (key: unknown, e: unknown) { + const t = document.createElement("script"); + t.type = "text/javascript"; + t.async = !0; + t.src = `https://cdn.segment.com/analytics.js/v1/${key}/analytics.min.js`; + const n = document.getElementsByTagName("script")[0]; + n.parentNode?.insertBefore(t, n); + analytics._loadOptions = e; // eslint-disable-line no-underscore-dangle + }; + analytics._writeKey = window.SEGMENT_KEY; // eslint-disable-line no-underscore-dangle + analytics.SNIPPET_VERSION = "4.15.3"; + analytics.load(window.SEGMENT_KEY); + analytics.page(); + } +} + +const GlobalStyle = createGlobalStyle` + * { + box-sizing: border-box; + margin: 0; + padding: 0; + } + + html, body, #root { + height: 100%; + } + + body { + width: 100%; + font-family: "Inter", sans-serif; + font-weight: 500; + font-size: 16px; + background-color: ${palette.solid.white}; + color: ${palette.solid.darkgrey}; + } + + input, textarea { + font-family: "Inter", sans-serif; + } +`; + +ReactDOM.render( + + + + + + + + + + , + document.getElementById("root") +); diff --git a/publisher/src/mocks/PreviewDataObject.tsx b/publisher/src/mocks/PreviewDataObject.tsx new file mode 100644 index 000000000..ab2aa1355 --- /dev/null +++ b/publisher/src/mocks/PreviewDataObject.tsx @@ -0,0 +1,88 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { useState } from "react"; +import styled from "styled-components/macro"; + +import { palette } from "../components/GlobalStyles"; + +const PreviewButton = styled.button<{ open?: boolean }>` + height: 80px; + width: 80px; + position: fixed; + bottom: 15px; + right: 15px; + z-index: 1000; + background: ${palette.solid.blue}; + color: ${palette.solid.white}; + border: none; + border-radius: 50%; + opacity: ${({ open }) => (open ? 1 : 0)}; + transition: 0.2s ease; + + &:hover { + cursor: pointer; + opacity: 1; + } +`; + +const PreviewDataObject: React.FC<{ + description?: string; + objectToDisplay: Record; +}> = ({ description, objectToDisplay }) => { + const [open, setOpen] = useState(false); + + return ( + <> + setOpen(!open)} open={open}> + {open ? "Close" : "Preview"} + + {open && ( +

    +          

    + {description} +

    + {JSON.stringify(objectToDisplay, null, 2)} +
    + )} + + ); +}; + +export default PreviewDataObject; diff --git a/publisher/src/mocks/mockReport.ts b/publisher/src/mocks/mockReport.ts new file mode 100644 index 000000000..952ad6b38 --- /dev/null +++ b/publisher/src/mocks/mockReport.ts @@ -0,0 +1,450 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export const mockOverview = { + id: 0, + year: 2022, + month: 4, + frequency: "MONTHLY", + last_modified_at: "April 12 2022", + editors: ["Editor #1", "Editor #2"], + status: "DRAFT", +}; + +export const mockMetrics = [ + { + key: "READMISSION_RATE", + display_name: "Readmission Rate", + description: + "Measure the number of individuals admitted who had at least one other prison admission within the prior year.", + reporting_note: + "Exclude re-entry after a temporary exit (escape, work release, appointment, etc).", + value: null, + unit: "readmissions", + category: "READMISSION_RATE", + label: "Readmission Rate", + definitions: [ + { + term: "", + definition: "", + }, + ], + contexts: [ + { + key: "DEFINITION_OF_READMISSION", + display_name: "Definition of Readmission", + reporting_note: "Agency's definition of readmission.", + required: false, + type: "TEXT", + value: null, + }, + { + key: "ADDITIONAL_CONTEXT", + display_name: "Additional Context", + reporting_note: + "Add any additional context that you would like to provide here.", + required: false, + type: "TEXT", + value: null, + }, + ], + disaggregations: [ + { + key: "READMISSION_KEY_TYPE", + display_name: "Readmission Types", + dimensions: [ + { + key: "NEW_OFFENSE", + label: "New Offense", + value: null, + reporting_note: "Readmission: New Offense", + }, + { + key: "VIOLATION_OF_CONDITIONS", + label: "Violation of Conditions", + value: null, + reporting_note: "Readmission: Violation of Conditions", + }, + { + key: "OTHER", + label: "Other", + value: null, + reporting_note: "Readmission: Other", + }, + { + key: "UNKNOWN", + label: "Unknown", + value: null, + reporting_note: "Readmission: Unknown", + }, + ], + required: false, + helper_text: "Break down the metric by NIBRS offense types.", + }, + ], + }, + { + key: "ADMISSIONS", + display_name: "Admissions", + description: + "Measure the number of new admission to the state corrections system.", + reporting_note: + "Report individual in the most serious category (new sentence > vilation > hold).", + value: null, + unit: "admissions", + category: "ADMISSIONS", + label: "Admissions", + definitions: [ + { + term: "", + definition: "", + }, + ], + contexts: [ + { + key: "DEFINITION_OF_ADMISSION", + display_name: "Definition of Admission", + reporting_note: "Agency's definition of admission.", + required: false, + type: "TEXT", + value: null, + }, + { + key: "ADDITIONAL_CONTEXT", + display_name: "Additional Context", + reporting_note: + "Add any additional context that you would like to provide here.", + required: false, + type: "TEXT", + value: null, + }, + ], + disaggregations: [ + { + key: "ADMISSIONS_KEY_TYPE", + display_name: "Population Type", + dimensions: [ + { + key: "NEW_SENTENCE", + label: "New Sentence", + value: null, + reporting_note: "Admissions: New Sentence", + }, + { + key: "TRANSFER_HOLD", + label: "Transfer/Hold", + value: null, + reporting_note: "Admissions: Transfer/Hold", + }, + { + key: "SUPERVISION_VIOLATION_REVOCATION", + label: "Supervision Violation/Revocation", + value: null, + reporting_note: "Admissions: Supervision Violation/Revocation", + }, + { + key: "OTHER", + label: "Other", + value: null, + reporting_note: "Admissions: Other", + }, + { + key: "UNKNOWN", + label: "Unknown", + value: null, + reporting_note: "Admissions: Unknown", + }, + ], + required: false, + helper_text: "", + }, + ], + }, + { + key: "AVERAGE_DAILY_POPULATION", + display_name: "Average Daily Population", + description: + "Measures the average daily population held in the state corrections system.", + reporting_note: + "Calculate the average against a 30-day month. Report individual in the most serious category (new sentence > vilation > hold).", + value: null, + unit: "people", + category: "PEOPLE", + label: "People", + definitions: [ + { + term: "", + definition: "", + }, + ], + contexts: [ + { + key: "VOC_COUNT_QUESTION", + display_name: + "Are individuals admitted for violation of conditions counted within the above population categories?", + reporting_note: + "Whether individual admitted for violation of conditions are counted within or separate from the above population categories.", + required: false, + type: "MULTIPLE_CHOICE", + value: null, + }, + { + key: "ADDITIONAL_CONTEXT", + display_name: "Additional Context", + reporting_note: + "Add any additional context that you would like to provide here.", + required: false, + type: "TEXT", + value: null, + }, + ], + disaggregations: [ + { + key: "AVG_DAILY_POP_KEY_TYPE", + display_name: "Population Type", + dimensions: [ + { + key: "NEW_SENTENCE", + label: "New Sentence", + value: null, + reporting_note: "Average Daily Population: New Sentence", + }, + { + key: "TRANSFER_HOLD", + label: "Transfer/Hold", + value: null, + reporting_note: "Average Daily Population: Transfer/Hold", + }, + { + key: "SUPERVISION_VIOLATION_REVOCATION", + label: "Supervision Violation/Revocation", + value: null, + reporting_note: + "Average Daily Population: Supervision Violation/Revocation", + }, + { + key: "OTHER", + label: "Other", + value: null, + reporting_note: "Average Daily Population: Other", + }, + { + key: "UNKNOWN", + label: "Unknown", + value: null, + reporting_note: "Average Daily Population: Unknown", + }, + ], + required: false, + helper_text: "", + }, + { + key: "RACE_ETHNICITY_KEY_TYPE", + display_name: "Race & Ethnicity", + dimensions: [ + { + key: "WHITE", + label: "White", + value: null, + reporting_note: "Race/Ethnicity: White", + }, + { + key: "BLACK", + label: "Black", + value: null, + reporting_note: "Race/Ethnicity: Black", + }, + { + key: "HISPANIC_LATINX", + label: "Hispanic/Latinx", + value: null, + reporting_note: "Race/Ethnicity: Hispanic/Latinx", + }, + { + key: "ASIAN", + label: "Asian", + value: null, + reporting_note: "Race/Ethnicity: Asian", + }, + { + key: "NATIVE_AMERICAN", + label: "Native American", + value: null, + reporting_note: "Race/Ethnicity: Native American", + }, + { + key: "NATIVE_HAWAIIAN_PI", + label: "Native Hawaiian or Pacific Islander", + value: null, + reporting_note: + "Race/Ethnicity: Native Hawaiian or Pacific Islander", + }, + { + key: "OTHER", + label: "Other", + value: null, + reporting_note: "Race/Ethnicity: Other", + }, + { + key: "UNKNOWN", + label: "Unknown", + value: null, + reporting_note: "Race/Ethnicity: Unknown", + }, + ], + required: false, + helper_text: + "Measure the average daily correctional population of each race/ethnic group. This is the average daily population for each group. Calculate the average against a 30-day month.", + }, + { + key: "GENDER_KEY_TYPE", + display_name: "Gender", + dimensions: [ + { + key: "MALE", + label: "Male", + value: null, + reporting_note: "Gender: Male", + }, + { + key: "FEMALE", + label: "Female", + value: null, + reporting_note: "Gender: Female", + }, + { + key: "NON_BINARY", + label: "Non-binary", + value: null, + reporting_note: "Gender: Non-binary", + }, + { + key: "OTHER", + label: "Other", + value: null, + reporting_note: "Gender: Other", + }, + { + key: "UNKNOWN", + label: "Unknown", + value: null, + reporting_note: "Gender: Unknown", + }, + ], + required: false, + helper_text: + "Measure the average daily correctional population of each gender group. This is the average daily population for each group. Calculate the average against a 30-day month.", + }, + ], + }, + { + key: "RELEASES", + display_name: "Releases", + description: "Measure the number of releases from the facility.", + reporting_note: + "Exclude temporary release (work release, appointment, court hearing, etc).", + value: null, + unit: "releases", + category: "RELEASES", + label: "Releases", + definitions: [ + { + term: "", + definition: "", + }, + ], + contexts: [ + { + key: "DEFINITION_OF_SUPERVISION", + display_name: "Definition of Supervision", + reporting_note: + "Agency's definition of supervision (probation, parole, either).", + required: false, + type: "TEXT", + value: null, + }, + { + key: "ADDITIONAL_CONTEXT", + display_name: "Additional Context", + reporting_note: + "Add any additional context that you would like to provide here.", + required: false, + type: "TEXT", + value: null, + }, + ], + disaggregations: [ + { + key: "RELEASE_KEY_TYPE", + display_name: "Release Types", + dimensions: [ + { + key: "SENTENCE_COMPLETION", + label: "Sentence Completion", + value: null, + reporting_note: "Releases: New Sentence", + }, + { + key: "PRETRIAL_RELEASE", + label: "Pretrial Release", + value: null, + reporting_note: "Releases: Pretrial Release", + }, + { + key: "TRANSFER", + label: "Transfer", + value: null, + reporting_note: "Releases: Transfer", + }, + { + key: "UNAPPROVED ABSENCE", + label: "Unapproved Absence", + value: null, + reporting_note: "Releases: Unapproved Absence", + }, + { + key: "COMPASSIONATE", + label: "Compassionate", + value: null, + reporting_note: "Releases: Compassionate", + }, + { + key: "OTHER", + label: "Other", + value: null, + reporting_note: "Releases: Other", + }, + { + key: "UNKNOWN", + label: "Unknown", + value: null, + reporting_note: "Releases: Unknown", + }, + ], + required: false, + helper_text: "", + }, + ], + }, +]; + +export const mockReport = { + ...mockOverview, + metrics: mockMetrics, +}; + +export default mockReport; diff --git a/publisher/src/mocks/reportOverviews.json b/publisher/src/mocks/reportOverviews.json new file mode 100644 index 000000000..d53b2c8d2 --- /dev/null +++ b/publisher/src/mocks/reportOverviews.json @@ -0,0 +1,438 @@ +{ + "orderedReports": [ + { + "id": 0, + "year": 2022, + "month": 4, + "frequency": "MONTHLY", + "last_modified_at": "1648771200000", + "editors": ["Editor #1", "Editor #2"], + "status": "DRAFT" + }, + { + "id": 1, + "year": 2022, + "month": 3, + "frequency": "MONTHLY", + "last_modified_at": "1646092800000", + "editors": ["Editor #1", "Editor #2", "Editor #3"], + "status": "DRAFT" + }, + { + "id": 2, + "year": 2022, + "month": 2, + "frequency": "MONTHLY", + "last_modified_at": "1643673600000", + "editors": ["Editor #3"], + "status": "PUBLISHED" + }, + { + "id": 3, + "year": 2022, + "month": 1, + "frequency": "MONTHLY", + "last_modified_at": "1640995200000", + "editors": ["Editor #1", "Editor #2"], + "status": "PUBLISHED" + }, + { + "id": 4, + "year": 2021, + "month": 12, + "frequency": "ANNUAL", + "last_modified_at": "1640995200000", + "editors": ["Editor #1", "Editor #2", "Editor #3", "Editor #4"], + "status": "PUBLISHED" + }, + { + "id": 5, + "year": 2021, + "month": 12, + "frequency": "MONTHLY", + "last_modified_at": "1640995200000", + "editors": ["Editor #4"], + "status": "PUBLISHED" + }, + { + "id": 6, + "year": 2021, + "month": 11, + "frequency": "MONTHLY", + "last_modified_at": "1635724800000", + "editors": ["Editor #1", "Editor #2"], + "status": "PUBLISHED" + }, + { + "id": 7, + "year": 2021, + "month": 10, + "frequency": "MONTHLY", + "last_modified_at": "1633046400000", + "editors": ["Editor #1", "Editor #2", "Editor #3"], + "status": "PUBLISHED" + }, + { + "id": 8, + "year": 2021, + "month": 9, + "frequency": "MONTHLY", + "last_modified_at": "1630454400000", + "editors": ["Editor #3"], + "status": "PUBLISHED" + }, + { + "id": 9, + "year": 2021, + "month": 8, + "frequency": "MONTHLY", + "last_modified_at": "1627776000000", + "editors": ["Editor #1", "Editor #2"], + "status": "PUBLISHED" + }, + { + "id": 10, + "year": 2021, + "month": 7, + "frequency": "MONTHLY", + "last_modified_at": "", + "editors": [], + "status": "NOT_STARTED" + }, + { + "id": 11, + "year": 2021, + "month": 6, + "frequency": "MONTHLY", + "last_modified_at": "1622505600000", + "editors": ["Editor #1", "Editor #2"], + "status": "DRAFT" + }, + { + "id": 12, + "year": 2021, + "month": 5, + "frequency": "MONTHLY", + "last_modified_at": "1619827200000", + "editors": ["Editor #1", "Editor #2", "Editor #3"], + "status": "DRAFT" + }, + { + "id": 13, + "year": 2021, + "month": 4, + "frequency": "MONTHLY", + "last_modified_at": "1617235200000", + "editors": ["Editor #3"], + "status": "PUBLISHED" + }, + { + "id": 14, + "year": 2021, + "month": 3, + "frequency": "MONTHLY", + "last_modified_at": "1614556800000", + "editors": ["Editor #1", "Editor #2"], + "status": "PUBLISHED" + }, + { + "id": 15, + "year": 2021, + "month": 2, + "frequency": "MONTHLY", + "last_modified_at": "", + "editors": [], + "status": "NOT_STARTED" + }, + { + "id": 16, + "year": 2021, + "month": 1, + "frequency": "MONTHLY", + "last_modified_at": "1609459200000", + "editors": ["Editor #1", "Editor #2"], + "status": "DRAFT" + }, + { + "id": 17, + "year": 2020, + "month": 12, + "frequency": "ANNUAL", + "last_modified_at": "", + "editors": [], + "status": "NOT_STARTED" + }, + { + "id": 18, + "year": 2020, + "month": 12, + "frequency": "MONTHLY", + "last_modified_at": "", + "editors": [], + "status": "NOT_STARTED" + }, + { + "id": 19, + "year": 2020, + "month": 11, + "frequency": "MONTHLY", + "last_modified_at": "1604188800000", + "editors": ["Editor #1", "Editor #2"], + "status": "DRAFT" + }, + { + "id": 20, + "year": 2020, + "month": 10, + "frequency": "MONTHLY", + "last_modified_at": "1601510400000", + "editors": ["Editor #1", "Editor #2", "Editor #3"], + "status": "DRAFT" + }, + { + "id": 21, + "year": 2020, + "month": 9, + "frequency": "MONTHLY", + "last_modified_at": "1598918400000", + "editors": ["Editor #3"], + "status": "PUBLISHED" + }, + { + "id": 22, + "year": 2020, + "month": 8, + "frequency": "MONTHLY", + "last_modified_at": "1596240000000", + "editors": ["Editor #1", "Editor #2"], + "status": "PUBLISHED" + }, + { + "id": 23, + "year": 2019, + "month": 7, + "frequency": "ANNUAL", + "last_modified_at": "", + "editors": [], + "status": "NOT_STARTED" + } + ], + "unorderedReports": [ + { + "id": 1, + "year": 2022, + "month": 3, + "frequency": "MONTHLY", + "last_modified_at": "1646092800000", + "editors": ["Editor #1", "Editor #2", "Editor #3"], + "status": "DRAFT" + }, + { + "id": 22, + "year": 2020, + "month": 8, + "frequency": "MONTHLY", + "last_modified_at": "1596240000000", + "editors": ["Editor #1", "Editor #2"], + "status": "PUBLISHED" + }, + { + "id": 3, + "year": 2022, + "month": 1, + "frequency": "MONTHLY", + "last_modified_at": "1640995200000", + "editors": ["Editor #1", "Editor #2"], + "status": "PUBLISHED" + }, + { + "id": 5, + "year": 2021, + "month": 12, + "frequency": "MONTHLY", + "last_modified_at": "1640995200000", + "editors": ["Editor #4"], + "status": "PUBLISHED" + }, + { + "id": 11, + "year": 2021, + "month": 6, + "frequency": "MONTHLY", + "last_modified_at": "1622505600000", + "editors": ["Editor #1", "Editor #2"], + "status": "DRAFT" + }, + { + "id": 6, + "year": 2021, + "month": 11, + "frequency": "MONTHLY", + "last_modified_at": "1635724800000", + "editors": ["Editor #1", "Editor #2"], + "status": "PUBLISHED" + }, + { + "id": 0, + "year": 2022, + "month": 4, + "frequency": "MONTHLY", + "last_modified_at": "1648771200000", + "editors": ["Editor #1", "Editor #2"], + "status": "DRAFT" + }, + { + "id": 7, + "year": 2021, + "month": 10, + "frequency": "MONTHLY", + "last_modified_at": "1633046400000", + "editors": ["Editor #1", "Editor #2", "Editor #3"], + "status": "PUBLISHED" + }, + { + "id": 19, + "year": 2020, + "month": 11, + "frequency": "MONTHLY", + "last_modified_at": "1604188800000", + "editors": ["Editor #1", "Editor #2"], + "status": "DRAFT" + }, + { + "id": 9, + "year": 2021, + "month": 8, + "frequency": "MONTHLY", + "last_modified_at": "1627776000000", + "editors": ["Editor #1", "Editor #2"], + "status": "PUBLISHED" + }, + { + "id": 10, + "year": 2021, + "month": 7, + "frequency": "MONTHLY", + "last_modified_at": "", + "editors": [], + "status": "NOT_STARTED" + }, + { + "id": 12, + "year": 2021, + "month": 5, + "frequency": "MONTHLY", + "last_modified_at": "1619827200000", + "editors": ["Editor #1", "Editor #2", "Editor #3"], + "status": "DRAFT" + }, + { + "id": 13, + "year": 2021, + "month": 4, + "frequency": "MONTHLY", + "last_modified_at": "1617235200000", + "editors": ["Editor #3"], + "status": "PUBLISHED" + }, + { + "id": 8, + "year": 2021, + "month": 9, + "frequency": "MONTHLY", + "last_modified_at": "1630454400000", + "editors": ["Editor #3"], + "status": "PUBLISHED" + }, + { + "id": 14, + "year": 2021, + "month": 3, + "frequency": "MONTHLY", + "last_modified_at": "1614556800000", + "editors": ["Editor #1", "Editor #2"], + "status": "PUBLISHED" + }, + { + "id": 15, + "year": 2021, + "month": 2, + "frequency": "MONTHLY", + "last_modified_at": "", + "editors": [], + "status": "NOT_STARTED" + }, + { + "id": 2, + "year": 2022, + "month": 2, + "frequency": "MONTHLY", + "last_modified_at": "1643673600000", + "editors": ["Editor #3"], + "status": "PUBLISHED" + }, + { + "id": 16, + "year": 2021, + "month": 1, + "frequency": "MONTHLY", + "last_modified_at": "1609459200000", + "editors": ["Editor #1", "Editor #2"], + "status": "DRAFT" + }, + { + "id": 18, + "year": 2020, + "month": 12, + "frequency": "MONTHLY", + "last_modified_at": "", + "editors": [], + "status": "NOT_STARTED" + }, + { + "id": 20, + "year": 2020, + "month": 10, + "frequency": "MONTHLY", + "last_modified_at": "1601510400000", + "editors": ["Editor #1", "Editor #2", "Editor #3"], + "status": "DRAFT" + }, + { + "id": 4, + "year": 2021, + "month": 12, + "frequency": "ANNUAL", + "last_modified_at": "1640995200000", + "editors": ["Editor #1", "Editor #2", "Editor #3", "Editor #4"], + "status": "PUBLISHED" + }, + { + "id": 21, + "year": 2020, + "month": 9, + "frequency": "MONTHLY", + "last_modified_at": "1598918400000", + "editors": ["Editor #3"], + "status": "PUBLISHED" + }, + { + "id": 17, + "year": 2020, + "month": 12, + "frequency": "ANNUAL", + "last_modified_at": "", + "editors": [], + "status": "NOT_STARTED" + }, + { + "id": 23, + "year": 2019, + "month": 7, + "frequency": "ANNUAL", + "last_modified_at": "", + "editors": [], + "status": "NOT_STARTED" + } + ] +} diff --git a/publisher/src/pages/AccountSettings.tsx b/publisher/src/pages/AccountSettings.tsx new file mode 100644 index 000000000..7ad5e48c0 --- /dev/null +++ b/publisher/src/pages/AccountSettings.tsx @@ -0,0 +1,99 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React from "react"; +import { useNavigate } from "react-router-dom"; +import styled from "styled-components/macro"; + +import { + Button, + GoBack, + TextInput, + Title, + TitleWrapper, +} from "../components/Forms"; +import { useStore } from "../stores"; + +const AccountSettingsPage = styled.div` + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +`; + +const SettingsFormPanel = styled.div` + width: 644px; +`; + +const ButtonWrapper = styled.div` + display: flex; + flex: 1 1 auto; + justify-content: space-between; +`; + +const AccountSettings = () => { + const { userStore } = useStore(); + const navigate = useNavigate(); + const [email, setEmail] = React.useState(userStore?.email || ""); + const [name, setName] = React.useState(userStore?.name || ""); + return ( + + navigate(-1)} + /> + + + Settings + + + setName(e.target.value)} + /> + setEmail(e.target.value)} + /> + + + + + + + + ); +}; + +export default AccountSettings; diff --git a/publisher/src/pages/Reports.tsx b/publisher/src/pages/Reports.tsx new file mode 100644 index 000000000..37c58b1ca --- /dev/null +++ b/publisher/src/pages/Reports.tsx @@ -0,0 +1,379 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { reaction, when } from "mobx"; +import { observer } from "mobx-react-lite"; +import React, { Fragment, useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; + +import checkmarkIcon from "../components/assets/status-check-icon.png"; +import { Badge, BadgeColorMapping } from "../components/Badge"; +import { Loading } from "../components/Loading"; +import { Onboarding } from "../components/Onboarding"; +import { + AdditionalEditorsTooltip, + Cell, + EmptySelectionCircle, + LabelCell, + LabelRow, + NoReportsDisplay, + PageTitle, + ReportActions, + ReportActionsItem, + ReportActionsNewIcon, + ReportActionsSelectIcon, + ReportsHeader, + Row, + SelectedCheckmark, + TabbedActionsWrapper, + TabbedBar, + TabbedItem, + TabbedOptions, + Table, +} from "../components/Reports"; +import { Permission, ReportOverview } from "../shared/types"; +import { useStore } from "../stores"; +import { + normalizeString, + printCommaSeparatedList, + printElapsedDaysMonthsYearsSinceDate, + printReportTitle, + removeSnakeCase, +} from "../utils"; + +enum ReportStatusFilterOption { + AllReports = "All Reports", + Draft = "Draft", + Published = "Published", + NotStarted = "Not_Started", +} + +const reportListColumnTitles = [ + "Report Period", + "Frequency", + "Editors", + "Last Modified", +]; + +const Reports: React.FC = () => { + const { reportStore, userStore, datapointsStore } = useStore(); + const navigate = useNavigate(); + + const [showOnboarding, setShowOnboarding] = useState(true); + const [loadingError, setLoadingError] = useState( + undefined + ); + const [showAdditionalEditorsTooltip, setShowAdditionalEditorsTooltip] = + useState(); + const [reportsFilter, setReportsFilter] = useState("allreports"); + const [selectionMode, setSelectionMode] = useState(false); + const [reportsToDelete, setReportsToDelete] = useState([]); + + const enterSelectionMode = () => setSelectionMode(true); + const exitSelectionMode = () => setSelectionMode(false); + const clearAllReportsToDelete = () => setReportsToDelete([]); + const addOrRemoveReportToDelete = (reportID: number) => + setReportsToDelete((prev) => + !prev.includes(reportID) + ? [...prev, reportID] + : prev.filter((id) => id !== reportID) + ); + + const filterReportsBy = ( + e: React.MouseEvent + ): void => { + const { id } = e.target as HTMLDivElement; + const normalizedID = normalizeString(id); + setReportsFilter(normalizedID); + }; + + const renderReportYearRow = ( + filteredReports: ReportOverview[], + currentIndex: number, + currentReportYear: number + ): JSX.Element | undefined => { + const indexIsLessThanListOfReports = + currentIndex + 1 < filteredReports.length; + const nextReportYear = + indexIsLessThanListOfReports && filteredReports[currentIndex + 1].year; + + if (indexIsLessThanListOfReports && nextReportYear !== currentReportYear) { + return {nextReportYear}; + } + }; + + // load report overviews after the /api/users request returns successfully + useEffect( + () => + // return when's disposer so it is cleaned up if it never runs + when( + () => userStore.userInfoLoaded, + async () => { + const result = await reportStore.getReportOverviews(); + if (result instanceof Error) { + setLoadingError(result.message); + } + } + ), + [reportStore, userStore] + ); + + // reload report overviews when the current agency ID changes + useEffect( + () => + // return disposer so it is cleaned up if it never runs + reaction( + () => userStore.currentAgencyId, + async (currentAgencyId, previousAgencyId) => { + // prevents us from calling getReportOverviews twice on initial load + if (previousAgencyId !== undefined) { + reportStore.resetState(); + datapointsStore.resetState(); + const result = await reportStore.getReportOverviews(); + if (result instanceof Error) { + setLoadingError(result.message); + } + } + } + ), + [reportStore, userStore, datapointsStore] + ); + + const filteredReportsMemoized = React.useMemo( + () => + reportsFilter === "allreports" + ? reportStore.reportOverviewList + : reportStore.reportOverviewList.filter( + (report) => normalizeString(report.status) === reportsFilter + ), + [reportStore.reportOverviewList, reportsFilter] + ); + + const renderReports = (userHasNoAgency: boolean) => { + if (reportStore.loadingOverview) { + return ; + } + if (loadingError) { + return {`Error: ${loadingError}`}; + } + + const reportStatusBadgeColors: BadgeColorMapping = { + DRAFT: "ORANGE", + PUBLISHED: "GREEN", + NOT_STARTED: "RED", + }; + + return ( + <> + {filteredReportsMemoized.length > 0 ? ( + filteredReportsMemoized.map( + (report: ReportOverview, index: number) => ( + + { + if (!selectionMode) { + navigate(`/reports/${report.id}`); + } else { + addOrRemoveReportToDelete(report.id); + } + }} + selected={ + selectionMode && reportsToDelete.includes(report.id) + } + > + {/* Report Period */} + + {selectionMode && ( + <> + {reportsToDelete.includes(report.id) ? ( + + ) : ( + + )} + + )} + + {printReportTitle( + report.month, + report.year, + report.frequency + )} + + + {removeSnakeCase(report.status).toLowerCase()} + + + + {/* Status */} + {report.frequency.toLowerCase()} + + {/* Editors */} + { + if (report.editors.length > 1) { + setShowAdditionalEditorsTooltip(report.id); + } + }} + onMouseLeave={() => + setShowAdditionalEditorsTooltip(undefined) + } + > + {report.editors.length === 0 ? ( + "-" + ) : ( + <> + {report.editors[0]} + {report.editors.length > 1 + ? `& ${report.editors.length - 1} other${ + report.editors.length > 2 ? "s" : "" + }` + : ``} + + {showAdditionalEditorsTooltip === report.id && ( + + {printCommaSeparatedList(report.editors)} + + )} + + )} + + + {/* Last Modified */} + + {!report.last_modified_at + ? "-" + : printElapsedDaysMonthsYearsSinceDate( + report.last_modified_at + )} + + + + {/* Report Year Marker */} + {renderReportYearRow( + filteredReportsMemoized, + index, + report.year + )} + + ) + ) + ) : ( + + {userHasNoAgency + ? "It looks like no agency is tied to this account. Please reach out to the Justice Counts team for assistance." + : "No reports to display."} + + )} + + ); + }; + + return ( + <> + + Reports + + {/* Filter Reports By */} + + + {Object.values(ReportStatusFilterOption).map((option) => ( + filterReportsBy(e)} + > + {removeSnakeCase(option)} + + ))} + + + + {/* Admin Only: Manage Reports */} + {userStore.permissions.includes(Permission.RECIDIVIZ_ADMIN) && ( + <> + + {!selectionMode && ( + <> + + Select + + navigate("/reports/create")} + > + New + + + )} + + {selectionMode && ( + <> + { + if (reportsToDelete.length > 0) { + reportStore.deleteReports(reportsToDelete); + exitSelectionMode(); + clearAllReportsToDelete(); + } + }} + > + Delete{" "} + + + { + exitSelectionMode(); + clearAllReportsToDelete(); + }} + > + Done + + + )} + + + )} + + + + {/* Labels */} + + {reportListColumnTitles.map((title) => ( + {title} + ))} + + + + {/* Reports List Table */} + {renderReports(userStore.userAgencies?.length === 0)}
    + + {/* Onboarding */} + {userStore.onboardingTopicsCompleted?.reportsview === false && + showOnboarding && ( + + )} + + ); +}; + +export default observer(Reports); diff --git a/publisher/src/react-app-env.d.ts b/publisher/src/react-app-env.d.ts new file mode 100644 index 000000000..6431bc5fc --- /dev/null +++ b/publisher/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/publisher/src/setupTests.ts b/publisher/src/setupTests.ts new file mode 100644 index 000000000..47215a52d --- /dev/null +++ b/publisher/src/setupTests.ts @@ -0,0 +1,24 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import "@testing-library/jest-dom"; + +import { enableFetchMocks } from "jest-fetch-mock"; + +enableFetchMocks(); + +window.APP_CONFIG = { + domain: "", + client_id: "", + audience: "", +}; + +// polyfill for when running jest tests +/* eslint-disable no-extend-native */ +if (typeof String.prototype.replaceAll === "undefined") { + String.prototype.replaceAll = function (match, replace) { + return this.replace(new RegExp(match, "g"), () => replace as string); + }; +} +/* eslint-enable no-extend-native */ diff --git a/publisher/src/shared/types.ts b/publisher/src/shared/types.ts new file mode 100644 index 000000000..b8ad3d31f --- /dev/null +++ b/publisher/src/shared/types.ts @@ -0,0 +1,275 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export enum Permission { + RECIDIVIZ_ADMIN = "recidiviz_admin", + SWITCH_AGENCIES = "switch_agencies", +} + +export type AgencySystems = + | "LAW_ENFORCEMENT" + | "PROSECUTION" + | "DEFENSE" + | "COURTS_AND_PRETRIAL" + | "JAILS" + | "PRISONS" + | "SUPERVISION" + | "PAROLE" + | "PROBATION" + | "POST_RELEASE"; + +export interface UserAgency { + name: string; + id: number; + fips_county_code: string; + state_code: string; + system: AgencySystems; + systems: AgencySystems[]; +} + +export type ReportFrequency = "MONTHLY" | "ANNUAL"; + +export type ReportStatus = "NOT_STARTED" | "DRAFT" | "PUBLISHED"; + +export interface ReportOverview { + id: number; + agency_id: number; + month: number; + year: number; + frequency: ReportFrequency; + last_modified_at: string | null; + // TODO(#14138): Backend should only send timestamps + last_modified_at_timestamp: number | null; + editors: string[]; + status: ReportStatus; +} + +export interface Report extends ReportOverview { + metrics: Metric[]; +} + +export type MetricWithErrors = Metric & { + error?: string; + contexts: MetricContextWithErrors[]; + disaggregations: MetricDisaggregationsWithErrors[]; +}; + +export type MetricContextWithErrors = MetricContext & { + error?: string; +}; + +export type MetricDisaggregationsWithErrors = MetricDisaggregations & { + dimensions: MetricDisaggregationDimensionsWithErrors[]; +}; + +export type MetricDisaggregationDimensionsWithErrors = + MetricDisaggregationDimensions & { + error?: string; + }; + +export interface Metric { + key: string; + system: AgencySystems; + display_name: string; + description: string; + reporting_note: string; + value: string | number | boolean | null | undefined; + unit: string; + category: string; + label: string; + definitions: MetricDefinition[]; + contexts: MetricContext[]; + disaggregations: MetricDisaggregations[]; + enabled?: boolean; +} + +export interface MetricDefinition { + term: string; + definition: string; +} + +export interface MetricContext { + key: string; + display_name: string | null | undefined; + reporting_note: string | null | undefined; + required: boolean; + type: "TEXT" | "NUMBER" | "MULTIPLE_CHOICE"; + value: string | number | boolean | null | undefined; + multiple_choice_options: string[]; +} + +export interface MetricDisaggregations { + key: string; + display_name: string; + dimensions: MetricDisaggregationDimensions[]; + required: boolean; + helper_text: string | null | undefined; + enabled?: boolean; +} + +export interface MetricDisaggregationDimensions { + key: string; + label: string; + value: string | number | boolean | null | undefined; + reporting_note: string; + enabled?: boolean; +} + +export interface CreateReportFormValuesType extends Record { + month: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12; + year: number; + frequency: ReportFrequency; + annualStartMonth: number; + isRecurring: boolean; +} + +export interface FormError { + message: string; + info?: string; +} + +export interface FormContexts { + [contextKey: string]: { value?: string; error?: FormError }; +} + +export interface FormDimensions { + [dimensionKey: string]: { value?: string; error?: FormError }; +} + +export interface FormDisaggregations { + [disaggregationKey: string]: FormDimensions; +} + +export interface FormMetric { + value: string | number; + contexts: FormContexts; + disaggregations: FormDisaggregations; +} + +export interface FormReport { + [metricKey: string]: FormMetric; +} + +export interface FormStoreMetricValue { + [metricKey: string]: { value?: string; error?: FormError }; +} +export interface FormStoreMetricValues { + [reportID: string]: FormStoreMetricValue; +} + +export interface FormStoreContextValue { + [metricKey: string]: FormContexts; +} +export interface FormStoreContextValues { + [reportID: string]: FormStoreContextValue; +} + +export interface FormStoreDisaggregationValue { + [metricKey: string]: FormDisaggregations; +} +export interface FormStoreDisaggregationValues { + [reportID: string]: FormStoreDisaggregationValue; +} + +export interface UpdatedMetricsValues { + key: string; + value: Metric["value"]; + contexts: { key: string; value: MetricContext["value"] }[]; + disaggregations: { + key: string; + dimensions: { + key: string; + value: MetricDisaggregationDimensions["value"]; + }[]; + }[]; +} + +/** + * Reports data that comes in from the server. + * This closely resembles how report data is stored in our backend. + */ +export interface RawDatapoint { + id: number; + report_id: number | null; + start_date: string; + end_date: string; + metric_definition_key: string; + metric_display_name: string | null; + disaggregation_display_name: string | null; + dimension_display_name: string | null; + value: string; + is_published: boolean; + frequency: ReportFrequency; +} + +/** + * A Datapoint is an object representing a piece of justice counts metrics data for rendering in Recharts. + * Currently we only render Stacked Bar Charts. + * Each Datapoint represents a bar on the bar chart. + * Each Datapoint has: + * • a unique start_date and end_date, which serve as the x-axis category, + * • the frequency of the reporting data, either monthly or annual + * • "dataVizMissingData" which is used to render the missing data bar if there are no metrics for the time range represented + * • remaning keys which store the name of a piece of the stacked bar chart and its value. + * + * For example, raw datapoints that look like {start_date: "1/2020", disaggregation: "Gender", dimension: "Male", value: 5}, + * {start_date: "1/2020", disaggregation: "Gender", dimension: "Female", value: 3}, would be combined into + * {start_date: "1/2020", "Male": 5, "Female": 3} + * and keyed by "Gender". + */ +export interface Datapoint { + start_date: string; + end_date: string; + frequency: ReportFrequency; + // dataVizMissingData is used to render the missing data bar if there are no values reported for that time range + dataVizMissingData: number; + // the value here should really be number | null but Typescript doesn't allow for this easily + [dimensionOrAggregatedTotal: string]: string | number | null; +} + +export interface DatapointsGroupedByAggregateAndDisaggregations { + aggregate: Datapoint[]; + disaggregations: { + [disaggregation: string]: { + [start_date: string]: Datapoint; + }; + }; +} + +export interface DatapointsByMetric { + [metricKey: string]: DatapointsGroupedByAggregateAndDisaggregations; +} + +export type DataVizTimeRange = 0 | 6 | 12 | 60 | 120; + +export const DataVizTimeRangesMap: { [key: string]: DataVizTimeRange } = { + All: 0, + "6 Months Ago": 6, + "1 Year Ago": 12, + "5 Years Ago": 60, + "10 Years Ago": 120, +}; + +export type DatapointsViewSetting = "Count" | "Percentage"; + +export interface DimensionNamesByMetricAndDisaggregation { + [metric: string]: { + [disaggregation: string]: string[]; + }; +} + +export const DataVizAggregateName = "Total"; diff --git a/publisher/src/stores/API.test.tsx b/publisher/src/stores/API.test.tsx new file mode 100644 index 000000000..99f81f7bc --- /dev/null +++ b/publisher/src/stores/API.test.tsx @@ -0,0 +1,75 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= +import API from "./API"; + +const mockFetch = fetch as jest.Mock; +const MockAuthStore = jest.fn(() => { + return { + getToken: () => "token", + }; +}) as jest.Mock; + +afterEach(() => { + jest.resetAllMocks(); +}); + +describe("testing API calls", () => { + const api = new API(MockAuthStore()); + + test("error calling protected api", async () => { + mockFetch.mockRejectedValue(new Error("Failed to fetch")); + + await expect( + api.request({ + path: "/api/hello", + method: "GET", + }) + ).rejects.toThrow("Failed to fetch"); + expect(fetch).toBeCalledTimes(1); + }); + + test("successfully calling protected api", async () => { + mockFetch.mockResolvedValue({ + json: () => + Promise.resolve({ + message: "The API successfully validated your access token.", + }), + }); + + const response = (await api.request({ + path: "/api", + method: "GET", + })) as Response; + const data = await response.json(); + + expect(data.message).toBe( + "The API successfully validated your access token." + ); + expect(fetch).toBeCalledTimes(1); + + expect.hasAssertions(); + }); + + test("call to protected api has authorization header", async () => { + await expect(api.request({ path: "/api", method: "POST" })).rejects.toThrow( + Error + ); + expect(mockFetch.mock.calls[0][1].headers).toHaveProperty("Authorization"); + + expect.hasAssertions(); + }); +}); diff --git a/publisher/src/stores/API.ts b/publisher/src/stores/API.ts new file mode 100644 index 000000000..8f67b89d4 --- /dev/null +++ b/publisher/src/stores/API.ts @@ -0,0 +1,150 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { makeAutoObservable, runInAction, when } from "mobx"; + +import { trackLoadTime, trackNetworkError } from "../analytics"; +import { AuthStore } from "../components/Auth"; +import { showToast } from "../components/Toast"; + +export interface RequestProps { + path: string; + method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; + body?: FormData | Record; + retrying?: boolean; +} + +class API { + authStore: AuthStore; + + isSessionInitialized: boolean; + + csrfToken: string; + + constructor(authStore: AuthStore) { + makeAutoObservable(this); + + this.authStore = authStore; + this.isSessionInitialized = false; + this.csrfToken = ""; + + when( + () => authStore.isAuthorized, + () => this.initSession() + ); + } + + async initSession(): Promise { + try { + const response = (await this.request({ + path: "/api/init", + method: "GET", + })) as Response; + const { csrf } = await response.json(); + + runInAction(() => { + if (csrf !== "") this.csrfToken = csrf; + this.isSessionInitialized = true; + }); + } catch (error) { + if (error instanceof Error) return error.message; + return String(error); + } + } + + async request({ + path, + method, + body, + retrying = false, + }: RequestProps): Promise { + try { + const startTime = Date.now(); + if (!this.authStore.getToken) { + return Promise.reject(); + } + + const token = await this.authStore.getToken(); + + // Files are sent as FormData and not JSON + const jsonOrFormDataBody = + body instanceof FormData ? body : JSON.stringify(body); + + const headers: HeadersInit = { + Authorization: `Bearer ${token}`, + "X-CSRF-Token": this.csrfToken, + }; + + if (!(body instanceof FormData)) { + headers["Content-Type"] = "application/json"; + } + + const response = await fetch(path, { + body: method !== "GET" ? jsonOrFormDataBody : null, + method, + headers, + }); + + if (response.status >= 400) { + if (!retrying) { + const responseText = await response.clone().text(); + + if (responseText.includes("The CSRF token has expired.")) { + await this.initSession(); + return runInAction(() => + this.request({ path, method, body, retrying: true }) + ); + } + } + + const responseCopy = response.clone(); + const responseJson = await responseCopy.json(); + trackNetworkError( + path, + method, + response.status, + responseJson.description + ); + } else { + const loadTime = Date.now() - startTime; + trackLoadTime(path, method, loadTime); + } + + return response; + } catch (error) { + if (error instanceof Error) { + trackNetworkError(path, method, 0, error.message); + if (error.message.includes("Login required")) { + showToast( + "Your session has expired. Redirecting you to the login page...", + false, + "red" + ); + // Wait before reloading so user has a chance to see the toast + setTimeout(() => { + window.location.reload(); + }, 1000); + } + throw error; + } + trackNetworkError(path, method, 0, String(error)); + throw error; + } + } +} + +export default API; diff --git a/publisher/src/stores/DatapointsStore.ts b/publisher/src/stores/DatapointsStore.ts new file mode 100644 index 000000000..c1cd4f029 --- /dev/null +++ b/publisher/src/stores/DatapointsStore.ts @@ -0,0 +1,155 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { makeAutoObservable, runInAction } from "mobx"; + +import { + DatapointsByMetric, + DataVizAggregateName, + DimensionNamesByMetricAndDisaggregation, + RawDatapoint, +} from "../shared/types"; +import { isPositiveNumber } from "../utils"; +import API from "./API"; +import UserStore from "./UserStore"; + +class DatapointsStore { + userStore: UserStore; + + api: API; + + rawDatapoints: RawDatapoint[]; + + dimensionNamesByMetricAndDisaggregation: DimensionNamesByMetricAndDisaggregation; + + loading: boolean; + + constructor(userStore: UserStore, api: API) { + makeAutoObservable(this); + + this.api = api; + this.userStore = userStore; + this.rawDatapoints = []; + this.dimensionNamesByMetricAndDisaggregation = {}; + this.loading = true; + } + + /** + * Transforms raw data from the server into Datapoints keyed by metric, + * grouped by aggregate values and disaggregations. + * Aggregate is an array of objects each containing start_date, end_date, and the aggregate value. + * Disaggregations are keyed by disaggregation name and each value is an object + * with the key being the start_date and the value being an object + * containing start_date, end_date and key value pairs for each dimension and their values. + * See the DatapointsByMetric type for details. + */ + get datapointsByMetric(): DatapointsByMetric { + return this.rawDatapoints.reduce((res: DatapointsByMetric, dp) => { + if (!res[dp.metric_definition_key]) { + res[dp.metric_definition_key] = { + aggregate: [], + disaggregations: {}, + }; + } + + const sanitizedValue = + dp.value !== null && isPositiveNumber(dp.value) + ? Number(dp.value) + : null; + + if ( + dp.disaggregation_display_name === null || + dp.dimension_display_name === null + ) { + res[dp.metric_definition_key].aggregate.push({ + [DataVizAggregateName]: sanitizedValue, + start_date: dp.start_date, + end_date: dp.end_date, + frequency: dp.frequency, + dataVizMissingData: 0, + }); + } else { + if ( + !res[dp.metric_definition_key].disaggregations[ + dp.disaggregation_display_name + ] + ) { + res[dp.metric_definition_key].disaggregations[ + dp.disaggregation_display_name + ] = {}; + } + res[dp.metric_definition_key].disaggregations[ + dp.disaggregation_display_name + ][dp.start_date] = { + ...res[dp.metric_definition_key].disaggregations[ + dp.disaggregation_display_name + ][dp.start_date], + start_date: dp.start_date, + end_date: dp.end_date, + [dp.dimension_display_name]: sanitizedValue, + frequency: dp.frequency, + dataVizMissingData: 0, + }; + } + return res; + }, {}); + } + + async getDatapoints(): Promise { + try { + const { currentAgency } = this.userStore; + if (currentAgency === undefined) { + // If user is not attached to an agency, + // no need to bother trying to load this data. + runInAction(() => { + this.loading = false; + }); + return; + } + const response = (await this.api.request({ + path: `/api/agencies/${currentAgency.id}/datapoints`, + method: "GET", + })) as Response; + if (response.status === 200) { + const result = await response.json(); + runInAction(() => { + this.rawDatapoints = result.datapoints; + this.dimensionNamesByMetricAndDisaggregation = + result.dimension_names_by_metric_and_disaggregation; + }); + } else { + const error = await response.json(); + throw new Error(error.description); + } + } catch (error) { + runInAction(() => { + this.loading = false; + }); + if (error instanceof Error) return new Error(error.message); + } + } + + resetState() { + // reset the state + runInAction(() => { + this.rawDatapoints = []; + this.loading = true; + }); + } +} + +export default DatapointsStore; diff --git a/publisher/src/stores/FormStore.test.tsx b/publisher/src/stores/FormStore.test.tsx new file mode 100644 index 000000000..72e6543b8 --- /dev/null +++ b/publisher/src/stores/FormStore.test.tsx @@ -0,0 +1,153 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { runInAction } from "mobx"; + +import { rootStore } from "."; + +const { reportStore, formStore } = rootStore; + +beforeEach(() => { + runInAction(() => { + reportStore.reportOverviews = { + 0: { + id: 0, + agency_id: 0, + year: 2022, + month: 4, + frequency: "MONTHLY", + last_modified_at: "April 12 2022", + last_modified_at_timestamp: null, + editors: ["Editor #1", "Editor #2"], + status: "DRAFT", + }, + }; + + reportStore.reportMetrics = { + 0: [ + { + key: "PROSECUTION_STAFF", + system: "LAW_ENFORCEMENT", + display_name: "Staff", + description: + "Measures the number of full-time staff employed by the agency.", + reporting_note: "DOCs report only correctional institution staff.", + value: 1000, + unit: "people", + category: "CAPACITY_AND_COST", + label: "Total Staff", + definitions: [ + { + term: "full-time staff", + definition: "definition of full-time staff", + }, + ], + contexts: [ + { + key: "PROGRAMMATIC_OR_MEDICAL_STAFF", + display_name: "Does this include programmatic or medical staff?", + reporting_note: null, + required: false, + type: "MULTIPLE_CHOICE", + multiple_choice_options: ["YES", "NO"], + value: null, + }, + ], + disaggregations: [ + { + key: "PROSECUTION_STAFF_TYPE", + display_name: "Staff Types", + dimensions: [ + { + key: "SUPPORT", + label: "Support", + value: null, + reporting_note: "Staff: Support", + }, + ], + required: false, + helper_text: "Break down the metric by NIBRS offense types.", + }, + ], + }, + ], + }; + }); +}); + +test("metrics value handler updates the metric value", () => { + formStore.updateMetricsValues(0, "PROSECUTION_STAFF", "2000", true); + + expect(formStore.metricsValues[0].PROSECUTION_STAFF.value).toEqual("2000"); + + expect.hasAssertions(); +}); + +test("disaggregation dimension value handler updates the disaggregation dimension value", () => { + formStore.updateDisaggregationDimensionValue( + 0, + "PROSECUTION_STAFF", + "PROSECUTION_STAFF_TYPE", + "SUPPORT", + "200", + false, + true + ); + + expect( + formStore.disaggregations[0].PROSECUTION_STAFF.PROSECUTION_STAFF_TYPE + .SUPPORT.value + ).toEqual("200"); + + expect.hasAssertions(); +}); + +test("context value handler updates the context value", () => { + formStore.updateContextValue( + 0, + "PROSECUTION_STAFF", + "PROGRAMMATIC_OR_MEDICAL_STAFF", + "100", + false, + "NUMBER", + true + ); + + expect( + formStore.contexts[0].PROSECUTION_STAFF.PROGRAMMATIC_OR_MEDICAL_STAFF.value + ).toEqual("100"); + + expect.hasAssertions(); +}); + +test("updatedReportValues maps all updated (and not updated) input values into required data structure", () => { + expect(JSON.stringify(formStore.reportUpdatedValuesForBackend(0))).toEqual( + JSON.stringify([ + { + key: "PROSECUTION_STAFF", + value: 2000, + contexts: [{ key: "PROGRAMMATIC_OR_MEDICAL_STAFF", value: 100 }], + disaggregations: [ + { + key: "PROSECUTION_STAFF_TYPE", + dimensions: [{ key: "SUPPORT", value: 200 }], + }, + ], + }, + ]) + ); +}); diff --git a/publisher/src/stores/FormStore.ts b/publisher/src/stores/FormStore.ts new file mode 100644 index 000000000..8a4303c95 --- /dev/null +++ b/publisher/src/stores/FormStore.ts @@ -0,0 +1,558 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { makeAutoObservable } from "mobx"; + +import { + FormError, + FormStoreContextValues, + FormStoreDisaggregationValues, + FormStoreMetricValues, + Metric, + UpdatedMetricsValues, +} from "../shared/types"; +import { + isPositiveNumber, + normalizeToString, + removeCommaSpaceAndTrim, + sanitizeInputValue, +} from "../utils"; +import ReportStore from "./ReportStore"; + +class FormStore { + reportStore: ReportStore; + + metricsValues: FormStoreMetricValues; + + contexts: FormStoreContextValues; + + disaggregations: FormStoreDisaggregationValues; + + constructor(reportStore: ReportStore) { + makeAutoObservable(this); + + this.reportStore = reportStore; + this.metricsValues = {}; + this.contexts = {}; + this.disaggregations = {}; + } + + validatePreviouslySavedInputs(reportID: number) { + /** Runs validation of previously saved inputs on load */ + this.reportStore.reportMetrics[reportID].forEach((metric) => { + if (metric.value !== null && metric.value !== undefined) { + this.updateMetricsValues( + reportID, + metric.key, + normalizeToString(metric.value), + metric.enabled + ); + } + + metric.disaggregations.forEach((disaggregation) => { + disaggregation.dimensions.forEach((dimension) => { + if (dimension.value !== null && dimension.value !== undefined) { + this.updateDisaggregationDimensionValue( + reportID, + metric.key, + disaggregation.key, + dimension.key, + normalizeToString(dimension.value), + disaggregation.required, + metric.enabled + ); + } + }); + }); + + metric.contexts.forEach((context) => { + if (context.value !== null && context.value !== undefined) { + this.updateContextValue( + reportID, + metric.key, + context.key, + normalizeToString(context.value), + context.required, + context.type, + metric.enabled + ); + } + }); + }); + } + + isMetricEmpty(reportID: number, metricKey: string) { + let isEmpty = true; + const metricToCheck = this.reportStore.reportMetrics[reportID].find( + (metric) => metric.key === metricKey + ); + + if (this.metricsValues[reportID]?.[metricKey]?.value) { + return false; + } + + metricToCheck?.contexts.forEach((context) => { + if (this.contexts[reportID]?.[metricKey]?.[context.key]?.value) { + isEmpty = false; + } + }); + + metricToCheck?.disaggregations.forEach((disaggregation) => { + disaggregation.dimensions.forEach((dimension) => { + if ( + this.disaggregations[reportID]?.[metricKey]?.[disaggregation.key]?.[ + dimension.key + ]?.value + ) { + isEmpty = false; + } + }); + }); + + return isEmpty; + } + + validateAndGetAllMetricFormValues(reportID: number): { + metrics: Metric[]; + isPublishable: boolean; + } { + let isPublishable = true; + let errorFound = false; + let allMetricsAreEmpty = true; + + const updatedMetrics = this.reportStore.reportMetrics[reportID]?.map( + (metric) => { + const metricValues = this.metricsValues[reportID]?.[metric.key]; + const contexts = this.contexts[reportID]?.[metric.key]; + const disaggregationForMetric = + this.disaggregations[reportID]?.[metric.key]; + const metricIsEmpty = this.isMetricEmpty(reportID, metric.key); + + if (metricIsEmpty) { + return metric; + } + + allMetricsAreEmpty = false; + + /** Touch & validate metric field */ + if (metricValues?.value !== "") { + this.updateMetricsValues( + reportID, + metric.key, + normalizeToString(metricValues?.value) || + normalizeToString(metric.value), + metric.enabled + ); + } + + const metricError = this.metricsValues[reportID]?.[metric.key]?.error; + + if (metricError) { + errorFound = true; + } + + return { + ...metric, + value: sanitizeInputValue(metricValues?.value, metric.value), + error: metricError, + contexts: metric.contexts.map((context) => { + /** Touch & validate context field */ + if (metricValues?.value !== "") { + this.updateContextValue( + reportID, + metric.key, + context.key, + normalizeToString(contexts?.[context.key]?.value) || + normalizeToString(context.value), + context.required, + context.type, + metric.enabled + ); + } + + const contextError = + this.contexts[reportID]?.[metric.key]?.[context.key]?.error; + + if (contextError) { + errorFound = true; + } + + return { + ...context, + value: sanitizeInputValue( + contexts?.[context.key]?.value, + context.value, + context.type + ), + error: contextError, + }; + }), + disaggregations: metric.disaggregations.map((disaggregation) => { + return { + ...disaggregation, + dimensions: disaggregation.dimensions?.map((dimension) => { + const disaggregationError = + this.disaggregations[reportID]?.[metric.key]?.[ + disaggregation.key + ]?.[dimension.key]?.error; + + if (disaggregationError) { + errorFound = true; + } + + return { + ...dimension, + value: sanitizeInputValue( + disaggregationForMetric?.[disaggregation.key]?.[ + dimension.key + ]?.value, + dimension.value + ), + error: disaggregationError, + }; + }), + }; + }), + }; + } + ); + + if (errorFound || allMetricsAreEmpty) { + isPublishable = false; + } + + return { metrics: updatedMetrics || [], isPublishable }; + } + + /** + * Maps updated values into data structure required by the backend. + * Backend requires a combination of updated values on updated fields, + * and default values (the ones retrieved from the backend on load) for + * fields that have not been updated. + * + * @returns updated array of metrics (in the required data structure) + */ + + reportUpdatedValuesForBackend( + reportID: number, + metricKey?: string + ): UpdatedMetricsValues[] { + const allMetrics = this.reportStore.reportMetrics[reportID]; + // If `metricKey` is not undefined, only update the corresponding metric. + // Else, update all metrics. + const metricsToUpdate = + metricKey !== undefined + ? this.reportStore.reportMetrics[reportID].filter( + (metric) => metric.key === metricKey + ) + : allMetrics; + const updatedMetricValues = metricsToUpdate?.map((metric) => { + /** Note: all empty inputs will be represented by null */ + const metricValue = sanitizeInputValue( + this.metricsValues[reportID]?.[metric.key]?.value, + metric.value + ); + + const combinedMetricValues: UpdatedMetricsValues = { + key: metric.key, + value: metricValue, + contexts: [], + disaggregations: [], + }; + + metric.contexts.forEach((context) => { + const contextValue = sanitizeInputValue( + this.contexts[reportID]?.[metric.key]?.[context.key]?.value, + context.value, + context.type + ); + + combinedMetricValues.contexts.push({ + key: context.key, + value: contextValue, + }); + }); + + metric.disaggregations.forEach((disaggregation) => { + combinedMetricValues.disaggregations.push({ + key: disaggregation.key, + dimensions: disaggregation.dimensions.map((dimension) => { + const dimensionValue = sanitizeInputValue( + this.disaggregations[reportID]?.[metric.key]?.[ + disaggregation.key + ]?.[dimension.key]?.value, + dimension.value + ); + + return { + key: dimension.key, + value: dimensionValue, + }; + }), + }); + }); + + return combinedMetricValues; + }); + + return updatedMetricValues || []; + } + + validate = ( + validationType: string, + value: string, + required: boolean, + reportID: number, + metricKey: string, + key1?: string, + key2?: string + ) => { + const cleanValue = removeCommaSpaceAndTrim(value); + const isRequiredButEmpty = required && cleanValue === ""; + const metricIsEmpty = this.isMetricEmpty(reportID, metricKey); + + const updateFieldErrorMessage = ( + operation: "ADD" | "DELETE" | "ADD TO METRIC", + error?: FormError + ) => { + /** + * Overall metric: !key1 && !key2 + * Context: key1 && !key2 + * Disaggregation Dimension: key1 && key2 + */ + if (operation === "ADD") { + if (key1 && key2) { + this.disaggregations[reportID][metricKey][key1][key2].error = error; + } else if (key1 && !key2) { + this.contexts[reportID][metricKey][key1].error = error; + } else { + this.metricsValues[reportID][metricKey].error = error; + } + } + if (operation === "ADD TO METRIC") { + this.metricsValues[reportID][metricKey].error = error; + } + if (operation === "DELETE") { + if (key1 && key2) { + delete this.disaggregations[reportID][metricKey][key1][key2].error; + } else if (key1 && !key2) { + delete this.contexts[reportID][metricKey][key1].error; + } else { + delete this.metricsValues[reportID][metricKey].error; + } + } + }; + + if (metricIsEmpty) { + if (this.metricsValues?.[reportID]?.[metricKey]?.error) + delete this.metricsValues[reportID][metricKey].error; + + if (this.contexts?.[reportID]?.[metricKey]) + Object.keys(this.contexts[reportID][metricKey]).forEach( + (contextKey) => { + delete this.contexts[reportID][metricKey][contextKey].error; + } + ); + + updateFieldErrorMessage("DELETE"); + return; + } + + if (key1 && !this.metricsValues?.[reportID]?.[metricKey]?.value) { + if (!this.metricsValues[reportID]) { + this.metricsValues[reportID] = {}; + } + if (!this.metricsValues[reportID][metricKey]) { + this.metricsValues[reportID][metricKey] = {}; + } + updateFieldErrorMessage("ADD TO METRIC", { + message: "You are also required to enter a value for this field.", + info: "Because you have entered data for this metric, you are also required to fill out this value. If you do not have this data, please leave all fields in this metric (including disaggregations and contexts) blank.", + }); + } + + /** Raise Error */ + if (isRequiredButEmpty) { + updateFieldErrorMessage("ADD", { + message: "You are also required to enter a value for this field.", + info: "Because you have entered data for this metric, you are also required to fill out this value. If you do not have this data, please leave all fields in this metric (including disaggregations and contexts) blank.", + }); + return; + } + + if (!required && cleanValue === "") { + /** Remove Error */ + updateFieldErrorMessage("DELETE"); + return; + } + + if (validationType === "NUMBER") { + /** Raise Error */ + if (!isPositiveNumber(cleanValue)) { + updateFieldErrorMessage("ADD", { + message: "Please enter a valid number.", + }); + return; + } + } + + /** Remove Error */ + updateFieldErrorMessage("DELETE"); + }; + + updateMetricsValues = ( + reportID: number, + metricKey: string, + updatedValue: string, + metricEnabled: boolean | undefined + ): void => { + /** + * Create an empty object within the property if none exist to improve access + * speed and to help with isolating re-renders for each form component. + */ + if (!this.metricsValues[reportID]) { + this.metricsValues[reportID] = {}; + } + if (!this.metricsValues[reportID][metricKey]) { + this.metricsValues[reportID][metricKey] = {}; + } + + this.metricsValues[reportID][metricKey].value = updatedValue; + if (metricEnabled) { + this.validate("NUMBER", updatedValue, true, reportID, metricKey); + } + }; + + updateDisaggregationDimensionValue = ( + reportID: number, + metricKey: string, + disaggregationKey: string, + dimensionKey: string, + updatedValue: string, + required: boolean, + metricEnabled: boolean | undefined + ): void => { + /** + * Create empty objects within the properties if none exist to improve access + * speed and to help with isolating re-renders for each form component. + */ + if (!this.disaggregations[reportID]) { + this.disaggregations[reportID] = {}; + } + + if (!this.disaggregations[reportID][metricKey]) { + this.disaggregations[reportID][metricKey] = {}; + } + + if (!this.disaggregations[reportID][metricKey][disaggregationKey]) { + this.disaggregations[reportID][metricKey][disaggregationKey] = {}; + } + + if ( + !this.disaggregations[reportID][metricKey][disaggregationKey][ + dimensionKey + ] + ) { + this.disaggregations[reportID][metricKey][disaggregationKey][ + dimensionKey + ] = {}; + } + + this.disaggregations[reportID][metricKey][disaggregationKey][ + dimensionKey + ].value = updatedValue; + + if (metricEnabled) { + this.validate( + "NUMBER", + updatedValue, + required, + reportID, + metricKey, + disaggregationKey, + dimensionKey + ); + } + }; + + updateContextValue = ( + reportID: number, + metricKey: string, + contextKey: string, + updatedValue: string, + required: boolean, + contextType: string, + metricEnabled: boolean | undefined + ): void => { + /** + * Create an empty object within the property if none exist to improve access + * speed and to help with isolating re-renders for each form component. + */ + if (!this.contexts[reportID]) { + this.contexts[reportID] = {}; + } + + if (!this.contexts[reportID][metricKey]) { + this.contexts[reportID][metricKey] = {}; + } + + if (!this.contexts[reportID][metricKey][contextKey]) { + this.contexts[reportID][metricKey][contextKey] = {}; + } + + this.contexts[reportID][metricKey][contextKey].value = updatedValue; + + if (metricEnabled) { + this.validate( + contextType, + updatedValue, + required, + reportID, + metricKey, + contextKey + ); + } + }; + + resetBinaryInput = ( + reportID: number, + metricKey: string, + contextKey: string, + required: boolean + ): void => { + /** + * Create an empty object within the property if none exist to improve access + * speed and to help with isolating re-renders for each form component. + */ + if (!this.contexts[reportID]) { + this.contexts[reportID] = {}; + } + + if (!this.contexts[reportID][metricKey]) { + this.contexts[reportID][metricKey] = {}; + } + + if (!this.contexts[reportID][metricKey][contextKey]) { + this.contexts[reportID][metricKey][contextKey] = {}; + } + + this.contexts[reportID][metricKey][contextKey].value = ""; + this.validate("TEXT", "", required, reportID, metricKey, contextKey); + }; +} + +export default FormStore; diff --git a/publisher/src/stores/ReportStore.test.tsx b/publisher/src/stores/ReportStore.test.tsx new file mode 100644 index 000000000..07212a837 --- /dev/null +++ b/publisher/src/stores/ReportStore.test.tsx @@ -0,0 +1,107 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { render, screen } from "@testing-library/react"; +import { runInAction } from "mobx"; +import React from "react"; + +import mockJSON from "../mocks/reportOverviews.json"; +import Reports from "../pages/Reports"; +import { ReportOverview } from "../shared/types"; +import { rootStore, StoreProvider } from "."; + +const mockUnorderedReportsMap: { [reportID: string]: ReportOverview } = {}; +(mockJSON.unorderedReports as ReportOverview[]).forEach((report) => { + mockUnorderedReportsMap[report.id] = report; +}); + +const mockedUseNavigate = jest.fn(); +const mockedUseLocation = jest.fn(); +jest.mock("react-router-dom", () => ({ + ...jest.requireActual("react-router-dom"), + useNavigate: () => mockedUseNavigate, + useLocation: () => mockedUseLocation, +})); + +beforeEach(() => { + rootStore.reportStore.reportOverviews = {}; + rootStore.reportStore.getReportOverviews = () => Promise.resolve(); +}); + +test("sort in reportOverviewList", () => { + runInAction(() => { + rootStore.reportStore.reportOverviews = mockUnorderedReportsMap; + }); + + expect(JSON.stringify(rootStore.reportStore.reportOverviewList)).toEqual( + JSON.stringify(mockJSON.orderedReports) + ); +}); + +test("loading reports", async () => { + render( + + + + ); + + const loader = screen.getByTestId("loading"); + expect(loader).toBeInTheDocument(); + + expect.hasAssertions(); +}); + +test("no reports to display", async () => { + render( + + + + ); + + runInAction(() => { + rootStore.userStore.userInfoLoaded = true; + rootStore.reportStore.loadingOverview = false; + rootStore.reportStore.reportOverviews = {}; + }); + + const noReportsLoaded = await screen.findByText(/No reports to display./i); + expect(noReportsLoaded).toBeInTheDocument(); + expect.hasAssertions(); +}); + +test("displayed reports", async () => { + render( + + + + ); + + runInAction(() => { + rootStore.reportStore.loadingOverview = false; + rootStore.reportStore.reportOverviews = mockUnorderedReportsMap; + }); + + // Arbitrary report dates included in mockJSON + const april2022 = await screen.findByText(/April 2022/i); + const december2020 = await screen.findByText(/December 2020/i); + const annualReport2019 = await screen.findByText(/Annual Report 2019/i); + expect(april2022).toBeInTheDocument(); + expect(december2020).toBeInTheDocument(); + expect(annualReport2019).toBeInTheDocument(); + + expect.hasAssertions(); +}); diff --git a/publisher/src/stores/ReportStore.ts b/publisher/src/stores/ReportStore.ts new file mode 100644 index 000000000..3ae812d70 --- /dev/null +++ b/publisher/src/stores/ReportStore.ts @@ -0,0 +1,377 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { makeAutoObservable, runInAction } from "mobx"; + +import { UploadedFileStatus } from "../components/DataUpload"; +import { MetricSettings } from "../components/MetricsView"; +import { + Metric, + Report, + ReportOverview, + ReportStatus, + UpdatedMetricsValues, +} from "../shared/types"; +import { groupBy } from "../utils/helperUtils"; +import API from "./API"; +import UserStore from "./UserStore"; + +class ReportStore { + userStore: UserStore; + + api: API; + + reportOverviews: { [reportID: string]: ReportOverview }; // key by report ID + + reportMetrics: { [reportID: string]: Metric[] }; // key by report ID + + reportMetricsBySystem: { [reportID: string]: { [system: string]: Metric[] } }; // key by report ID, then by system + + loadingOverview: boolean; + + constructor(userStore: UserStore, api: API) { + makeAutoObservable(this); + + this.api = api; + this.userStore = userStore; + this.reportOverviews = {}; + this.reportMetrics = {}; + this.reportMetricsBySystem = {}; + this.loadingOverview = true; + } + + get reportOverviewList(): ReportOverview[] { + return Object.values(this.reportOverviews).sort((a, b) => { + const dateA = new Date(a.year, a.month - 1).getTime(); + const dateB = new Date(b.year, b.month - 1).getTime(); + if (a.year === b.year) { + // Annual reports should always be sorted before Monthly reports, + // regardless of their month + if (a.frequency === "ANNUAL") { + return -1; + } + if (b.frequency === "ANNUAL") { + return 1; + } + } + return dateB - dateA; + }); + } + + async getReportOverviews(): Promise { + try { + const { currentAgency } = this.userStore; + if (currentAgency === undefined) { + // If user is not attached to an agency, + // no need to bother trying to load reports. + runInAction(() => { + this.loadingOverview = false; + }); + } + if (currentAgency !== undefined) { + const response = (await this.api.request({ + path: `/api/agencies/${currentAgency.id}/reports`, + method: "GET", + })) as Response; + if (response.status === 200) { + const allReports = await response.json(); + + runInAction(() => { + allReports.forEach((report: ReportOverview) => { + this.reportOverviews[report.id] = report; + }); + this.loadingOverview = false; + }); + } else { + const error = await response.json(); + throw new Error(error.description); + } + } + } catch (error) { + runInAction(() => { + this.loadingOverview = false; + }); + if (error instanceof Error) return new Error(error.message); + } + } + + async getReport(reportID: number): Promise { + try { + const response = (await this.api.request({ + path: `/api/reports/${reportID}`, + method: "GET", + })) as Response; + + if (response.status !== 200) { + throw new Error("There was an issue getting this report."); + } + + const report = (await response.json()) as Report; + const { metrics, ...overview } = report; + + runInAction(() => { + this.reportOverviews[reportID] = overview; + const metricsBySystem = groupBy(metrics, (metric) => metric.system); + this.reportMetricsBySystem[reportID] = metricsBySystem; + // ensure that the order of the metrics in reportMetricsBySystem + // matches the order of the metrics in reportMetrics + this.reportMetrics[reportID] = Object.values(metricsBySystem).flat(); + }); + } catch (error) { + if (error instanceof Error) return new Error(error.message); + } + } + + async createReport( + body: Record + ): Promise { + try { + const { currentAgency } = this.userStore; + + if (currentAgency === undefined) { + throw new Error( + "Either invalid user/agency information or no user or agency information initialized." + ); + } + + const response = (await this.api.request({ + path: "/api/reports", + method: "POST", + body: { agency_id: currentAgency.id, ...body }, + })) as Response; + + return response; + } catch (error) { + if (error instanceof Error) return new Error(error.message); + } + } + + async updateReport( + reportID: number, + updatedMetrics: UpdatedMetricsValues[], + status: ReportStatus + ): Promise { + try { + const response = (await this.api.request({ + path: `/api/reports/${reportID}`, + body: { + status, + time_loaded: + this.reportOverviews[reportID].last_modified_at_timestamp, + metrics: updatedMetrics, + }, + method: "PATCH", + })) as Response; + + if (response.status === 200) { + /** Update the editor details (editors & last modified details) in real time within the report after autosave. */ + const report = (await response.json()) as Report; + this.reportOverviews[report.id] = report; + } + + return response; + } catch (error) { + if (error instanceof Error) return new Error(error.message); + } + } + + async deleteReports( + reportIDs: number[] + ): Promise { + try { + const response = (await this.api.request({ + path: `/api/reports`, + body: { report_ids: reportIDs }, + method: "DELETE", + })) as Response; + + if (response.status !== 200) { + throw new Error("There was an issue deleting these reports."); + } + + runInAction(() => { + this.resetState(); + this.getReportOverviews(); + }); + + return response; + } catch (error) { + if (error instanceof Error) return new Error(error.message); + } + } + + async getReportSettings(): Promise { + try { + const { currentAgency } = this.userStore; + + if (currentAgency === undefined) { + throw new Error( + "Either invalid user/agency information or no user or agency information initialized." + ); + } + + const response = (await this.api.request({ + path: `/api/agencies/${currentAgency.id}/metrics`, + method: "GET", + })) as Response; + + if (response.status !== 200) { + throw new Error("There was an issue retrieving the report settings."); + } + + return response; + } catch (error) { + if (error instanceof Error) return new Error(error.message); + } + } + + async updateReportSettings( + updatedMetricSettings: MetricSettings[] + ): Promise { + try { + const { currentAgency } = this.userStore; + + if (currentAgency === undefined) { + throw new Error( + "Either invalid user/agency information or no user or agency information initialized." + ); + } + + const response = (await this.api.request({ + path: `/api/agencies/${currentAgency.id}/metrics`, + body: { metrics: updatedMetricSettings }, + method: "PUT", + })) as Response; + + if (response.status !== 200) { + throw new Error("There was an issue updating the report settings."); + } + + return response; + } catch (error) { + if (error instanceof Error) return new Error(error.message); + } + } + + async getUploadedFilesList(): Promise { + const { currentAgency } = this.userStore; + + if (currentAgency === undefined) { + return new Error( + "Either invalid user/agency information or no user or agency information initialized." + ); + } + + const response = (await this.api.request({ + path: `/api/agencies/${currentAgency.id}/spreadsheets`, + method: "GET", + })) as Response; + + if (response.status !== 200) { + return new Error("There was an issue retrieving the list of files."); + } + + return response; + } + + async fetchSpreadsheetBlob( + spreadsheetID: number + ): Promise { + try { + const response = (await this.api.request({ + path: `/api/spreadsheets/${spreadsheetID}`, + method: "GET", + })) as Response; + + if (response.status !== 200) { + throw new Error("There was an issue downloading the spreadsheet."); + } + + return response; + } catch (error) { + if (error instanceof Error) return new Error(error.message); + } + } + + async uploadExcelSpreadsheet( + formData: FormData + ): Promise { + try { + const response = (await this.api.request({ + path: `/api/spreadsheets`, + body: formData, + method: "POST", + })) as Response; + + if (response.status !== 200) { + throw new Error("There was an issue uploading the file."); + } + + return response; + } catch (error) { + if (error instanceof Error) return new Error(error.message); + } + } + + async deleteUploadedSpreadsheet( + spreadsheetID: number + ): Promise { + const response = (await this.api.request({ + path: `/api/spreadsheets/${spreadsheetID}`, + method: "DELETE", + })) as Response; + + if (response.status !== 200) { + return new Error("There was an issue deleting the file."); + } + + return response; + } + + async updateFileStatus( + spreadsheetID: number, + status: UploadedFileStatus + ): Promise { + try { + const response = (await this.api.request({ + path: `/api/spreadsheets/${spreadsheetID}`, + body: { status }, + method: "PATCH", + })) as Response; + + if (response.status !== 200) { + throw new Error("There was an issue updating the file status."); + } + + return response; + } catch (error) { + if (error instanceof Error) return new Error(error.message); + } + } + + resetState() { + // reset the state when switching agencies + runInAction(() => { + this.reportOverviews = {}; + this.reportMetrics = {}; + this.reportMetricsBySystem = {}; + this.loadingOverview = true; + }); + } +} + +export default ReportStore; diff --git a/publisher/src/stores/RootStore.ts b/publisher/src/stores/RootStore.ts new file mode 100644 index 000000000..c9575fd8d --- /dev/null +++ b/publisher/src/stores/RootStore.ts @@ -0,0 +1,66 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= +import { Auth0ClientOptions } from "@auth0/auth0-spa-js"; + +import { AuthStore } from "../components/Auth"; +import API from "./API"; +import DatapointsStore from "./DatapointsStore"; +import FormStore from "./FormStore"; +import ReportStore from "./ReportStore"; +import UserStore from "./UserStore"; + +const getAuthSettings = (): Auth0ClientOptions | undefined => { + if (window.APP_CONFIG) { + return { + domain: window.APP_CONFIG.domain, + client_id: window.APP_CONFIG.clientId, + redirect_uri: window.location.origin, + audience: window.APP_CONFIG.audience, + useRefreshTokens: true, + }; + } + return undefined; +}; + +class RootStore { + authStore: AuthStore; + + api: API; + + userStore: UserStore; + + reportStore: ReportStore; + + formStore: FormStore; + + datapointsStore: DatapointsStore; + + constructor() { + this.authStore = new AuthStore({ + authSettings: getAuthSettings(), + }); + this.api = new API(this.authStore); + this.userStore = new UserStore(this.authStore, this.api); + this.reportStore = new ReportStore(this.userStore, this.api); + this.formStore = new FormStore(this.reportStore); + this.datapointsStore = new DatapointsStore(this.userStore, this.api); + } +} + +export default new RootStore(); + +export type { RootStore }; diff --git a/publisher/src/stores/StoreProvider.tsx b/publisher/src/stores/StoreProvider.tsx new file mode 100644 index 000000000..d6bd63cec --- /dev/null +++ b/publisher/src/stores/StoreProvider.tsx @@ -0,0 +1,48 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import React, { useContext } from "react"; + +import NoAuthConfigErrorPage from "../components/Error/NoAuthConfigErrorPage"; +import rootStore from "./RootStore"; + +const StoreContext = React.createContext( + undefined +); + +export const StoreProvider: React.FC = ({ + children, +}): React.ReactElement => { + if (window.APP_CONFIG) { + return ( + + {children} + + ); + } + return ; +}; + +export function useStore(): typeof rootStore { + const context = useContext(StoreContext); + + if (context === undefined) { + throw new Error("useStore must be used within a StoreProvider"); + } + + return context; +} diff --git a/publisher/src/stores/UserStore.ts b/publisher/src/stores/UserStore.ts new file mode 100644 index 000000000..06c1cdb27 --- /dev/null +++ b/publisher/src/stores/UserStore.ts @@ -0,0 +1,235 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= +import { makeAutoObservable, runInAction, when } from "mobx"; +import { makePersistable } from "mobx-persist-store"; + +import { APP_METADATA_CLAIM, AuthStore } from "../components/Auth"; +import { showToast } from "../components/Toast"; +import { UserAgency } from "../shared/types"; +import API from "./API"; + +type UserSettingsRequestBody = { + name: string | null; + email: string | null; +}; +class UserStore { + authStore: AuthStore; + + api: API; + + auth0UserID: string | undefined; + + userAgencies: UserAgency[] | undefined; + + userInfoLoaded: boolean; + + onboardingTopicsCompleted: { [topic: string]: boolean } | undefined; + + permissions: string[]; + + currentAgencyId: number | undefined; + + constructor(authStore: AuthStore, api: API) { + makeAutoObservable(this); + makePersistable(this, { + name: "UserStore", + properties: ["currentAgencyId"], + storage: window.localStorage, + }); + + this.authStore = authStore; + this.api = api; + this.auth0UserID = this.authStore.user?.id; + this.userAgencies = undefined; + this.userInfoLoaded = false; + this.onboardingTopicsCompleted = undefined; + this.permissions = []; + this.currentAgencyId = undefined; + + when( + () => api.isSessionInitialized, + () => this.updateAndRetrieveUserPermissionsAndAgencies() + ); + } + + async updateUserNameAndEmail( + name: string, + email: string + ): Promise { + try { + const body: UserSettingsRequestBody = { name: null, email: null }; + const isNameUpdated = name !== this.authStore.user?.name; + const isEmailUpdated = email !== this.authStore.user?.email; + if (isNameUpdated) { + body.name = name; + } + if (isEmailUpdated) { + body.email = email; + } + const response = await this.api.request({ + path: "/api/users", + method: "PATCH", + body, + }); + runInAction(() => { + this.authStore.user = { ...this.authStore.user, name, email }; + }); + + if (response && response instanceof Response) { + if (response.status === 200 && isNameUpdated && !isEmailUpdated) { + showToast(`Name was successfully updated to ${name}.`, true); + return; + } + if (response.status === 200 && isNameUpdated && isEmailUpdated) { + showToast( + `Name and email were successfully updated. You will be logged out. Please check your email at ${email} to verify your new email before logging in again.`, + /* check */ true, + /* color */ undefined, + /* timeout */ 4500 + ); + return; + } + if (response.status === 200 && !isNameUpdated && isEmailUpdated) { + showToast( + `Email was successfully updated. You will be logged out. Please check your email at ${email} to verify your new email before logging in again.`, + /* check */ true, + /* color */ undefined, + /* timeout */ 4500 + ); + return; + } + if (response.status !== 200) { + showToast("Failed to update user details.", false, "red"); + return; + } + } + } catch (error) { + let errorMessage = ""; + if (error instanceof Error) { + errorMessage = error.message; + } else { + errorMessage = String(error); + } + + showToast(`Failed to update user details. ${errorMessage}`, false, "red"); + return errorMessage; + } + } + + getInitialAgencyId(): number | undefined { + // this.currentAgencyId is persisted in the user's localStorage. + // First, try to retrieve the persisted value + if (this.currentAgencyId !== undefined) { + const currentAgency = this.userAgencies?.find( + (agency) => agency.id === this.currentAgencyId + ); + // if the agency exists, set current agency to the persisted value + if (currentAgency) { + return this.currentAgencyId; + } + } + // if the agency does not exist, or there is no persisted currentAgencyId value, + // just set the current agency id to the first agency in the array of user agencies + if (this.userAgencies && this.userAgencies.length > 0) { + // attempting to access 0 index in the empty array leads to the mobx warning "[mobx] Out of bounds read: 0" + // so check the length of the array before accessing + return this.userAgencies[0].id; + } + return undefined; + } + + get name(): string | undefined { + return this.authStore.user?.name; + } + + get email(): string | undefined { + return this.authStore.user?.email; + } + + get nameOrEmail(): string | undefined { + return this.name || this.email; + } + + get currentAgency(): UserAgency | undefined { + return this.userAgencies?.find( + (agency) => agency.id === this.currentAgencyId + ); + } + + setCurrentAgencyId(agencyId: number | undefined) { + runInAction(() => { + this.currentAgencyId = agencyId; + }); + } + + async updateAndRetrieveUserPermissionsAndAgencies() { + try { + const response = (await this.api.request({ + path: "/api/users", + method: "PUT", + body: { + name: this.name, + }, + })) as Response; + const { agencies: userAgencies, permissions } = await response.json(); + runInAction(() => { + this.userAgencies = userAgencies; + this.permissions = permissions; + this.currentAgencyId = this.getInitialAgencyId(); + this.userInfoLoaded = true; + this.onboardingTopicsCompleted = this.authStore.user?.[ + APP_METADATA_CLAIM + ]?.onboarding_topics_completed || { + reportsview: false, + dataentryview: false, + }; + }); + } catch (error) { + if (error instanceof Error) return error.message; + return String(error); + } + } + + async updateOnboardingStatus(topic: string, status: boolean) { + try { + const response = (await this.api.request({ + path: "/api/users", + method: "PUT", + body: { + onboarding_topics_completed: { + ...this.onboardingTopicsCompleted, + [topic]: status, + }, + }, + })) as Response; + + runInAction(() => { + this.onboardingTopicsCompleted = { + ...this.onboardingTopicsCompleted, + [topic]: status, + }; + }); + + return response; + } catch (error) { + if (error instanceof Error) return error.message; + return String(error); + } + } +} + +export default UserStore; diff --git a/publisher/src/stores/index.ts b/publisher/src/stores/index.ts new file mode 100644 index 000000000..9786834b2 --- /dev/null +++ b/publisher/src/stores/index.ts @@ -0,0 +1,22 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./API"; +export * from "./ReportStore"; +export { default as rootStore } from "./RootStore"; +export * from "./StoreProvider"; +export * from "./UserStore"; diff --git a/publisher/src/utils/conversionUtils.ts b/publisher/src/utils/conversionUtils.ts new file mode 100644 index 000000000..73ec81d43 --- /dev/null +++ b/publisher/src/utils/conversionUtils.ts @@ -0,0 +1,29 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +/** + * Converts pixel to rem based on a root `font-size` of 16px. + * + * @param px - pixel value as "24px" + * @param root (optional) - change conversion from a default root `font-size` of 16px + * @returns rem value as string + */ + +export const rem = (px: string, root?: number) => { + const pxAsNumber = Number(px.replace("px", "")); + return `${pxAsNumber / (root || 16)}rem`; +}; diff --git a/publisher/src/utils/dateUtils.test.ts b/publisher/src/utils/dateUtils.test.ts new file mode 100644 index 000000000..f5b962be8 --- /dev/null +++ b/publisher/src/utils/dateUtils.test.ts @@ -0,0 +1,134 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { + printDateRangeFromMonthYear, + printElapsedDaysMonthsYearsSinceDate, +} from "./dateUtils"; + +describe("printDateRangeFromMonthYear", () => { + test("monthly", () => { + const result1 = printDateRangeFromMonthYear(1, 2022); + const result2 = printDateRangeFromMonthYear(2, 2022); + const result3 = printDateRangeFromMonthYear(3, 2022); + const result4 = printDateRangeFromMonthYear(4, 2022); + const result5 = printDateRangeFromMonthYear(5, 2022); + const result6 = printDateRangeFromMonthYear(6, 2022); + const result7 = printDateRangeFromMonthYear(7, 2022); + const result8 = printDateRangeFromMonthYear(8, 2022); + const result9 = printDateRangeFromMonthYear(9, 2022); + const result10 = printDateRangeFromMonthYear(10, 2022); + const result11 = printDateRangeFromMonthYear(11, 2022); + const result12 = printDateRangeFromMonthYear(12, 2022); + const result13 = printDateRangeFromMonthYear(1, 2020); + const result14 = printDateRangeFromMonthYear(12, 2020); + expect(result1).toEqual("January 1, 2022 - January 31, 2022"); + expect(result2).toEqual("February 1, 2022 - February 28, 2022"); + expect(result3).toEqual("March 1, 2022 - March 31, 2022"); + expect(result4).toEqual("April 1, 2022 - April 30, 2022"); + expect(result5).toEqual("May 1, 2022 - May 31, 2022"); + expect(result6).toEqual("June 1, 2022 - June 30, 2022"); + expect(result7).toEqual("July 1, 2022 - July 31, 2022"); + expect(result8).toEqual("August 1, 2022 - August 31, 2022"); + expect(result9).toEqual("September 1, 2022 - September 30, 2022"); + expect(result10).toEqual("October 1, 2022 - October 31, 2022"); + expect(result11).toEqual("November 1, 2022 - November 30, 2022"); + expect(result12).toEqual("December 1, 2022 - December 31, 2022"); + expect(result13).toEqual("January 1, 2020 - January 31, 2020"); + expect(result14).toEqual("December 1, 2020 - December 31, 2020"); + }); + + test("annual", () => { + const result1 = printDateRangeFromMonthYear(1, 2022, "ANNUAL"); + const result2 = printDateRangeFromMonthYear(7, 2022, "ANNUAL"); + expect(result1).toEqual("January 1, 2022 - December 31, 2022"); + expect(result2).toEqual("July 1, 2022 - June 30, 2023"); + }); +}); + +describe("printElapsedDaysMonthsYearsSinceDate", () => { + const dayAsMilliseconds = 86400000; + const zeroDaysLapsed = new Date( + Date.now() - dayAsMilliseconds * 0 + ).toString(); + const oneDayLapsed = new Date(Date.now() - dayAsMilliseconds * 1).toString(); + const twoDaysLapsed = new Date(Date.now() - dayAsMilliseconds * 2).toString(); + const fifteenDaysLapsed = new Date( + Date.now() - dayAsMilliseconds * 15 + ).toString(); + const fourtyDaysLapsed = new Date( + Date.now() - dayAsMilliseconds * 40 + ).toString(); + const sixtyDaysLapsed = new Date( + Date.now() - dayAsMilliseconds * 60 + ).toString(); + const hundredDaysLapsed = new Date( + Date.now() - dayAsMilliseconds * 100 + ).toString(); + const fiveHundredDaysLapsed = new Date( + Date.now() - dayAsMilliseconds * 500 + ).toString(); + const nineHundredDaysLapsed = new Date( + Date.now() - dayAsMilliseconds * 900 + ).toString(); + + test("0 days ago prints today", () => { + const zeroDaysLapsedText = + printElapsedDaysMonthsYearsSinceDate(zeroDaysLapsed); + const nonZeroDaysLapsedText = + printElapsedDaysMonthsYearsSinceDate(fifteenDaysLapsed); + expect(zeroDaysLapsedText).toEqual("today"); + expect(nonZeroDaysLapsedText).not.toEqual("today"); + }); + + test("1 day ago prints yesterday", () => { + const oneDayLapsedText = printElapsedDaysMonthsYearsSinceDate(oneDayLapsed); + expect(oneDayLapsedText).toEqual("yesterday"); + }); + + test("less than 31 days ago prints number of days lapsed", () => { + const twoDaysLapsedText = + printElapsedDaysMonthsYearsSinceDate(twoDaysLapsed); + const fifteenDaysLapsedText = + printElapsedDaysMonthsYearsSinceDate(fifteenDaysLapsed); + expect(twoDaysLapsedText).toEqual("2 days ago"); + expect(fifteenDaysLapsedText).toEqual("15 days ago"); + }); + + test("more than 30 days prints number of months lapsed", () => { + const fourtyDaysLapsedText = + printElapsedDaysMonthsYearsSinceDate(fourtyDaysLapsed); + const sixtyDaysLapsedText = + printElapsedDaysMonthsYearsSinceDate(sixtyDaysLapsed); + const hundredDaysLapsedText = + printElapsedDaysMonthsYearsSinceDate(hundredDaysLapsed); + expect(fourtyDaysLapsedText).toEqual("a month ago"); + expect(sixtyDaysLapsedText).toEqual("2 months ago"); + expect(hundredDaysLapsedText).toEqual("3 months ago"); + }); + + test("more than 365 days prints number of years lapsed", () => { + const fiveHundredDaysLapsedText = printElapsedDaysMonthsYearsSinceDate( + fiveHundredDaysLapsed + ); + const nineHundredDaysLapsedText = printElapsedDaysMonthsYearsSinceDate( + nineHundredDaysLapsed + ); + expect(fiveHundredDaysLapsedText).toEqual("a year ago"); + expect(nineHundredDaysLapsedText).toEqual("2 years ago"); + }); +}); diff --git a/publisher/src/utils/dateUtils.ts b/publisher/src/utils/dateUtils.ts new file mode 100644 index 000000000..a3ec6e09b --- /dev/null +++ b/publisher/src/utils/dateUtils.ts @@ -0,0 +1,133 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { ReportFrequency } from "../shared/types"; + +export const monthsByName = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", +]; + +/** + * @returns the month and year as a string + * @example "March 2022" + */ +export const printDateAsMonthYear = (month: number, year: number): string => { + return new Intl.DateTimeFormat("en-US", { + month: "long", + year: "numeric", + }).format(Date.UTC(year, month, -15)); +}; + +/** + * @returns either "Annual Report [YEAR]" or "[MONTH] [YEAR]" as a string depending on frequency + * @example "Annual Report 2022" or "March 2022" + */ +export const printReportTitle = ( + month: number, + year: number, + frequency: ReportFrequency +): string => { + if (frequency === "ANNUAL") { + return `Annual Report ${year}`; + } + + return printDateAsMonthYear(month, year); +}; + +/** + * @returns elapsed number of days since a provided date as a string + * @example 'today', 'yesterday', '2 days ago', '3 months ago', '5 years ago' + */ +export const printElapsedDaysMonthsYearsSinceDate = (date: string): string => { + const now = +new Date(Date.now()); + const stringDateToNumber = +new Date(date); + const daysLapsed = Math.floor( + (now - stringDateToNumber) / (1000 * 60 * 60 * 24) + ); + + if (daysLapsed === 0) { + return `today`; + } + + if (daysLapsed === 1) { + return `yesterday`; + } + + if (daysLapsed < 31) { + return `${daysLapsed !== 1 ? daysLapsed : "a"} day${ + daysLapsed !== 1 ? "s" : "" + } ago`; + } + + if (daysLapsed > 30 && daysLapsed < 365) { + const monthsLapsed = Math.floor(daysLapsed / 30); + return `${monthsLapsed !== 1 ? monthsLapsed : "a"} month${ + monthsLapsed !== 1 ? "s" : "" + } ago`; + } + + if (daysLapsed >= 365) { + const yearsLapsed = Math.floor(daysLapsed / 365); + return `${yearsLapsed !== 1 ? yearsLapsed : "a"} year${ + yearsLapsed !== 1 ? "s" : "" + } ago`; + } + + return ""; +}; + +/** + * Prints a human-readable date range of the provided month based on month and year + * @returns date range of the month as a string + * @example printDateRangeFromMonthYear(12, 2022) returns 'December 1, 2022 - December 31, 2022' + */ +export const printDateRangeFromMonthYear = ( + month: number, + year: number, + frequency: ReportFrequency = "MONTHLY" +): string => { + /** + * Note: backend sends true month number, whereas JavaScript's Date API deals with zero-indexed month numbers + * The below method of calculating the last day (number) of a given month relies on getting the 0th day of the following month. + * Simply providing the true month number value (from `month` param) does the + 1 (following month) calculation for us. + */ + + if (frequency === "MONTHLY") { + const lastDayOfMonth = new Date(year, month, 0)?.getDate(); + const currentMonth = monthsByName[month - 1]; + return `${currentMonth} 1, ${year} - ${currentMonth} ${lastDayOfMonth}, ${year}`; + } + + const currentMonth = monthsByName[month - 1]; + const prevMonthNumber = month === 1 ? 12 : month - 1; + const prevMonth = monthsByName[prevMonthNumber - 1]; + const lastDayOfPrevMonth = new Date(year, prevMonthNumber, 0)?.getDate(); + return `${currentMonth} 1, ${year} - ${prevMonth} ${lastDayOfPrevMonth}, ${ + month === 1 ? year : year + 1 + }`; +}; diff --git a/publisher/src/utils/helperUtils.test.ts b/publisher/src/utils/helperUtils.test.ts new file mode 100644 index 000000000..c07454fa6 --- /dev/null +++ b/publisher/src/utils/helperUtils.test.ts @@ -0,0 +1,127 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { + formatNumberInput, + isPositiveNumber, + normalizeToString, + sanitizeInputValue, +} from "./helperUtils"; + +describe("sanitizeInputValue", () => { + test("return previous value if input value is undefined", () => { + const undefinedInput = sanitizeInputValue(undefined, 2); + const definedInput = sanitizeInputValue("1", 2); + + expect(undefinedInput).toBe(2); + expect(definedInput).toBe(1); + }); + + test("return null if empty string input", () => { + const emptyStringInput = sanitizeInputValue("", 2); + const nonEmptyStringInput = sanitizeInputValue("text", 2); + + expect(emptyStringInput).toBeNull(); + expect(nonEmptyStringInput).not.toBeNull(); + }); + + test("return the number zero for string 0 and 0.00 with decimals", () => { + const zeroString = sanitizeInputValue("0", null); + const zeroDecimal = sanitizeInputValue("0.00", null); + + expect(zeroString).toBe(0); + expect(zeroDecimal).toBe(0); + }); + + test("return value converted to number if convertible", () => { + const numberString = sanitizeInputValue("123", null); + const numberStringWithDecimals = sanitizeInputValue("123.2341", null); + const numberStringWithDecimalsAfterZero = sanitizeInputValue( + "0.12341", + null + ); + + expect(numberString).toBe(123); + expect(numberStringWithDecimals).toBe(123.2341); + expect(numberStringWithDecimalsAfterZero).toBe(0.12341); + }); + + test("return value as string if not convertible to number", () => { + const nonNumber = sanitizeInputValue("0.123abc", null); + expect(typeof nonNumber).toBe("string"); + }); +}); + +describe("normalizeToString", () => { + test("return string version of value", () => { + const undefinedInput = normalizeToString(undefined); + const nullInput = normalizeToString(null); + const booleanInput = normalizeToString(false); + const numberInput = normalizeToString(22); + const stringInput = normalizeToString("Hello"); + + expect(undefinedInput).toBe(""); + expect(nullInput).toBe(""); + expect(booleanInput).toBe("false"); + expect(numberInput).toBe("22"); + expect(stringInput).toBe("Hello"); + }); +}); + +describe("formatNumberInput", () => { + test("return formatted number with commas and decimals", () => { + const inputWithCommasSpaces = formatNumberInput( + " 1231223,23,23,3,3.123123123 11 " + ); + const inputWithSeriesOfNumbers = formatNumberInput("123122323233312"); + + expect(inputWithCommasSpaces).toBe("1,231,223,232,333.12312312311"); + expect(inputWithSeriesOfNumbers).toBe("123,122,323,233,312"); + }); + + test("return formatted number on first decimal instance", () => { + const inputWithDecimalAtEnd = formatNumberInput("2,32,3,23,2."); + expect(inputWithDecimalAtEnd).toBe("2,323,232."); + }); + + test("return input value if not valid", () => { + const invalidInput = formatNumberInput("12xyz!"); + expect(invalidInput).toBe("12xyz!"); + }); +}); + +describe("isPositiveNumber", () => { + test("valid positive numbers return true", () => { + expect(isPositiveNumber("1")).toBe(true); + expect(isPositiveNumber("12")).toBe(true); + expect(isPositiveNumber("13")).toBe(true); + expect(isPositiveNumber("3.4")).toBe(true); + expect(isPositiveNumber("0")).toBe(true); + }); + test("negative numbers return false", () => { + expect(isPositiveNumber("-1")).toBe(false); + expect(isPositiveNumber("-5")).toBe(false); + expect(isPositiveNumber("-5.6")).toBe(false); + }); + test("invalid numbers return false", () => { + expect(isPositiveNumber("-1 ")).toBe(false); + expect(isPositiveNumber("0.0.0")).toBe(false); + expect(isPositiveNumber("five")).toBe(false); + expect(isPositiveNumber(" ")).toBe(false); + expect(isPositiveNumber("")).toBe(false); + }); +}); diff --git a/publisher/src/utils/helperUtils.ts b/publisher/src/utils/helperUtils.ts new file mode 100644 index 000000000..94036fb50 --- /dev/null +++ b/publisher/src/utils/helperUtils.ts @@ -0,0 +1,222 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +import { debounce, memoize } from "lodash"; + +import { MetricContext } from "../shared/types"; + +export const isPositiveNumber = (value: string) => { + return (value.trim() !== "" && Number(value) === 0) || Number(value) > 0; +}; + +/** + * Separate multiple people on a list by comma - no comma for the last person on the list + * @example ['Editor 1', 'Editor 2', 'Editor 3'] would print: `Editor 1, Editor 2, Editor 3` + */ +export const printCommaSeparatedList = (list: string[]): string => { + const string = list.map((item, i) => + i < list.length - 1 ? `${item}, ` : `${item}` + ); + return string.join(" "); +}; + +/** + * Take a string, trim and remove all spacing, and lowercase it. + * @example normalizeString("All Reports ") will be "allreports" + */ +export const normalizeString = (string: string): string => { + return string.split(" ").join("").toLowerCase().trim(); +}; + +/** + * Take a string, replace _ with ' ' space. + * @example "NOT_STARTED" becomes "NOT STARTED" + */ +export const removeSnakeCase = (string: string): string => { + return string.split("_").join(" "); +}; + +/** + * Concatenate two string keys by an `_` underscore (default) or a specified separator string + * @returns a single concatenated string + * @examples + * combineTwoKeyNames("KEY1", "KEY2") will return "KEY1_KEY2" + * combineTwoKeyNames("KEY1", "KEY2", "-") will return "KEY1-KEY2" + */ +export const combineTwoKeyNames = ( + key1: string, + key2: string, + separator?: string +) => { + return `${key1}${separator || "_"}${key2}`; +}; + +/** + * Remove commas, spaces and trim string + * + * @returns a trimmed string free from spaces and commas + * @example " 1,000,00 0 " becomes "1000000" + */ + +export const removeCommaSpaceAndTrim = (string: string) => { + return string?.replaceAll(",", "").replaceAll(" ", "").trim(); +}; + +/** + * Formats string version of numbers into string format with thousands separator + * + * @returns a string representation of a number with commas + * @example " 1231223,23,23,3,3.123123123 11 " " becomes "1,231,223,232,333.12312312311" + */ + +export const formatNumberInput = ( + value: string | undefined +): string | undefined => { + if (value === undefined) { + return undefined; + } + + const maxNumber = 999_999_999_999_999; // 1 quadrillion + const cleanValue = removeCommaSpaceAndTrim(value); + const splitValues = cleanValue.split("."); + + if (Number(cleanValue) > maxNumber) { + return Number(cleanValue.slice(0, 15)).toLocaleString(); + } + + if (splitValues && splitValues.length === 2) { + if (cleanValue[cleanValue.length - 1] === ".") { + return Number(splitValues[0]) !== 0 && Number(splitValues[0]) + ? `${Number(splitValues[0]).toLocaleString()}.` + : value; + } + + if (cleanValue.includes(".")) { + const [wholeNumber, decimal] = cleanValue.split("."); + return Number(wholeNumber) + ? `${Number(wholeNumber).toLocaleString()}.${decimal}` + : value; + } + } + return Number(cleanValue) ? Number(cleanValue).toLocaleString() : value; +}; + +/** + * Sanitize by formatting and converting string input to appropriate value for backend. + * + * @param value input value + * @param previousValue previously saved value retrieved from the backend + * @returns + * * `previousValue` from the backend if `value` is undefined + * * `null` for empty string + * * number `0` for true zeros ("0", "0.000", etc.) + * * `value` converted to number + * * `value` itself (if it is not a number) or if the type is "TEXT" + */ + +export const sanitizeInputValue = ( + value: string | undefined, + previousValue: string | number | boolean | null | undefined, + type?: MetricContext["type"] +): string | number | boolean | null | undefined => { + if (value === undefined) { + return previousValue; + } + const cleanValue = removeCommaSpaceAndTrim(value); + if (cleanValue === "") { + return null; + } + if (type === "TEXT") { + return value; + } + if (Number(cleanValue) === 0) { + return 0; + } + return Number(cleanValue) || value; +}; + +/** + * Converts string | number | boolean | null | undefined into string equivalents that conforms to a text input + * + * @returns a string, "" empty string to represent null and undefined, stringified version of number and boolean + */ +export const normalizeToString = ( + value: string | number | boolean | null | undefined +): string => { + const stringValue = value?.toString(); + return !stringValue ? "" : stringValue; +}; + +/** + * Group a list of objects based on property value + * @param arr list of objects + * @param key name of the property on which to perform the grouping + * @returns dictionary of property value to list of objects with that value + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const groupBy = (arr: T[], key: (i: T) => K) => { + const result = {} as Record; + arr.forEach((item) => { + if (!result[key(item)]) { + result[key(item)] = []; + } + result[key(item)].push(item); + }); + return result; +}; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export interface MemoizeDebouncedFunction any> { + (...args: Parameters): void; + flush: (...args: Parameters) => void; +} + +/** + * This method should be used instead of the standard `debounce` if we want to + * debounce *only* if the arguments to the function are the same. + * For instance, consider a function `click(param: str)`. With standard debounce, + * calling `click('foo')` and `click('bar')` in quick succession will only result + * in the execution of `click('bar')`. However, using memoized debounce, both + * functions will execute, because their parameters are different. + * Taken from https://github.com/lodash/lodash/issues/2403#issuecomment-816137402 + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function memoizeDebounce any>( + func: F, + wait = 0, + options: _.DebounceSettings = {}, + resolver?: (...args: Parameters) => unknown +): MemoizeDebouncedFunction { + const debounceMemo = memoize<(...args: Parameters) => _.DebouncedFunc>( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + (..._args: Parameters) => debounce(func, wait, options), + resolver + ); + + function wrappedFunction( + this: MemoizeDebouncedFunction, + ...args: Parameters + ): ReturnType | undefined { + return debounceMemo(...args)(...args); + } + + wrappedFunction.flush = (...args: Parameters): void => { + debounceMemo(...args).flush(); + }; + + return wrappedFunction as unknown as MemoizeDebouncedFunction; +} diff --git a/publisher/src/utils/index.ts b/publisher/src/utils/index.ts new file mode 100644 index 000000000..3d8962b73 --- /dev/null +++ b/publisher/src/utils/index.ts @@ -0,0 +1,20 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +export * from "./conversionUtils"; +export * from "./dateUtils"; +export * from "./helperUtils"; diff --git a/publisher/src/window.d.ts b/publisher/src/window.d.ts new file mode 100644 index 000000000..f89db5ce8 --- /dev/null +++ b/publisher/src/window.d.ts @@ -0,0 +1,32 @@ +// Recidiviz - a data platform for criminal justice reform +// Copyright (C) 2022 Recidiviz, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ============================================================================= + +// According to https://github.com/microsoft/TypeScript/issues/33128#issuecomment-748937504, +// this line is needed in order to turn this from a script into a module in order +// to allow the interface definition to be extended. +export {}; + +declare global { + interface Window { + // values added from `app_public_config.js` + APP_CONFIG: Record; + SEGMENT_KEY: string; + + // Segment's analytics.js + analytics: SegmentAnalytics.AnalyticsJS; + } +} diff --git a/publisher/tsconfig.json b/publisher/tsconfig.json new file mode 100644 index 000000000..c37853f2e --- /dev/null +++ b/publisher/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@recidiviz/tsconfig/react" +} diff --git a/publisher/yarn.lock b/publisher/yarn.lock new file mode 100644 index 000000000..56db0afb2 --- /dev/null +++ b/publisher/yarn.lock @@ -0,0 +1,9709 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" + integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== + dependencies: + "@jridgewell/trace-mapping" "^0.3.0" + +"@apideck/better-ajv-errors@^0.3.1": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.3.tgz#ab0b1e981e1749bf59736cf7ebe25cfc9f949c15" + integrity sha512-9o+HO2MbJhJHjDYZaDxJmSDckvDpiuItEsrIShV0DXeCshXWRHhqYyU/PKHMkuClOmFnZhRd6wzv4vpDu/dRKg== + dependencies: + json-schema "^0.4.0" + jsonpointer "^5.0.0" + leven "^3.1.0" + +"@auth0/auth0-react@^1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@auth0/auth0-react/-/auth0-react-1.9.0.tgz#957041fa9756a5cf20412116f19f2d1367aa66b6" + integrity sha512-VkovI2i7dI1dkIJAdS51O9XMq6vlcHJn9DL+if4rSxt+sNocFd1i4q0j07a9XbafBj4/WEkSbOiX93z2ZXqdAA== + dependencies: + "@auth0/auth0-spa-js" "^1.19.3" + +"@auth0/auth0-spa-js@^1.19.3", "@auth0/auth0-spa-js@^1.20.1": + version "1.20.1" + resolved "https://registry.yarnpkg.com/@auth0/auth0-spa-js/-/auth0-spa-js-1.20.1.tgz#8e49e76f0a8f5153595489a1399c980738609a65" + integrity sha512-hJyZ1n/7K0srArsnR9RKViGKh550SBE7nNB4g0F0X9H3VWCbETlCDWgnRckrhy045Bmb10VVcDBes3uImWTnjw== + dependencies: + abortcontroller-polyfill "^1.7.3" + browser-tabs-lock "^1.2.15" + core-js "^3.20.3" + es-cookie "^1.3.2" + fast-text-encoding "^1.0.3" + promise-polyfill "^8.2.1" + unfetch "^4.2.0" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.8.3": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + dependencies: + "@babel/highlight" "^7.16.7" + +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.8", "@babel/compat-data@^7.17.0", "@babel/compat-data@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" + integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== + +"@babel/core@^7.0.0-0", "@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.7.tgz#f7c28228c83cdf2dbd1b9baa06eaf9df07f0c2f9" + integrity sha512-djHlEfFHnSnTAcPb7dATbiM5HxGOP98+3JLBZtjRb5I7RXrw7kFRoG2dXM8cm3H+o11A8IFH/uprmJpwFynRNQ== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.7" + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helpers" "^7.17.7" + "@babel/parser" "^7.17.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + +"@babel/eslint-parser@^7.16.3": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz#eabb24ad9f0afa80e5849f8240d0e5facc2d90d6" + integrity sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA== + dependencies: + eslint-scope "^5.1.1" + eslint-visitor-keys "^2.1.0" + semver "^6.3.0" + +"@babel/generator@^7.17.3", "@babel/generator@^7.17.7", "@babel/generator@^7.7.2": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.7.tgz#8da2599beb4a86194a3b24df6c085931d9ee45ad" + integrity sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w== + dependencies: + "@babel/types" "^7.17.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@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" + integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== + dependencies: + "@babel/types" "^7.16.7" + +"@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" + integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" + integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== + dependencies: + "@babel/compat-data" "^7.17.7" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7", "@babel/helper-create-class-features-plugin@^7.17.1", "@babel/helper-create-class-features-plugin@^7.17.6": + version "7.17.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz#3778c1ed09a7f3e65e6d6e0f6fbfcc53809d92c9" + integrity sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + +"@babel/helper-create-regexp-features-plugin@^7.16.7": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" + integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + regexpu-core "^5.0.1" + +"@babel/helper-define-polyfill-provider@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" + integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.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" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + +"@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" + integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== + dependencies: + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" + +"@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" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-member-expression-to-functions@^7.16.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4" + integrity sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw== + dependencies: + "@babel/types" "^7.17.0" + +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4", "@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" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-transforms@^7.16.7", "@babel/helper-module-transforms@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" + integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.17.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" + +"@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" + integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== + dependencies: + "@babel/types" "^7.16.7" + +"@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.13.0", "@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-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" + integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-wrap-function" "^7.16.8" + "@babel/types" "^7.16.8" + +"@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" + integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-simple-access@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" + integrity sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== + dependencies: + "@babel/types" "^7.17.0" + +"@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" + integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== + dependencies: + "@babel/types" "^7.16.0" + +"@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" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + dependencies: + "@babel/types" "^7.16.7" + +"@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-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-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" + integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== + dependencies: + "@babel/helper-function-name" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.8" + "@babel/types" "^7.16.8" + +"@babel/helpers@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.7.tgz#6fc0a24280fd00026e85424bbfed4650e76d7127" + integrity sha512-TKsj9NkjJfTBxM7Phfy7kv6yYc4ZcOo+AaWGqQOKTPDOmcGkIFb5xNA746eKisQkm4yavUYh4InYM9S+VnO01w== + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" + +"@babel/highlight@^7.16.7": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" + integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.3", "@babel/parser@^7.17.7", "@babel/parser@^7.7.0": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.7.tgz#fc19b645a5456c8d6fdb6cecd3c66c0173902800" + integrity sha512-bm3AQf45vR4gKggRfvJdYJ0gFLoCbsPxiFLSH6hTVYABptNHY6l9NrhnucVjQ/X+SPtLANT9lc0fFhikj+VBRA== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": + version "7.16.7" + 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.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050" + integrity sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9" + integrity sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + +"@babel/plugin-proposal-async-generator-functions@^7.16.8": + 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" + integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-class-properties@^7.16.0", "@babel/plugin-proposal-class-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" + integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-proposal-class-static-block@^7.16.7": + version "7.17.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz#164e8fd25f0d80fa48c5a4d1438a6629325ad83c" + integrity sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.17.6" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-proposal-decorators@^7.16.4": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.17.2.tgz#c36372ddfe0360cac1ee331a238310bddca11493" + integrity sha512-WH8Z95CwTq/W8rFbMqb9p3hicpt4RX4f0K659ax2VHxgOyT6qQmUaEVEjIh4WR9Eh9NymkVn5vwsrE68fAQNUw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.17.1" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/plugin-syntax-decorators" "^7.17.0" + charcodes "^0.2.0" + +"@babel/plugin-proposal-dynamic-import@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" + integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" + integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" + integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" + integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" + integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.16.0", "@babel/plugin-proposal-numeric-separator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" + integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.16.7": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz#d9eb649a54628a51701aef7e0ea3d17e2b9dd390" + integrity sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw== + dependencies: + "@babel/compat-data" "^7.17.0" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.16.7" + +"@babel/plugin-proposal-optional-catch-binding@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" + integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.16.0", "@babel/plugin-proposal-optional-chaining@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" + integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.16.0", "@babel/plugin-proposal-private-methods@^7.16.11": + version "7.16.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" + integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.10" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-proposal-private-property-in-object@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce" + integrity sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-proposal-unicode-property-regex@^7.16.7", "@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" + integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + 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-decorators@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.17.0.tgz#a2be3b2c9fe7d78bd4994e790896bc411e2f166d" + integrity sha512-qWe85yCXsvDEluNP0OyeQjH63DlhAR3W7K9BxxU1MvbDb48tgBG+Ao6IJJ6smPDrrVzSQZrbF6donpkFBMcs3A== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@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" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-flow@^7.14.5", "@babel/plugin-syntax-flow@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.7.tgz#202b147e5892b8452bbb0bb269c7ed2539ab8832" + integrity sha512-UDo3YGQO0jH6ytzVwgSLv9i/CzMcUjbKenL67dTrAZPPv6GFAtDhe6jqnvmoKzC/7htNTohhos+onPtDMqJwaQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-syntax-import-meta@^7.8.3": + 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.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz#50b6571d13f764266a113d77c82b4a6508bbe665" + integrity sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@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.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": + 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-typescript@^7.16.7", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" + integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-arrow-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" + integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-async-to-generator@^7.16.8": + 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" + integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + +"@babel/plugin-transform-block-scoped-functions@^7.16.7": + 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" + integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-block-scoping@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" + integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-classes@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" + integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" + integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-destructuring@^7.16.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.7.tgz#49dc2675a7afa9a5e4c6bdee636061136c3408d1" + integrity sha512-XVh0r5yq9sLR4vZ6eVZe8FKfIcSgaTBxVBRSYokRj2qksf6QerYnTxz9/GTuKTH/n/HwLP7t6gtlybHetJ/6hQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-dotall-regex@^7.16.7", "@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" + integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-duplicate-keys@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" + integrity sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-exponentiation-operator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" + integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-flow-strip-types@^7.16.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.7.tgz#291fb140c78dabbf87f2427e7c7c332b126964b8" + integrity sha512-mzmCq3cNsDpZZu9FADYYyfZJIOrSONmHcop2XEKPdBNMa4PDC4eEvcOvzZaCNcjKu72v0XQlA5y1g58aLRXdYg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-flow" "^7.16.7" + +"@babel/plugin-transform-for-of@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" + integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" + integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== + dependencies: + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" + integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-member-expression-literals@^7.16.7": + 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" + integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-modules-amd@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" + integrity sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.16.8": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.7.tgz#d86b217c8e45bb5f2dbc11eefc8eab62cf980d19" + integrity sha512-ITPmR2V7MqioMJyrxUo2onHNC3e+MvfFiFIR0RP21d3PtlVb6sfzoxNKiphSZUOM9hEIdzCcZe83ieX3yoqjUA== + dependencies: + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-simple-access" "^7.17.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7" + integrity sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw== + dependencies: + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" + integrity sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.16.8": + 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" + integrity sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + +"@babel/plugin-transform-new-target@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" + integrity sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-object-super@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" + integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + +"@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" + integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-property-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" + integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-react-constant-elements@^7.12.1": + version "7.17.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.17.6.tgz#6cc273c2f612a6a50cb657e63ee1303e5e68d10a" + integrity sha512-OBv9VkyyKtsHZiHLoSfCn+h6yU7YKX8nrs32xUmOa1SRSk+t03FosB6fBZ0Yz4BpD1WV7l73Nsad+2Tz7APpqw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-react-display-name@^7.16.0", "@babel/plugin-transform-react-display-name@^7.16.7": + 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" + integrity sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-react-jsx-development@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz#43a00724a3ed2557ed3f276a01a929e6686ac7b8" + integrity sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.16.7" + +"@babel/plugin-transform-react-jsx@^7.14.9", "@babel/plugin-transform-react-jsx@^7.16.7": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.3.tgz#eac1565da176ccb1a715dae0b4609858808008c1" + integrity sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-jsx" "^7.16.7" + "@babel/types" "^7.17.0" + +"@babel/plugin-transform-react-pure-annotations@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.7.tgz#232bfd2f12eb551d6d7d01d13fe3f86b45eb9c67" + integrity sha512-hs71ToC97k3QWxswh2ElzMFABXHvGiJ01IB1TbYQDGeWRKWz/MPUTh5jGExdHvosYKpnJW5Pm3S4+TA3FyX+GA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-regenerator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb" + integrity sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" + integrity sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-runtime@^7.16.4": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz#0a2e08b5e2b2d95c4b1d3b3371a2180617455b70" + integrity sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.5.0" + babel-plugin-polyfill-regenerator "^0.3.0" + semver "^6.3.0" + +"@babel/plugin-transform-shorthand-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" + integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-spread@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" + integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + +"@babel/plugin-transform-sticky-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" + integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-template-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" + integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-typeof-symbol@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" + integrity sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-typescript@^7.16.7": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz#591ce9b6b83504903fa9dd3652c357c2ba7a1ee0" + integrity sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-typescript" "^7.16.7" + +"@babel/plugin-transform-unicode-escapes@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" + integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-unicode-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" + integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4": + version "7.16.11" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982" + integrity sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g== + dependencies: + "@babel/compat-data" "^7.16.8" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-option" "^7.16.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.7" + "@babel/plugin-proposal-async-generator-functions" "^7.16.8" + "@babel/plugin-proposal-class-properties" "^7.16.7" + "@babel/plugin-proposal-class-static-block" "^7.16.7" + "@babel/plugin-proposal-dynamic-import" "^7.16.7" + "@babel/plugin-proposal-export-namespace-from" "^7.16.7" + "@babel/plugin-proposal-json-strings" "^7.16.7" + "@babel/plugin-proposal-logical-assignment-operators" "^7.16.7" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.7" + "@babel/plugin-proposal-numeric-separator" "^7.16.7" + "@babel/plugin-proposal-object-rest-spread" "^7.16.7" + "@babel/plugin-proposal-optional-catch-binding" "^7.16.7" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + "@babel/plugin-proposal-private-methods" "^7.16.11" + "@babel/plugin-proposal-private-property-in-object" "^7.16.7" + "@babel/plugin-proposal-unicode-property-regex" "^7.16.7" + "@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-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.16.7" + "@babel/plugin-transform-async-to-generator" "^7.16.8" + "@babel/plugin-transform-block-scoped-functions" "^7.16.7" + "@babel/plugin-transform-block-scoping" "^7.16.7" + "@babel/plugin-transform-classes" "^7.16.7" + "@babel/plugin-transform-computed-properties" "^7.16.7" + "@babel/plugin-transform-destructuring" "^7.16.7" + "@babel/plugin-transform-dotall-regex" "^7.16.7" + "@babel/plugin-transform-duplicate-keys" "^7.16.7" + "@babel/plugin-transform-exponentiation-operator" "^7.16.7" + "@babel/plugin-transform-for-of" "^7.16.7" + "@babel/plugin-transform-function-name" "^7.16.7" + "@babel/plugin-transform-literals" "^7.16.7" + "@babel/plugin-transform-member-expression-literals" "^7.16.7" + "@babel/plugin-transform-modules-amd" "^7.16.7" + "@babel/plugin-transform-modules-commonjs" "^7.16.8" + "@babel/plugin-transform-modules-systemjs" "^7.16.7" + "@babel/plugin-transform-modules-umd" "^7.16.7" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.8" + "@babel/plugin-transform-new-target" "^7.16.7" + "@babel/plugin-transform-object-super" "^7.16.7" + "@babel/plugin-transform-parameters" "^7.16.7" + "@babel/plugin-transform-property-literals" "^7.16.7" + "@babel/plugin-transform-regenerator" "^7.16.7" + "@babel/plugin-transform-reserved-words" "^7.16.7" + "@babel/plugin-transform-shorthand-properties" "^7.16.7" + "@babel/plugin-transform-spread" "^7.16.7" + "@babel/plugin-transform-sticky-regex" "^7.16.7" + "@babel/plugin-transform-template-literals" "^7.16.7" + "@babel/plugin-transform-typeof-symbol" "^7.16.7" + "@babel/plugin-transform-unicode-escapes" "^7.16.7" + "@babel/plugin-transform-unicode-regex" "^7.16.7" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.16.8" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.5.0" + babel-plugin-polyfill-regenerator "^0.3.0" + core-js-compat "^3.20.2" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@^7.12.5", "@babel/preset-react@^7.16.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.16.7.tgz#4c18150491edc69c183ff818f9f2aecbe5d93852" + integrity sha512-fWpyI8UM/HE6DfPBzD8LnhQ/OcH8AgTaqcqP2nGOXEUV+VKBR5JRN9hCk9ai+zQQ57vtm9oWeXguBCPNUjytgA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-option" "^7.16.7" + "@babel/plugin-transform-react-display-name" "^7.16.7" + "@babel/plugin-transform-react-jsx" "^7.16.7" + "@babel/plugin-transform-react-jsx-development" "^7.16.7" + "@babel/plugin-transform-react-pure-annotations" "^7.16.7" + +"@babel/preset-typescript@^7.16.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz#ab114d68bb2020afc069cd51b37ff98a046a70b9" + integrity sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-option" "^7.16.7" + "@babel/plugin-transform-typescript" "^7.16.7" + +"@babel/runtime-corejs3@^7.10.2": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.17.7.tgz#cf914f474c490ef1aa8661d47adaa0a993636e7e" + integrity sha512-TvliGJjhxis5m7xIMvlXH/xG8Oa/LK0SCUCyfKD6nLi42n5fB4WibDJ0g9trmmBB6hwpMNx+Lzbxy9/4gpMaVw== + dependencies: + core-js-pure "^3.20.2" + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.16.7", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825" + integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.1.2": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.7.6": + version "7.17.8" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.8.tgz#3e56e4aff81befa55ac3ac6a0967349fd1c5bca2" + integrity sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.16.7", "@babel/template@^7.3.3": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" + integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.3" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.3" + "@babel/types" "^7.17.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@csstools/normalize.css@*": + version "12.0.0" + resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz#a9583a75c3f150667771f30b60d9f059473e62c4" + integrity sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg== + +"@csstools/postcss-color-function@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-1.0.3.tgz#251c961a852c99e9aabdbbdbefd50e9a96e8a9ff" + integrity sha512-J26I69pT2B3MYiLY/uzCGKVJyMYVg9TCpXkWsRlt+Yfq+nELUEm72QXIMYXs4xA9cJA4Oqs2EylrfokKl3mJEQ== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-font-format-keywords@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.0.tgz#7e7df948a83a0dfb7eb150a96e2390ac642356a1" + integrity sha512-oO0cZt8do8FdVBX8INftvIA4lUrKUSCcWUf9IwH9IPWOgKT22oAZFXeHLoDK7nhB2SmkNycp5brxfNMRLIhd6Q== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-hwb-function@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.0.tgz#d6785c1c5ba8152d1d392c66f3a6a446c6034f6d" + integrity sha512-VSTd7hGjmde4rTj1rR30sokY3ONJph1reCBTUXqeW1fKwETPy1x4t/XIeaaqbMbC5Xg4SM/lyXZ2S8NELT2TaA== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-ic-unit@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.0.tgz#f484db59fc94f35a21b6d680d23b0ec69b286b7f" + integrity sha512-i4yps1mBp2ijrx7E96RXrQXQQHm6F4ym1TOD0D69/sjDjZvQ22tqiEvaNw7pFZTUO5b9vWRHzbHzP9+UKuw+bA== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-is-pseudo-class@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.1.tgz#472fff2cf434bdf832f7145b2a5491587e790c9e" + integrity sha512-Og5RrTzwFhrKoA79c3MLkfrIBYmwuf/X83s+JQtz/Dkk/MpsaKtqHV1OOzYkogQ+tj3oYp5Mq39XotBXNqVc3Q== + dependencies: + postcss-selector-parser "^6.0.9" + +"@csstools/postcss-normalize-display-values@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.0.tgz#ce698f688c28517447aedf15a9037987e3d2dc97" + integrity sha512-bX+nx5V8XTJEmGtpWTO6kywdS725t71YSLlxWt78XoHUbELWgoCXeOFymRJmL3SU1TLlKSIi7v52EWqe60vJTQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-oklab-function@^1.0.1": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.0.2.tgz#87cd646e9450347a5721e405b4f7cc35157b7866" + integrity sha512-QwhWesEkMlp4narAwUi6pgc6kcooh8cC7zfxa9LSQNYXqzcdNUtNBzbGc5nuyAVreb7uf5Ox4qH1vYT3GA1wOg== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-progressive-custom-properties@^1.1.0", "@csstools/postcss-progressive-custom-properties@^1.2.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz#542292558384361776b45c85226b9a3a34f276fa" + integrity sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA== + dependencies: + postcss-value-parser "^4.2.0" + +"@emotion/cache@^10.0.27": + version "10.0.29" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0" + integrity sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ== + dependencies: + "@emotion/sheet" "0.9.4" + "@emotion/stylis" "0.8.5" + "@emotion/utils" "0.11.3" + "@emotion/weak-memoize" "0.2.5" + +"@emotion/core@^10.0.14": + version "10.3.1" + resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.3.1.tgz#4021b6d8b33b3304d48b0bb478485e7d7421c69d" + integrity sha512-447aUEjPIm0MnE6QYIaFz9VQOHSXf4Iu6EWOIqq11EAPqinkSZmfymPTmlOE3QjLv846lH4JVZBUOtwGbuQoww== + dependencies: + "@babel/runtime" "^7.5.5" + "@emotion/cache" "^10.0.27" + "@emotion/css" "^10.0.27" + "@emotion/serialize" "^0.11.15" + "@emotion/sheet" "0.9.4" + "@emotion/utils" "0.11.3" + +"@emotion/css@^10.0.27": + version "10.0.27" + resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c" + integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw== + dependencies: + "@emotion/serialize" "^0.11.15" + "@emotion/utils" "0.11.3" + babel-plugin-emotion "^10.0.27" + +"@emotion/hash@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" + integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== + +"@emotion/is-prop-valid@^0.8.8": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + +"@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16": + version "0.11.16" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad" + integrity sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg== + dependencies: + "@emotion/hash" "0.8.0" + "@emotion/memoize" "0.7.4" + "@emotion/unitless" "0.7.5" + "@emotion/utils" "0.11.3" + csstype "^2.5.7" + +"@emotion/sheet@0.9.4": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5" + integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA== + +"@emotion/stylis@0.8.5", "@emotion/stylis@^0.8.4": + version "0.8.5" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" + integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== + +"@emotion/unitless@0.7.5", "@emotion/unitless@^0.7.4": + version "0.7.5" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" + integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== + +"@emotion/utils@0.11.3": + version "0.11.3" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924" + integrity sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw== + +"@emotion/weak-memoize@0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" + integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== + +"@eslint/eslintrc@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" + integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.3.1" + globals "^13.9.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@fontsource/libre-baskerville@^4.1.0": + version "4.5.3" + resolved "https://registry.yarnpkg.com/@fontsource/libre-baskerville/-/libre-baskerville-4.5.3.tgz#2be61ed7c349ad18dbcc947291bef9aa94ce26e1" + integrity sha512-c65YbQy65HyL2+KCZ0Xws54wzVlErVU2Ia1ewgkpEqwgtU/wb93pyCP2YOVI4K6jbIEXa6D1V0WsRM3XP9lmSQ== + +"@fontsource/libre-franklin@^4.1.0": + version "4.5.3" + resolved "https://registry.yarnpkg.com/@fontsource/libre-franklin/-/libre-franklin-4.5.3.tgz#89c519e60433cc63a473b31d5985ecba3ed89dac" + integrity sha512-dH3xW1RA1G8KPKAMv4FIQIzo04rT9uc+K3HzSNfxhrE0DpqIaABf7geUSV2GWtf5gjqdrjzrjLXjs0ehgkPrtQ== + +"@humanwhocodes/config-array@^0.9.2": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" + integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" + integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + +"@jest/core@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" + integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/reporters" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^27.5.1" + jest-config "^27.5.1" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-resolve-dependencies "^27.5.1" + jest-runner "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + jest-watcher "^27.5.1" + micromatch "^4.0.4" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== + dependencies: + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + +"@jest/fake-timers@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== + dependencies: + "@jest/types" "^27.5.1" + "@sinonjs/fake-timers" "^8.0.1" + "@types/node" "*" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +"@jest/globals@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/types" "^27.5.1" + expect "^27.5.1" + +"@jest/reporters@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" + integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-haste-map "^27.5.1" + jest-resolve "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.1.0" + +"@jest/source-map@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" + integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.9" + source-map "^0.6.0" + +"@jest/test-result@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" + integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== + dependencies: + "@jest/console" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" + integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== + dependencies: + "@jest/test-result" "^27.5.1" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-runtime "^27.5.1" + +"@jest/transform@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.5.1" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-regex-util "^27.5.1" + jest-util "^27.5.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" + integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pmmmwh/react-refresh-webpack-plugin@^0.5.3": + version "0.5.4" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.4.tgz#df0d0d855fc527db48aac93c218a0bf4ada41f99" + integrity sha512-zZbZeHQDnoTlt2AF+diQT0wsSXpvWiaIOZwBRdltNFhG1+I3ozyaw7U/nBiUwyJ0D+zwdXp0E3bWOl38Ag2BMw== + dependencies: + ansi-html-community "^0.0.8" + common-path-prefix "^3.0.0" + core-js-pure "^3.8.1" + error-stack-parser "^2.0.6" + find-up "^5.0.0" + html-entities "^2.1.0" + loader-utils "^2.0.0" + schema-utils "^3.0.0" + source-map "^0.7.3" + +"@react-spring/animated@~9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.4.4.tgz#15e21923e55c06ca2bcea432869b91b2f8b07519" + integrity sha512-e9xnuBaUTD+NolKikUmrGWjX8AVCPyj1GcEgjgq9E+0sXKv46UY7cm2EmB6mUDTxWIDVKebARY++xT4nGDraBQ== + dependencies: + "@react-spring/shared" "~9.4.4" + "@react-spring/types" "~9.4.4" + +"@react-spring/core@~9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.4.4.tgz#7730988cec7302ba6e0977cf4c08c30249d95622" + integrity sha512-llgb0ljFyjMB0JhWsaFHOi9XFT8n1jBMVs1IFY2ipIBerWIRWrgUmIpakLPHTa4c4jwqTaDSwX90s2a0iN7dxQ== + dependencies: + "@react-spring/animated" "~9.4.4" + "@react-spring/rafz" "~9.4.4" + "@react-spring/shared" "~9.4.4" + "@react-spring/types" "~9.4.4" + +"@react-spring/konva@~9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@react-spring/konva/-/konva-9.4.4.tgz#e65e3b85274e9af36c6037dbafa402d9f01db076" + integrity sha512-ZHwsf4l/W5YzK8TwlvGXL9SYiHxxC6iEOAKStRs8WV6VuBvTFgIoGK5RNOTbsRC2N/spNWnN6JViz1PNbgrB+A== + dependencies: + "@react-spring/animated" "~9.4.4" + "@react-spring/core" "~9.4.4" + "@react-spring/shared" "~9.4.4" + "@react-spring/types" "~9.4.4" + +"@react-spring/native@~9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@react-spring/native/-/native-9.4.4.tgz#8581e03d0c4a11f3e5a1fc8cf505c81f9d9a5fcf" + integrity sha512-p0/JI59JVkgVjnoLvu+cpEgEkE0B3RDvzT1oNaCAx0ePaGQo4ICAS8PyOgPvN5IHUOy59CBLSMNnFyHV+IgaGQ== + dependencies: + "@react-spring/animated" "~9.4.4" + "@react-spring/core" "~9.4.4" + "@react-spring/shared" "~9.4.4" + "@react-spring/types" "~9.4.4" + +"@react-spring/rafz@~9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.4.4.tgz#736c9ed1099baebeea20c357b9700b01b83ea9de" + integrity sha512-5ki/sQ06Mdf8AuFstSt5zbNNicRT4LZogiJttDAww1ozhuvemafNWEHxhzcULgCPCDu2s7HsroaISV7+GQWrhw== + +"@react-spring/shared@~9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.4.4.tgz#e1ae00a77d170d86d77d9a19dc7015bdddc2d26f" + integrity sha512-ySVgScDZlhm/+Iy2smY9i/DDrShArY0j6zjTS/Re1lasKnhq8qigoGiAxe8xMPJNlCaj3uczCqHy3TY9bKRtfQ== + dependencies: + "@react-spring/rafz" "~9.4.4" + "@react-spring/types" "~9.4.4" + +"@react-spring/three@~9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@react-spring/three/-/three-9.4.4.tgz#a26de44854e166184ddba57313bfc52efce67368" + integrity sha512-z77ohxg8zG0CcZJojzfoJTTrjSbIyefNz2RlId68/4IypnOs1p8kB2Q1p+wX4KyWORpLg8ivsPcjtwBjGwfDtg== + dependencies: + "@react-spring/animated" "~9.4.4" + "@react-spring/core" "~9.4.4" + "@react-spring/shared" "~9.4.4" + "@react-spring/types" "~9.4.4" + +"@react-spring/types@~9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.4.4.tgz#97c69881788e624d7cc68d4385fdaa9b5fd20642" + integrity sha512-KpxKt/D//q/t/6FBcde/RE36LKp8PpWu7kFEMLwpzMGl9RpcexunmYOQJWwmJWtkQjgE1YRr7DzBMryz6La1cQ== + +"@react-spring/web@~9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@react-spring/web/-/web-9.4.4.tgz#0d13356e61c1d47e83a36112e19e5db691f3fbe5" + integrity sha512-iJmOLdhcuizriUlu/xqBc5y8KaFts+UI+iC+GxyTwBtzxA9czKiSAZW2ESuhG8stafa3jncwjfTQQp84KN36cw== + dependencies: + "@react-spring/animated" "~9.4.4" + "@react-spring/core" "~9.4.4" + "@react-spring/shared" "~9.4.4" + "@react-spring/types" "~9.4.4" + +"@react-spring/zdog@~9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@react-spring/zdog/-/zdog-9.4.4.tgz#e0e19175a9a22d74614dbf3c624513fd35e69f9d" + integrity sha512-qmD8zRcodbQKTAFVMdgW2pYIZP1KttDnz2S2JEc7kx8I8F5ljn9czgRl5c4w9HJ0dpO8VTfPq4sKa4tlUL23yg== + dependencies: + "@react-spring/animated" "~9.4.4" + "@react-spring/core" "~9.4.4" + "@react-spring/shared" "~9.4.4" + "@react-spring/types" "~9.4.4" + +"@recidiviz/design-system@^2.7.0": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@recidiviz/design-system/-/design-system-2.7.0.tgz#25b67d141d88ab20548a08bf98284201b1ad1d34" + integrity sha512-Bnl/xGmY9k1QpHptKZa/QPIY99Cbmw1rxam70GRiZiKHY7ePdvHn8XucaFE1dJUyq/gDWC/KJSatJxZQpy1pgQ== + dependencies: + "@fontsource/libre-baskerville" "^4.1.0" + "@fontsource/libre-franklin" "^4.1.0" + "@types/react-tabs" "^2.3.2" + body-scroll-lock "^3.1.5" + polished "^4.1.0" + prop-types "^15.7.2" + react-is "^17.0.2" + react-modal "^3.12.1" + react-spring "^9.4.3" + react-tabs "^3.2.2" + react-toast-notifications "^2.4.3" + styled-components "^5.2.1" + +"@recidiviz/eslint-config@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@recidiviz/eslint-config/-/eslint-config-2.0.0.tgz#3b911264deb8ec2865dbaf8df4da8a8496c61583" + integrity sha512-r23ijnTDO43yODsEQYuuA25hNNnOJj/T6beMr7xsdOgw+Kd6iU+IKLr+lSpgIeBMUqK+YdyQRuXw4fdiQPWqlg== + dependencies: + eslint-config-airbnb "^18.2.0" + eslint-config-prettier "^8.1.0" + prettier "^2.2.1" + +"@recidiviz/tsconfig@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@recidiviz/tsconfig/-/tsconfig-1.0.0.tgz#317b6dc9a6c45016d10f4f4864b124d4ce5ba097" + integrity sha512-N6brrksfnQIYh7fqKhFhM+SQr817lXQdCgtHJyEvRL9rhtOR+1Y0b0nhVADZWEUSdRJdzjHoWWkOIJPoI9AluA== + dependencies: + "@tsconfig/node12" "^1.0.7" + +"@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" + +"@rushstack/eslint-patch@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.1.tgz#782fa5da44c4f38ae9fd38e9184b54e451936118" + integrity sha512-BUyKJGdDWqvWC5GEhyOiUrGNi9iJUr4CU0O2WxJL6QJhHeeA/NVBalH+FeK0r/x/W0rPymXt5s78TDS7d6lCwg== + +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@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" + +"@svgr/babel-plugin-add-jsx-attribute@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906" + integrity sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg== + +"@svgr/babel-plugin-remove-jsx-attribute@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz#6b2c770c95c874654fd5e1d5ef475b78a0a962ef" + integrity sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg== + +"@svgr/babel-plugin-remove-jsx-empty-expression@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz#25621a8915ed7ad70da6cea3d0a6dbc2ea933efd" + integrity sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA== + +"@svgr/babel-plugin-replace-jsx-attribute-value@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz#0b221fc57f9fcd10e91fe219e2cd0dd03145a897" + integrity sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ== + +"@svgr/babel-plugin-svg-dynamic-title@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz#139b546dd0c3186b6e5db4fefc26cb0baea729d7" + integrity sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg== + +"@svgr/babel-plugin-svg-em-dimensions@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz#6543f69526632a133ce5cabab965deeaea2234a0" + integrity sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw== + +"@svgr/babel-plugin-transform-react-native-svg@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz#00bf9a7a73f1cad3948cdab1f8dfb774750f8c80" + integrity sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q== + +"@svgr/babel-plugin-transform-svg-component@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz#583a5e2a193e214da2f3afeb0b9e8d3250126b4a" + integrity sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ== + +"@svgr/babel-preset@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-5.5.0.tgz#8af54f3e0a8add7b1e2b0fcd5a882c55393df327" + integrity sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^5.4.0" + "@svgr/babel-plugin-remove-jsx-attribute" "^5.4.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "^5.0.1" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^5.0.1" + "@svgr/babel-plugin-svg-dynamic-title" "^5.4.0" + "@svgr/babel-plugin-svg-em-dimensions" "^5.4.0" + "@svgr/babel-plugin-transform-react-native-svg" "^5.4.0" + "@svgr/babel-plugin-transform-svg-component" "^5.5.0" + +"@svgr/core@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-5.5.0.tgz#82e826b8715d71083120fe8f2492ec7d7874a579" + integrity sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ== + dependencies: + "@svgr/plugin-jsx" "^5.5.0" + camelcase "^6.2.0" + cosmiconfig "^7.0.0" + +"@svgr/hast-util-to-babel-ast@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz#5ee52a9c2533f73e63f8f22b779f93cd432a5461" + integrity sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ== + dependencies: + "@babel/types" "^7.12.6" + +"@svgr/plugin-jsx@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz#1aa8cd798a1db7173ac043466d7b52236b369000" + integrity sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA== + dependencies: + "@babel/core" "^7.12.3" + "@svgr/babel-preset" "^5.5.0" + "@svgr/hast-util-to-babel-ast" "^5.5.0" + svg-parser "^2.0.2" + +"@svgr/plugin-svgo@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz#02da55d85320549324e201c7b2e53bf431fcc246" + integrity sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ== + dependencies: + cosmiconfig "^7.0.0" + deepmerge "^4.2.2" + svgo "^1.2.2" + +"@svgr/webpack@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-5.5.0.tgz#aae858ee579f5fa8ce6c3166ef56c6a1b381b640" + integrity sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g== + dependencies: + "@babel/core" "^7.12.3" + "@babel/plugin-transform-react-constant-elements" "^7.12.1" + "@babel/preset-env" "^7.12.1" + "@babel/preset-react" "^7.12.5" + "@svgr/core" "^5.5.0" + "@svgr/plugin-jsx" "^5.5.0" + "@svgr/plugin-svgo" "^5.5.0" + loader-utils "^2.0.0" + +"@testing-library/dom@^8.0.0", "@testing-library/dom@^8.11.3": + version "8.11.3" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.11.3.tgz#38fd63cbfe14557021e88982d931e33fb7c1a808" + integrity sha512-9LId28I+lx70wUiZjLvi1DB/WT2zGOxUh46glrSNMaWVx849kKAluezVzZrXJfTKKoQTmEOutLes/bHg4Bj3aA== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^4.2.0" + aria-query "^5.0.0" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.4.4" + pretty-format "^27.0.2" + +"@testing-library/jest-dom@^5.14.1": + version "5.16.2" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz#f329b36b44aa6149cd6ced9adf567f8b6aa1c959" + integrity sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug== + dependencies: + "@babel/runtime" "^7.9.2" + "@types/testing-library__jest-dom" "^5.9.1" + aria-query "^5.0.0" + chalk "^3.0.0" + css "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.5.6" + lodash "^4.17.15" + redent "^3.0.0" + +"@testing-library/react@^12.0.0": + version "12.1.4" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.4.tgz#09674b117e550af713db3f4ec4c0942aa8bbf2c0" + integrity sha512-jiPKOm7vyUw311Hn/HlNQ9P8/lHNtArAx0PisXyFixDDvfl8DbD6EUdbshK5eqauvBSvzZd19itqQ9j3nferJA== + dependencies: + "@babel/runtime" "^7.12.5" + "@testing-library/dom" "^8.0.0" + "@types/react-dom" "*" + +"@testing-library/user-event@^13.2.1": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" + integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== + dependencies: + "@babel/runtime" "^7.12.5" + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@tsconfig/node12@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" + integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + +"@types/aria-query@^4.2.0": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc" + integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig== + +"@types/auth0@^2.34.13": + version "2.34.13" + resolved "https://registry.yarnpkg.com/@types/auth0/-/auth0-2.34.13.tgz#9bc2c114efff012a46fbcae94976958dd24c6c3e" + integrity sha512-eqTXGLGv4hLVMFaZOyZaXtjQqLnpgrcmyZXoRF99IQoOg1q/6KCy606+BRnqK6ywHGtI8fLk8Gjs2rvIFj0bWg== + +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.1.18" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.18.tgz#1a29abcc411a9c05e2094c98f9a1b7da6cdf49f8" + integrity sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== + dependencies: + "@babel/types" "^7.3.0" + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" + integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.4.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304" + integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/eslint@^7.28.2": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.29.0.tgz#e56ddc8e542815272720bb0b4ccc2aff9c3e1c78" + integrity sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@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/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.28" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" + integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/history@^4.7.11": + version "4.7.11" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" + integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== + +"@types/hoist-non-react-statics@*": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + +"@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== + +"@types/http-proxy@^1.17.8": + version "1.17.8" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" + integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@*", "@types/jest@^27.0.1": + version "27.4.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d" + integrity sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw== + dependencies: + jest-matcher-utils "^27.0.0" + pretty-format "^27.0.0" + +"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.10" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.10.tgz#9b05b7896166cd00e9cbd59864853abf65d9ac23" + integrity sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + +"@types/lodash.debounce@^4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.7.tgz#0285879defb7cdb156ae633cecd62d5680eded9f" + integrity sha512-X1T4wMZ+gT000M2/91SYj0d/7JfeNZ9PeeOldSNoE/lunLeQXKvkmIumI29IaKMotU/ln/McOIvgzZcQ/3TrSA== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*", "@types/lodash@^4.14.182": + version "4.14.182" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2" + integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/node@*": + version "17.0.21" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644" + integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ== + +"@types/node@^16.7.13": + version "16.11.26" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.26.tgz#63d204d136c9916fb4dcd1b50f9740fe86884e47" + integrity sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/prettier@^2.1.5": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" + integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA== + +"@types/prop-types@*": + version "15.7.4" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" + integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== + +"@types/q@^1.5.1": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.5.tgz#75a2a8e7d8ab4b230414505d92335d1dcb53a6df" + integrity sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ== + +"@types/qs@*", "@types/qs@^6.9.7": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/reach__router@^1.3.10": + version "1.3.10" + resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.10.tgz#141d500213a452d9d9d71d5ad96c4104094f55a3" + integrity sha512-iHAFGaVOrWi00/q7oBybggGsz5TOmwOW4M1H9sT7i9lly4qFC8XOgsdf6jUsoaOz2sknFHALEtZqCoDbokdJ2Q== + dependencies: + "@types/react" "*" + +"@types/react-dom@*", "@types/react-dom@^17.0.9": + version "17.0.13" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.13.tgz#a3323b974ee4280070982b3112351bb1952a7809" + integrity sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ== + dependencies: + "@types/react" "*" + +"@types/react-modal@^3.13.1": + version "3.13.1" + resolved "https://registry.yarnpkg.com/@types/react-modal/-/react-modal-3.13.1.tgz#5b9845c205fccc85d9a77966b6e16dc70a60825a" + integrity sha512-iY/gPvTDIy6Z+37l+ibmrY+GTV4KQTHcCyR5FIytm182RQS69G5ps4PH2FxtC7bAQ2QRHXMevsBgck7IQruHNg== + dependencies: + "@types/react" "*" + +"@types/react-router-dom@^5.3.3": + version "5.3.3" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" + integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router" "*" + +"@types/react-router@*": + version "5.1.18" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.18.tgz#c8851884b60bc23733500d86c1266e1cfbbd9ef3" + integrity sha512-YYknwy0D0iOwKQgz9v8nOzt2J6l4gouBmDnWqUUznltOTaon+r8US8ky8HvN0tXvc38U9m6z/t2RsVsnd1zM0g== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + +"@types/react-tabs@^2.3.2": + version "2.3.4" + resolved "https://registry.yarnpkg.com/@types/react-tabs/-/react-tabs-2.3.4.tgz#b63662ee52e59a86ec33b78b9721d8163a46394c" + integrity sha512-HQzhKW+RF/7h14APw/2cu4Nnt+GmsTvfBKbFdn/NbYpb8Q+iB65wIkPHz4VRKDxWtOpNFpOUtzt5r0LRmQMfOA== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^17.0.20": + version "17.0.40" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.40.tgz#dc010cee6254d5239a138083f3799a16638e6bad" + integrity sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ== + dependencies: + "@types/prop-types" "*" + "@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/retry@^0.12.0": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" + integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== + +"@types/scheduler@*": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/styled-components@^5.1.24": + version "5.1.24" + resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.24.tgz#b52ae677f03ea8a6018aa34c6c96b7018b7a3571" + integrity sha512-mz0fzq2nez+Lq5IuYammYwWgyLUE6OMAJTQL9D8hFLP4Pkh7gVYJii/VQWxq8/TK34g/OrkehXaFNdcEKcItug== + dependencies: + "@types/hoist-non-react-statics" "*" + "@types/react" "*" + csstype "^3.0.2" + +"@types/testing-library__jest-dom@^5.9.1": + version "5.14.3" + resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.3.tgz#ee6c7ffe9f8595882ee7bda8af33ae7b8789ef17" + integrity sha512-oKZe+Mf4ioWlMuzVBaXQ9WDnEm1+umLx0InILg+yvZVBBDmzV5KfZyLrCvadtWcx8+916jLmHafcmqqffl+iIw== + dependencies: + "@types/jest" "*" + +"@types/trusted-types@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" + integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== + +"@types/ws@^8.2.2": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^16.0.0": + version "16.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + dependencies: + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@^5.15.0", "@typescript-eslint/eslint-plugin@^5.5.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.15.0.tgz#c28ef7f2e688066db0b6a9d95fb74185c114fb9a" + integrity sha512-u6Db5JfF0Esn3tiAKELvoU5TpXVSkOpZ78cEGn/wXtT2RVqs2vkt4ge6N8cRCyw7YVKhmmLDbwI2pg92mlv7cA== + dependencies: + "@typescript-eslint/scope-manager" "5.15.0" + "@typescript-eslint/type-utils" "5.15.0" + "@typescript-eslint/utils" "5.15.0" + debug "^4.3.2" + functional-red-black-tree "^1.0.1" + ignore "^5.1.8" + regexpp "^3.2.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@^5.0.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.15.0.tgz#407bbbdf1d11d24de81cfdf556b3a9f4252ba4ae" + integrity sha512-AJOOaBrVqKYWaYDBtgMi9XVDB3YHXlffto/3A4VQ39VVaNqosSOp/nW09G4N/ej8WlzHQB2jTnSfP5wWsXSQJA== + dependencies: + "@typescript-eslint/utils" "5.15.0" + +"@typescript-eslint/parser@^5.15.0", "@typescript-eslint/parser@^5.5.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.15.0.tgz#95f603f8fe6eca7952a99bfeef9b85992972e728" + integrity sha512-NGAYP/+RDM2sVfmKiKOCgJYPstAO40vPAgACoWPO/+yoYKSgAXIFaBKsV8P0Cc7fwKgvj27SjRNX4L7f4/jCKQ== + dependencies: + "@typescript-eslint/scope-manager" "5.15.0" + "@typescript-eslint/types" "5.15.0" + "@typescript-eslint/typescript-estree" "5.15.0" + debug "^4.3.2" + +"@typescript-eslint/scope-manager@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.15.0.tgz#d97afab5e0abf4018d1289bd711be21676cdd0ee" + integrity sha512-EFiZcSKrHh4kWk0pZaa+YNJosvKE50EnmN4IfgjkA3bTHElPtYcd2U37QQkNTqwMCS7LXeDeZzEqnsOH8chjSg== + dependencies: + "@typescript-eslint/types" "5.15.0" + "@typescript-eslint/visitor-keys" "5.15.0" + +"@typescript-eslint/type-utils@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.15.0.tgz#d2c02eb2bdf54d0a645ba3a173ceda78346cf248" + integrity sha512-KGeDoEQ7gHieLydujGEFLyLofipe9PIzfvA/41urz4hv+xVxPEbmMQonKSynZ0Ks2xDhJQ4VYjB3DnRiywvKDA== + dependencies: + "@typescript-eslint/utils" "5.15.0" + debug "^4.3.2" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.15.0.tgz#c7bdd103843b1abae97b5518219d3e2a0d79a501" + integrity sha512-yEiTN4MDy23vvsIksrShjNwQl2vl6kJeG9YkVJXjXZnkJElzVK8nfPsWKYxcsGWG8GhurYXP4/KGj3aZAxbeOA== + +"@typescript-eslint/typescript-estree@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.15.0.tgz#81513a742a9c657587ad1ddbca88e76c6efb0aac" + integrity sha512-Hb0e3dGc35b75xLzixM3cSbG1sSbrTBQDfIScqdyvrfJZVEi4XWAT+UL/HMxEdrJNB8Yk28SKxPLtAhfCbBInA== + dependencies: + "@typescript-eslint/types" "5.15.0" + "@typescript-eslint/visitor-keys" "5.15.0" + debug "^4.3.2" + globby "^11.0.4" + is-glob "^4.0.3" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.15.0", "@typescript-eslint/utils@^5.13.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.15.0.tgz#468510a0974d3ced8342f37e6c662778c277f136" + integrity sha512-081rWu2IPKOgTOhHUk/QfxuFog8m4wxW43sXNOMSCdh578tGJ1PAaWPsj42LOa7pguh173tNlMigsbrHvh/mtA== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.15.0" + "@typescript-eslint/types" "5.15.0" + "@typescript-eslint/typescript-estree" "5.15.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/visitor-keys@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.15.0.tgz#5669739fbf516df060f978be6a6dce75855a8027" + integrity sha512-+vX5FKtgvyHbmIJdxMJ2jKm9z2BIlXJiuewI8dsDYMp5LzPUcuTT78Ya5iwvQg3VqSVdmxyM8Anj1Jeq7733ZQ== + dependencies: + "@typescript-eslint/types" "5.15.0" + eslint-visitor-keys "^3.0.0" + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +abortcontroller-polyfill@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5" + integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-node@^1.6.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" + integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== + dependencies: + acorn "^7.0.0" + acorn-walk "^7.0.0" + xtend "^4.0.2" + +acorn-walk@^7.0.0, acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn@^7.0.0, acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.0: + version "8.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" + integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== + +address@^1.0.1, address@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + +adjust-sourcemap-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz#fc4a0fd080f7d10471f30a7320f25560ade28c99" + integrity sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A== + dependencies: + loader-utils "^2.0.0" + regex-parser "^2.2.11" + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.6.0, ajv@^8.8.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" + integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-escapes@^4.2.1, ansi-escapes@^4.3.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3, anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.1.tgz#eb0c9a8f77786cad2af8ff2b862899842d7b6adb" + integrity sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +aria-query@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" + integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== + dependencies: + "@babel/runtime" "^7.10.2" + "@babel/runtime-corejs3" "^7.10.2" + +aria-query@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.0.tgz#210c21aaf469613ee8c9a62c7f86525e058db52c" + integrity sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-includes@^3.1.3, array-includes@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" + integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + get-intrinsic "^1.1.1" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.flat@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" + integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + +array.prototype.flatmap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446" + integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.19.0" + +asap@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= + +async@^2.6.2: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + +async@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9" + integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +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== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@^10.0.2, autoprefixer@^10.4.2: + version "10.4.4" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.4.tgz#3e85a245b32da876a893d3ac2ea19f01e7ea5a1e" + integrity sha512-Tm8JxsB286VweiZ5F0anmbyGiNI3v3wGv3mz9W+cxEDYB/6jbnj6GM9H9mK3wIL8ftgl+C07Lcwb8PG5PCCPzA== + dependencies: + browserslist "^4.20.2" + caniuse-lite "^1.0.30001317" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +axe-core@^4.3.5: + version "4.4.1" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.1.tgz#7dbdc25989298f9ad006645cd396782443757413" + integrity sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw== + +axobject-query@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" + integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== + +babel-eslint@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" + integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" + +babel-jest@^27.4.2, babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== + dependencies: + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-loader@^8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d" + integrity sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw== + dependencies: + find-cache-dir "^3.3.1" + loader-utils "^1.4.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-emotion@^10.0.27: + version "10.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.2.2.tgz#a1fe3503cff80abfd0bdda14abd2e8e57a79d17d" + integrity sha512-SMSkGoqTbTyUTDeuVuPIWifPdUGkTk1Kf9BWRiXIOIcuyMfsdp2EjeiiFvOzX8NOBvEh/ypKYvUh2rkgAJMCLA== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@emotion/hash" "0.8.0" + "@emotion/memoize" "0.7.4" + "@emotion/serialize" "^0.11.16" + babel-plugin-macros "^2.0.0" + babel-plugin-syntax-jsx "^6.18.0" + convert-source-map "^1.5.0" + escape-string-regexp "^1.0.5" + find-root "^1.1.0" + source-map "^0.5.7" + +babel-plugin-import@^1.13.3: + version "1.13.3" + resolved "https://registry.yarnpkg.com/babel-plugin-import/-/babel-plugin-import-1.13.3.tgz#9dbbba7d1ac72bd412917a830d445e00941d26d7" + integrity sha512-1qCWdljJOrDRH/ybaCZuDgySii4yYrtQ8OJQwrcDqdt0y67N30ng3X3nABg6j7gR7qUJgcMa9OMhc4AGViDwWw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/runtime" "^7.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + +babel-plugin-macros@^2.0.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" + integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== + dependencies: + "@babel/runtime" "^7.7.2" + cosmiconfig "^6.0.0" + resolve "^1.12.0" + +babel-plugin-macros@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + +babel-plugin-named-asset-import@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz#6b7fa43c59229685368683c28bc9734f24524cc2" + integrity sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q== + +babel-plugin-polyfill-corejs2@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" + integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.3.1" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" + integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + core-js-compat "^3.21.0" + +babel-plugin-polyfill-regenerator@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" + integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + +"babel-plugin-styled-components@>= 1.12.0": + version "2.0.6" + resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.6.tgz#6f76c7f7224b7af7edc24a4910351948c691fc90" + integrity sha512-Sk+7o/oa2HfHv3Eh8sxoz75/fFvEdHsXV4grdeHufX0nauCmymlnN0rGhIvfpMQSJMvGutJ85gvCGea4iqmDpg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-module-imports" "^7.16.0" + babel-plugin-syntax-jsx "^6.18.0" + lodash "^4.17.11" + picomatch "^2.3.0" + +babel-plugin-syntax-jsx@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= + +babel-plugin-transform-react-remove-prop-types@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" + integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@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-top-level-await" "^7.8.3" + +babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== + dependencies: + babel-plugin-jest-hoist "^27.5.1" + babel-preset-current-node-syntax "^1.0.0" + +babel-preset-react-app@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz#ed6005a20a24f2c88521809fa9aea99903751584" + integrity sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg== + dependencies: + "@babel/core" "^7.16.0" + "@babel/plugin-proposal-class-properties" "^7.16.0" + "@babel/plugin-proposal-decorators" "^7.16.4" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.0" + "@babel/plugin-proposal-numeric-separator" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.0" + "@babel/plugin-proposal-private-methods" "^7.16.0" + "@babel/plugin-transform-flow-strip-types" "^7.16.0" + "@babel/plugin-transform-react-display-name" "^7.16.0" + "@babel/plugin-transform-runtime" "^7.16.4" + "@babel/preset-env" "^7.16.4" + "@babel/preset-react" "^7.16.0" + "@babel/preset-typescript" "^7.16.0" + "@babel/runtime" "^7.16.3" + babel-plugin-macros "^3.1.0" + babel-plugin-transform-react-remove-prop-types "^0.4.24" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bfj@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.0.2.tgz#1988ce76f3add9ac2913fd8ba47aad9e651bfbb2" + integrity sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw== + dependencies: + bluebird "^3.5.5" + check-types "^11.1.1" + hoopy "^0.1.4" + tryer "^1.0.1" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +body-parser@1.19.2: + version "1.19.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" + integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.7" + raw-body "2.4.3" + type-is "~1.6.18" + +body-scroll-lock@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz#c1392d9217ed2c3e237fee1e910f6cdd80b7aaec" + integrity sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg== + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +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, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browser-tabs-lock@^1.2.15: + version "1.2.15" + resolved "https://registry.yarnpkg.com/browser-tabs-lock/-/browser-tabs-lock-1.2.15.tgz#d5012e652e2a0cb4eba471b0a2300c2fa5d92788" + integrity sha512-J8K9vdivK0Di+b8SBdE7EZxDr88TnATing7XoLw6+nFkXMQ6sVBh92K3NQvZlZU91AIkFRi0w3sztk5Z+vsswA== + dependencies: + lodash ">=4.17.21" + +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1, browserslist@^4.19.1, browserslist@^4.19.3, browserslist@^4.20.2: + version "4.20.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" + integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== + dependencies: + caniuse-lite "^1.0.30001317" + electron-to-chromium "^1.4.84" + escalade "^3.1.1" + node-releases "^2.0.2" + picocolors "^1.0.0" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +builtin-modules@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" + integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +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== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0, camelcase@^6.2.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +camelize@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" + integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001317: + version "1.0.30001317" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001317.tgz#0548fb28fd5bc259a70b8c1ffdbe598037666a1b" + integrity sha512-xIZLh8gBm4dqNX0gkzrBeyI86J2eCjWzYAs40q88smG844YIrN4tVQl/RhquHvKEKImWWFIVh1Lxe5n1G/N+GQ== + +case-sensitive-paths-webpack-plugin@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== + +chalk@^2.0.0, chalk@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +char-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-2.0.1.tgz#6dafdb25f9d3349914079f010ba8d0e6ff9cd01e" + integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw== + +charcodes@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/charcodes/-/charcodes-0.2.0.tgz#5208d327e6cc05f99eb80ffc814707572d1f14e4" + integrity sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ== + +check-types@^11.1.1: + version "11.1.2" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.1.2.tgz#86a7c12bf5539f6324eb0e70ca8896c0e38f3e2f" + integrity sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ== + +chokidar@^3.4.2, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== + +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + +classnames@^2.2.5: + version "2.3.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + +clean-css@^5.2.2: + version "5.2.4" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.2.4.tgz#982b058f8581adb2ae062520808fb2429bd487a4" + integrity sha512-nKseG8wCzEuji/4yrgM/5cthL9oTDc5UOQyFMvW/Q53oP6gLH690o1NbuTh6Y18nujr7BxlsFuS7gXLnLzKJGg== + dependencies: + source-map "~0.6.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clsx@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" + integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.1.4, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colord@^2.9.1: + version "2.9.2" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.2.tgz#25e2bacbbaa65991422c07ea209e2089428effb1" + integrity sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ== + +colorette@^2.0.10: + version "2.0.16" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +common-path-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" + integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== + +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" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +confusing-browser-globals@^1.0.10, confusing-browser-globals@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" + integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +core-js-compat@^3.20.2, core-js-compat@^3.21.0: + version "3.21.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.1.tgz#cac369f67c8d134ff8f9bd1623e3bc2c42068c82" + integrity sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g== + dependencies: + browserslist "^4.19.1" + semver "7.0.0" + +core-js-pure@^3.20.2, core-js-pure@^3.8.1: + version "3.21.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51" + integrity sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ== + +core-js@^3.19.2, core-js@^3.20.3: + version "3.21.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.21.1.tgz#f2e0ddc1fc43da6f904706e8e955bc19d06a0d94" + integrity sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + +cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cross-fetch@^3.0.4: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== + dependencies: + node-fetch "2.6.7" + +cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +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-blank-pseudo@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz#36523b01c12a25d812df343a32c322d2a2324561" + integrity sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ== + dependencies: + postcss-selector-parser "^6.0.9" + +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" + integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU= + +css-declaration-sorter@^6.0.3: + version "6.1.4" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.1.4.tgz#b9bfb4ed9a41f8dcca9bf7184d849ea94a8294b4" + integrity sha512-lpfkqS0fctcmZotJGhnxkIyJWvBXgpyi2wsFd4J8VB7wzyrT6Ch/3Q+FMNJpjK4gu1+GN5khOnpU2ZVKrLbhCw== + dependencies: + timsort "^0.3.0" + +css-has-pseudo@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz#57f6be91ca242d5c9020ee3e51bbb5b89fc7af73" + integrity sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw== + dependencies: + postcss-selector-parser "^6.0.9" + +css-loader@^6.5.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" + integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.7" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.5" + +css-minimizer-webpack-plugin@^3.2.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz#ab78f781ced9181992fe7b6e4f3422e76429878f" + integrity sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q== + dependencies: + cssnano "^5.0.6" + jest-worker "^27.0.2" + postcss "^8.3.5" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + +css-prefers-color-scheme@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz#ca8a22e5992c10a5b9d315155e7caee625903349" + integrity sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA== + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-select@^4.1.3: + version "4.2.1" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd" + integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ== + dependencies: + boolbase "^1.0.0" + css-what "^5.1.0" + domhandler "^4.3.0" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-to-react-native@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756" + integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ== + dependencies: + camelize "^1.0.0" + css-color-keywords "^1.0.0" + postcss-value-parser "^4.0.2" + +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-unit-converter@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" + integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== + +css-what@^3.2.1: + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" + integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== + +css-what@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" + integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== + +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= + +css@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" + integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== + dependencies: + inherits "^2.0.4" + source-map "^0.6.1" + source-map-resolve "^0.6.0" + +cssdb@^6.4.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-6.5.0.tgz#61264b71f29c834f09b59cb3e5b43c8226590122" + integrity sha512-Rh7AAopF2ckPXe/VBcoUS9JrCZNSyc60+KpgE6X25vpVxA32TmiqvExjkfhwP4wGSb6Xe8Z/JIyGqwgx/zZYFA== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^*: + version "5.2.4" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.4.tgz#eced79bbc1ab7270337c4038a21891daac2329bc" + integrity sha512-w1Gg8xsebln6/axZ6qDFQHuglrGfbIHOIx0g4y9+etRlRab8CGpSpe6UMsrgJe4zhCaJ0LwLmc+PhdLRTwnhIA== + dependencies: + css-declaration-sorter "^6.0.3" + cssnano-utils "^*" + postcss-calc "^8.2.3" + postcss-colormin "^*" + postcss-convert-values "^*" + postcss-discard-comments "^*" + postcss-discard-duplicates "^*" + postcss-discard-empty "^*" + postcss-discard-overridden "^*" + postcss-merge-longhand "^*" + postcss-merge-rules "^*" + postcss-minify-font-values "^*" + postcss-minify-gradients "^*" + postcss-minify-params "^*" + postcss-minify-selectors "^*" + postcss-normalize-charset "^*" + postcss-normalize-display-values "^*" + postcss-normalize-positions "^*" + postcss-normalize-repeat-style "^*" + postcss-normalize-string "^*" + postcss-normalize-timing-functions "^*" + postcss-normalize-unicode "^*" + postcss-normalize-url "^*" + postcss-normalize-whitespace "^*" + postcss-ordered-values "^*" + postcss-reduce-initial "^*" + postcss-reduce-transforms "^*" + postcss-svgo "^*" + postcss-unique-selectors "^*" + +cssnano-utils@^*, cssnano-utils@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" + integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== + +cssnano@^5.0.6: + version "5.1.4" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.4.tgz#c648192e8e2f1aacb7d839e6aa3706b50cc7f8e4" + integrity sha512-hbfhVZreEPyzl+NbvRsjNo54JOX80b+j6nqG2biLVLaZHJEiqGyMh4xDGHtwhUKd5p59mj2GlDqlUBwJUuIu5A== + dependencies: + cssnano-preset-default "^*" + lilconfig "^2.0.3" + yaml "^1.10.2" + +csso@^4.0.2, csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +csstype@^2.5.7: + version "2.6.20" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda" + integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA== + +csstype@^3.0.2: + version "3.0.11" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33" + integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw== + +"d3-array@2 - 3", "d3-array@2.10.0 - 3": + version "3.2.0" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.0.tgz#15bf96cd9b7333e02eb8de8053d78962eafcff14" + integrity sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g== + dependencies: + internmap "1 - 2" + +"d3-color@1 - 3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + +"d3-format@1 - 3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== + +"d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + +"d3-path@1 - 3": + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.0.1.tgz#f09dec0aaffd770b7995f1a399152bf93052321e" + integrity sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w== + +d3-scale@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== + dependencies: + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" + +d3-shape@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.1.0.tgz#c8a495652d83ea6f524e482fca57aa3f8bc32556" + integrity sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ== + dependencies: + d3-path "1 - 3" + +"d3-time-format@2 - 4": + version "4.1.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + +"d3-time@1 - 3", "d3-time@2.1.1 - 3": + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.0.0.tgz#65972cb98ae2d4954ef5c932e8704061335d4975" + integrity sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ== + dependencies: + d3-array "2 - 3" + +damerau-levenshtein@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" + integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== + +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + +debug@2.6.9, debug@^2.6.0, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +debug@^3.1.1, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decimal.js-light@^2.4.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" + integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== + +decimal.js@^10.2.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-is@^0.1.3, deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + +del@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" + integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== + dependencies: + globby "^11.0.1" + graceful-fs "^4.2.4" + is-glob "^4.0.1" + is-path-cwd "^2.2.0" + is-path-inside "^3.0.2" + p-map "^4.0.0" + rimraf "^3.0.2" + slash "^3.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +detect-port-alt@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" + integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +detective@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b" + integrity sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg== + dependencies: + acorn-node "^1.6.1" + defined "^1.0.0" + minimist "^1.1.1" + +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: + version "0.5.13" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz#102ee5f25eacce09bdf1cfa5a298f86da473be4b" + integrity sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw== + +dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-helpers@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + +dom-helpers@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" + integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== + dependencies: + "@babel/runtime" "^7.8.7" + csstype "^3.0.2" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626" + integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g== + dependencies: + domelementtype "^2.2.0" + +domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== + +duplexer@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +ee-first@1.1.1: + version "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.7" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.7.tgz#c544d9c7f715783dd92f0bddcf73a59e6962d006" + integrity sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw== + dependencies: + jake "^10.8.5" + +electron-to-chromium@^1.4.84: + version "1.4.85" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.85.tgz#a3666ba42147026b9f34d4d8d4caf0740e80f751" + integrity sha512-K9AsQ41WS2bjZUFpRWfvaS4RjEcRCamEkBJN1Z1TQILBfP1H8QnJ9ti0wiLiMv0sRjX3EHKzgs9jDnmGFx2jXg== + +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +enhanced-resolve@^5.9.2: + version "5.9.2" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz#0224dcd6a43389ebfb2d55efee517e5466772dd9" + integrity sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +error-stack-parser@^2.0.6: + version "2.0.7" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.7.tgz#b0c6e2ce27d0495cf78ad98715e0cad1219abb57" + integrity sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA== + dependencies: + stackframe "^1.1.1" + +es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-cookie@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/es-cookie/-/es-cookie-1.3.2.tgz#80e831597f72a25721701bdcb21d990319acd831" + integrity sha512-UTlYYhXGLOy05P/vKVT2Ui7WtC7NiRzGtJyAKKn32g5Gvcjn7KAClLPWlipCtxIus934dFg9o9jXiBL0nP+t9Q== + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +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" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-config-airbnb-base@^14.2.1: + version "14.2.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" + integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== + dependencies: + confusing-browser-globals "^1.0.10" + object.assign "^4.1.2" + object.entries "^1.1.2" + +eslint-config-airbnb-base@^15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" + integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== + dependencies: + confusing-browser-globals "^1.0.10" + object.assign "^4.1.2" + object.entries "^1.1.5" + semver "^6.3.0" + +eslint-config-airbnb@^18.2.0: + version "18.2.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz#b7fe2b42f9f8173e825b73c8014b592e449c98d9" + integrity sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg== + dependencies: + eslint-config-airbnb-base "^14.2.1" + object.assign "^4.1.2" + object.entries "^1.1.2" + +eslint-config-airbnb@^19.0.4: + version "19.0.4" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz#84d4c3490ad70a0ffa571138ebcdea6ab085fdc3" + integrity sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew== + dependencies: + eslint-config-airbnb-base "^15.0.0" + object.assign "^4.1.2" + object.entries "^1.1.5" + +eslint-config-prettier@^8.1.0, eslint-config-prettier@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== + +eslint-config-react-app@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-7.0.0.tgz#0fa96d5ec1dfb99c029b1554362ab3fa1c3757df" + integrity sha512-xyymoxtIt1EOsSaGag+/jmcywRuieQoA2JbPCjnw9HukFj9/97aGPoZVFioaotzk1K5Qt9sHO5EutZbkrAXS0g== + dependencies: + "@babel/core" "^7.16.0" + "@babel/eslint-parser" "^7.16.3" + "@rushstack/eslint-patch" "^1.1.0" + "@typescript-eslint/eslint-plugin" "^5.5.0" + "@typescript-eslint/parser" "^5.5.0" + babel-preset-react-app "^10.0.1" + confusing-browser-globals "^1.0.11" + eslint-plugin-flowtype "^8.0.3" + eslint-plugin-import "^2.25.3" + eslint-plugin-jest "^25.3.0" + eslint-plugin-jsx-a11y "^6.5.1" + eslint-plugin-react "^7.27.1" + eslint-plugin-react-hooks "^4.3.0" + eslint-plugin-testing-library "^5.0.1" + +eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== + dependencies: + debug "^3.2.7" + resolve "^1.20.0" + +eslint-import-resolver-typescript@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.5.0.tgz#07661966b272d14ba97f597b51e1a588f9722f0a" + integrity sha512-qZ6e5CFr+I7K4VVhQu3M/9xGv9/YmwsEXrsm3nimw8vWaVHRDrQRp26BgCypTxBp3vUp4o5aVEJRiy0F2DFddQ== + dependencies: + debug "^4.3.1" + glob "^7.1.7" + is-glob "^4.0.1" + resolve "^1.20.0" + tsconfig-paths "^3.9.0" + +eslint-module-utils@^2.7.2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz#ad7e3a10552fdd0642e1e55292781bd6e34876ee" + integrity sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ== + dependencies: + debug "^3.2.7" + find-up "^2.1.0" + +eslint-plugin-flowtype@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz#e1557e37118f24734aa3122e7536a038d34a4912" + integrity sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ== + dependencies: + lodash "^4.17.21" + string-natural-compare "^3.0.1" + +eslint-plugin-import@^2.25.3, eslint-plugin-import@^2.25.4: + version "2.25.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz#322f3f916a4e9e991ac7af32032c25ce313209f1" + integrity sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA== + dependencies: + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" + debug "^2.6.9" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.2" + has "^1.0.3" + is-core-module "^2.8.0" + is-glob "^4.0.3" + minimatch "^3.0.4" + object.values "^1.1.5" + resolve "^1.20.0" + tsconfig-paths "^3.12.0" + +eslint-plugin-jest@^25.3.0: + version "25.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz#ff4ac97520b53a96187bad9c9814e7d00de09a6a" + integrity sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ== + dependencies: + "@typescript-eslint/experimental-utils" "^5.0.0" + +eslint-plugin-jsx-a11y@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz#cdbf2df901040ca140b6ec14715c988889c2a6d8" + integrity sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g== + dependencies: + "@babel/runtime" "^7.16.3" + aria-query "^4.2.2" + array-includes "^3.1.4" + ast-types-flow "^0.0.7" + axe-core "^4.3.5" + axobject-query "^2.2.0" + damerau-levenshtein "^1.0.7" + emoji-regex "^9.2.2" + has "^1.0.3" + jsx-ast-utils "^3.2.1" + language-tags "^1.0.5" + minimatch "^3.0.4" + +eslint-plugin-prettier@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz#8b99d1e4b8b24a762472b4567992023619cb98e0" + integrity sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-react-hooks@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172" + integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA== + +eslint-plugin-react@^7.27.1, eslint-plugin-react@^7.29.4: + version "7.29.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz#4717de5227f55f3801a5fd51a16a4fa22b5914d2" + integrity sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ== + dependencies: + array-includes "^3.1.4" + array.prototype.flatmap "^1.2.5" + doctrine "^2.1.0" + estraverse "^5.3.0" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.5" + object.fromentries "^2.0.5" + object.hasown "^1.1.0" + object.values "^1.1.5" + prop-types "^15.8.1" + resolve "^2.0.0-next.3" + semver "^6.3.0" + string.prototype.matchall "^4.0.6" + +eslint-plugin-simple-import-sort@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz#a1dad262f46d2184a90095a60c66fef74727f0f8" + integrity sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw== + +eslint-plugin-testing-library@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.1.0.tgz#6ad539a53d4e897d3045902f8e534e07cebd4e8b" + integrity sha512-YSNzasJUbyhOTe14ZPygeOBvcPvcaNkwHwrj4vdf+uirr2D32JTDaKi6CP5Os2aWtOcvt4uBSPXp9h5xGoqvWQ== + dependencies: + "@typescript-eslint/utils" "^5.13.0" + +eslint-scope@5.1.1, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + +eslint-webpack-plugin@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-3.1.1.tgz#83dad2395e5f572d6f4d919eedaa9cf902890fcb" + integrity sha512-xSucskTN9tOkfW7so4EaiFIkulWLXwCB/15H917lR6pTv0Zot6/fetFucmENRb7J5whVSFKIvwnrnsa78SG2yg== + dependencies: + "@types/eslint" "^7.28.2" + jest-worker "^27.3.1" + micromatch "^4.0.4" + normalize-path "^3.0.0" + schema-utils "^3.1.1" + +eslint@^8.11.0, eslint@^8.3.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.11.0.tgz#88b91cfba1356fc10bb9eb592958457dfe09fb37" + integrity sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA== + dependencies: + "@eslint/eslintrc" "^1.2.1" + "@humanwhocodes/config-array" "^0.9.2" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^6.0.1" + globals "^13.6.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + regexpp "^3.2.0" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd" + integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ== + dependencies: + acorn "^8.7.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.3.0" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: + version "5.3.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" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^4.0.0, eventemitter3@^4.0.1: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exenv@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" + integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50= + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== + dependencies: + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + +express@^4.17.1: + version "4.17.3" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" + integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.19.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.4.2" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.9.7" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-equals@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-2.0.4.tgz#3add9410585e2d7364c2deeb6a707beadb24b927" + integrity sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w== + +fast-glob@^3.2.11, fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +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== + +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-text-encoding@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz#ec02ac8e01ab8a319af182dae2681213cfe9ce53" + integrity sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig== + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +filelist@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.3.tgz#448607750376484932f67ef1b9ff07386b036c83" + integrity sha512-LwjCsruLWQULGYKy7TX0OPtrL9kLpojOFKc5VCTxdFTV7w5zbsgqVKfnkKG7Qgjtq50gKfO56hJv88OfcGb70Q== + dependencies: + minimatch "^5.0.1" + +filesize@^8.0.6: + version "8.0.7" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8" + integrity sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.5" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== + +follow-redirects@^1.0.0: + version "1.14.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" + integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== + +fork-ts-checker-webpack-plugin@^6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.0.tgz#0282b335fa495a97e167f69018f566ea7d2a2b5e" + integrity sha512-cS178Y+xxtIjEUorcHddKS7yCMlrDPV31mt47blKKRfMd70Kxu5xruAFE2o9sDY6wVC5deuob/u/alD04YYHnw== + dependencies: + "@babel/code-frame" "^7.8.3" + "@types/json-schema" "^7.0.5" + chalk "^4.1.0" + chokidar "^3.4.2" + cosmiconfig "^6.0.0" + deepmerge "^4.2.2" + fs-extra "^9.0.0" + glob "^7.1.6" + memfs "^3.1.2" + minimatch "^3.0.4" + schema-utils "2.7.0" + semver "^7.3.2" + tapable "^1.0.0" + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-extra@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8" + integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^9.0.0, 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.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^2.3.2, fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +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== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +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== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +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-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.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, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1, glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +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== + +globals@^13.6.0, globals@^13.9.0: + version "13.13.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b" + integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.1, globby@^11.0.4: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, 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== + +gzip-size@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== + dependencies: + duplexer "^0.1.2" + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +harmony-reflect@^1.4.6: + version "1.6.2" + resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.2.tgz#31ecbd32e648a34d030d86adb67d4d47547fe710" + integrity sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g== + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + 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" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +history@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b" + integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ== + dependencies: + "@babel/runtime" "^7.7.6" + +hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + +html-entities@^2.1.0, html-entities@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" + integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== + dependencies: + camel-case "^4.1.2" + clean-css "^5.2.2" + commander "^8.3.0" + he "^1.2.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.10.0" + +html-webpack-plugin@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" + integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== + dependencies: + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.6.tgz#2e02406ab2df8af8a7abfba62e0da01c62b95afd" + integrity sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA== + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +http-proxy-middleware@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz#03af0f4676d172ae775cb5c33f592f40e1a4e07a" + integrity sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +idb@^6.1.4: + version "6.1.5" + resolved "https://registry.yarnpkg.com/idb/-/idb-6.1.5.tgz#dbc53e7adf1ac7c59f9b2bf56e00b4ea4fce8c7b" + integrity sha512-IJtugpKkiVXQn5Y+LteyBCNk1N8xpGV3wWZk9EVtZWH8DYkjBn0bX1XnGP9RkyZF0sAcywa6unHqSWKe7q4LGw== + +identity-obj-proxy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" + integrity sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ= + dependencies: + harmony-reflect "^1.4.6" + +ignore@^5.1.8, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +immer@^9.0.7: + version "9.0.12" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.12.tgz#2d33ddf3ee1d247deab9d707ca472c8c942a0f20" + integrity sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA== + +import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.5: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + +ip@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1: + version "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== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +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-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +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.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-core-module@^2.2.0, is-core-module@^2.8.0, is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + 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-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= + +is-negative-zero@^2.0.1: + 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.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + 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 sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-path-cwd@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-regex@^1.0.4, 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 sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + +is-root@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + +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-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-weakref@^1.0.1: + 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" + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.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= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jake@^10.8.5: + version "10.8.5" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" + integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.1" + minimatch "^3.0.4" + +jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== + dependencies: + "@jest/types" "^27.5.1" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + +jest-cli@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== + dependencies: + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + prompts "^2.0.1" + yargs "^16.2.0" + +jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== + dependencies: + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== + dependencies: + detect-newline "^3.0.0" + +jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + +jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jsdom "^16.6.0" + +jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +jest-fetch-mock@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz#31749c456ae27b8919d69824f1c2bd85fe0a1f3b" + integrity sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw== + dependencies: + cross-fetch "^3.0.4" + promise-polyfill "^8.1.3" + +jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== + +jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== + dependencies: + "@jest/types" "^27.5.1" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + throat "^6.0.1" + +jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== + dependencies: + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.5.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^27.0.0, jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== + +jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== + dependencies: + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" + +jest-resolve@^27.4.2, jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + source-map-support "^0.5.6" + throat "^6.0.1" + +jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.9" + +jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + natural-compare "^1.4.0" + pretty-format "^27.5.1" + semver "^7.3.2" + +jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== + dependencies: + "@jest/types" "^27.5.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.5.1" + leven "^3.1.0" + pretty-format "^27.5.1" + +jest-watch-typeahead@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-1.0.0.tgz#4de2ca1eb596acb1889752afbab84b74fcd99173" + integrity sha512-jxoszalAb394WElmiJTFBMzie/RDCF+W7Q29n5LzOPtcoQoHWfdUtHFkbhgf5NwWe8uMOxvKb/g7ea7CshfkTw== + dependencies: + ansi-escapes "^4.3.1" + chalk "^4.0.0" + jest-regex-util "^27.0.0" + jest-watcher "^27.0.0" + slash "^4.0.0" + string-length "^5.0.1" + strip-ansi "^7.0.1" + +jest-watcher@^27.0.0, jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== + dependencies: + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.5.1" + string-length "^4.0.1" + +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.0.2, jest-worker@^27.3.1, jest-worker@^27.4.5, jest-worker@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^27.4.3: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" + integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== + dependencies: + "@jest/core" "^27.5.1" + import-local "^3.0.2" + jest-cli "^27.5.1" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsdom@^16.6.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.6" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "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== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2, json5@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +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.0" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.0.tgz#f802669a524ec4805fa7389eadbc9921d5dc8072" + integrity sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg== + +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b" + integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA== + dependencies: + array-includes "^3.1.3" + object.assign "^4.1.2" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +klona@^2.0.4, klona@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" + integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== + +language-subtag-registry@~0.3.2: + version "0.3.21" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a" + integrity sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg== + +language-tags@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" + integrity sha1-0yHbxNowuovzAk4ED6XBRmH5GTo= + dependencies: + language-subtag-registry "~0.3.2" + +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== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lilconfig@^2.0.3, lilconfig@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.4.tgz#f4507d043d7058b380b6a8f5cb7bcd4b34cee082" + integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +loader-runner@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + +loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" + integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +loader-utils@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.0.tgz#bcecc51a7898bee7473d4bc6b845b23af8304d4f" + integrity sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ== + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +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.mapvalues@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" + integrity sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ== + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.pickby@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.pickby/-/lodash.pickby-4.6.0.tgz#7dea21d8c18d7703a27c704c15d3b84a67e33aff" + integrity sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q== + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash@>=4.17.21, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lz-string@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" + integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= + +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.0, 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" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memfs@^3.1.2, memfs@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" + integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw== + dependencies: + fs-monkey "1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +min-indent@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + +mini-css-extract-plugin@^2.4.5: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz#578aebc7fc14d32c0ad304c2c34f08af44673f5e" + integrity sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w== + dependencies: + schema-utils "^4.0.0" + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^3.0.4, 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.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + +mkdirp@^0.5.5, mkdirp@~0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mobx-persist-store@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/mobx-persist-store/-/mobx-persist-store-1.0.6.tgz#23e45332f638945d147e7158d0761843616a75cb" + integrity sha512-GOV1/0H2bMQhsJKpwRrR74c+B7wl9sOSwMeq7ed1PPsIanW/aYVj0RaQDqVOTYKJfeLV9wNGnWk0EATWprNluw== + +mobx-react-lite@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.3.0.tgz#7174e807201943beff6f9d3701492314c9fc0db3" + integrity sha512-U/kMSFtV/bNVgY01FuiGWpRkaQVHozBq5CEBZltFvPt4FcV111hEWkgwqVg9GPPZSEuEdV438PEz8mk8mKpYlA== + +mobx@^6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.4.2.tgz#d25cd358a46b7a8fe2d8299259bc71008a2aa5b3" + integrity sha512-b4xQJYiH8sb0sEbfq/Ws3N77DEJtSihUFD1moeiz2jNoJ5B+mqJutt54ouO9iEfkp7Wk4jQDsVUOh7DPEW3wEw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +nanoid@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +node-forge@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-releases@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" + integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +nth-check@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" + integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== + dependencies: + boolbase "^1.0.0" + +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-hash@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" + integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== + +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +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" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.0, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.entries@^1.1.2, object.entries@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" + integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.fromentries@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" + integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.getownpropertydescriptors@^2.1.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" + integrity sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.hasown@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5" + integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.values@^1.1.0, object.values@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" + integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9, open@^8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-retry@^4.5.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" + integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== + dependencies: + "@types/retry" "^0.12.0" + retry "^0.13.1" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0, parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6, path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +pkg-dir@^4.1.0, pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + +polished@^4.1.0: + version "4.1.4" + resolved "https://registry.yarnpkg.com/polished/-/polished-4.1.4.tgz#640293ba834109614961a700fdacbb6599fb12d0" + integrity sha512-Nq5Mbza+Auo7N3sQb1QMFaQiDO+4UexWuSGR7Cjb4Sw11SZIJcrrFtiZ+L0jT9MBsUsxDboHVASbCLbE1rnECg== + dependencies: + "@babel/runtime" "^7.16.7" + +portfinder@^1.0.28: + version "1.0.28" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.5" + +postcss-attribute-case-insensitive@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.0.tgz#39cbf6babf3ded1e4abf37d09d6eda21c644105c" + integrity sha512-b4g9eagFGq9T5SWX4+USfVyjIb3liPnjhHHRMP7FMB2kFVpYyfEscV0wP3eaXhKlcHKUut8lt5BGoeylWA/dBQ== + dependencies: + postcss-selector-parser "^6.0.2" + +postcss-browser-comments@^4: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz#bcfc86134df5807f5d3c0eefa191d42136b5e72a" + integrity sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg== + +postcss-calc@^8.2.3: + version "8.2.4" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" + integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== + dependencies: + postcss-selector-parser "^6.0.9" + postcss-value-parser "^4.2.0" + +postcss-color-functional-notation@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.2.tgz#f59ccaeb4ee78f1b32987d43df146109cc743073" + integrity sha512-DXVtwUhIk4f49KK5EGuEdgx4Gnyj6+t2jBSEmxvpIK9QI40tWrpS2Pua8Q7iIZWBrki2QOaeUdEaLPPa91K0RQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-hex-alpha@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.3.tgz#61a0fd151d28b128aa6a8a21a2dad24eebb34d52" + integrity sha512-fESawWJCrBV035DcbKRPAVmy21LpoyiXdPTuHUfWJ14ZRjY7Y7PA6P4g8z6LQGYhU1WAxkTxjIjurXzoe68Glw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-rebeccapurple@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.0.2.tgz#5d397039424a58a9ca628762eb0b88a61a66e079" + integrity sha512-SFc3MaocHaQ6k3oZaFwH8io6MdypkUtEy/eXzXEB1vEQlO3S3oDc/FSZA8AsS04Z25RirQhlDlHLh3dn7XewWw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-colormin@^*: + version "5.3.0" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" + integrity sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.2.0" + +postcss-convert-values@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.0.tgz#f8d3abe40b4ce4b1470702a0706343eac17e7c10" + integrity sha512-GkyPbZEYJiWtQB0KZ0X6qusqFHUepguBCNFi9t5JJc7I2OTXG7C0twbTLvCfaKOLl3rSXmpAwV7W5txd91V84g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-media@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz#1be6aff8be7dc9bf1fe014bde3b71b92bb4552f1" + integrity sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g== + +postcss-custom-properties@^12.1.4: + version "12.1.4" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.4.tgz#e3d8a8000f28094453b836dff5132385f2862285" + integrity sha512-i6AytuTCoDLJkWN/MtAIGriJz3j7UX6bV7Z5t+KgFz+dwZS15/mlTJY1S0kRizlk6ba0V8u8hN50Fz5Nm7tdZw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-selectors@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.0.tgz#022839e41fbf71c47ae6e316cb0e6213012df5ef" + integrity sha512-/1iyBhz/W8jUepjGyu7V1OPcGbc636snN1yXEQCinb6Bwt7KxsiU7/bLQlp8GwAXzCh7cobBU5odNn/2zQWR8Q== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-dir-pseudo-class@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.4.tgz#9afe49ea631f0cb36fa0076e7c2feb4e7e3f049c" + integrity sha512-I8epwGy5ftdzNWEYok9VjW9whC4xnelAtbajGv4adql4FIF09rnrxnA9Y8xSHN47y7gqFIv10C5+ImsLeJpKBw== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-discard-comments@^*: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.1.tgz#e90019e1a0e5b99de05f63516ce640bd0df3d369" + integrity sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ== + +postcss-discard-duplicates@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" + integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== + +postcss-discard-empty@^*: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" + integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== + +postcss-discard-overridden@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" + integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== + +postcss-double-position-gradients@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.1.tgz#a12cfdb7d11fa1a99ccecc747f0c19718fb37152" + integrity sha512-jM+CGkTs4FcG53sMPjrrGE0rIvLDdCrqMzgDC5fLI7JHDO7o6QG8C5TQBtExb13hdBdoH9C2QVbG4jo2y9lErQ== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-env-function@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-4.0.5.tgz#b9614d50abd91e4c88a114644a9766880dabe393" + integrity sha512-gPUJc71ji9XKyl0WSzAalBeEA/89kU+XpffpPxSaaaZ1c48OL36r1Ep5R6+9XAPkIiDlSvVAwP4io12q/vTcvA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-flexbugs-fixes@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz#2028e145313074fc9abe276cb7ca14e5401eb49d" + integrity sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ== + +postcss-focus-visible@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz#50c9ea9afa0ee657fb75635fabad25e18d76bf9e" + integrity sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-focus-within@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz#5b1d2ec603195f3344b716c0b75f61e44e8d2e20" + integrity sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-font-variant@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" + integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== + +postcss-gap-properties@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz#6401bb2f67d9cf255d677042928a70a915e6ba60" + integrity sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ== + +postcss-image-set-function@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-4.0.6.tgz#bcff2794efae778c09441498f40e0c77374870a9" + integrity sha512-KfdC6vg53GC+vPd2+HYzsZ6obmPqOk6HY09kttU19+Gj1nC3S3XBVEXDHxkhxTohgZqzbUb94bKXvKDnYWBm/A== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-initial@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" + integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== + +postcss-js@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.0.tgz#31db79889531b80dc7bc9b0ad283e418dce0ac00" + integrity sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ== + dependencies: + camelcase-css "^2.0.1" + +postcss-lab-function@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.1.2.tgz#b75afe43ba9c1f16bfe9bb12c8109cabd55b5fc2" + integrity sha512-isudf5ldhg4fk16M8viAwAbg6Gv14lVO35N3Z/49NhbwPQ2xbiEoHgrRgpgQojosF4vF7jY653ktB6dDrUOR8Q== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-load-config@^3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.3.tgz#21935b2c43b9a86e6581a576ca7ee1bde2bd1d23" + integrity sha512-5EYgaM9auHGtO//ljHH+v/aC/TQ5LHXtL7bQajNAUBKUVKiYE8rYpFms7+V26D9FncaGe2zwCoPQsFKb5zF/Hw== + dependencies: + lilconfig "^2.0.4" + yaml "^1.10.2" + +postcss-loader@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.1.tgz#0895f7346b1702103d30fdc66e4d494a93c008ef" + integrity sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.5" + semver "^7.3.5" + +postcss-logical@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-5.0.4.tgz#ec75b1ee54421acc04d5921576b7d8db6b0e6f73" + integrity sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g== + +postcss-media-minmax@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz#7140bddec173e2d6d657edbd8554a55794e2a5b5" + integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== + +postcss-merge-longhand@^*: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.2.tgz#fe3002f38ad5827c1d6f7d5bb3f71d2566a2a138" + integrity sha512-18/bp9DZnY1ai9RlahOfLBbmIUKfKFPASxRCiZ1vlpZqWPCn8qWPFlEozqmWL+kBtcEQmG8W9YqGCstDImvp/Q== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^*" + +postcss-merge-rules@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.0.tgz#a2d5117eba09c8686a5471d97bd9afcf30d1b41f" + integrity sha512-NecukEJovQ0mG7h7xV8wbYAkXGTO3MPKnXvuiXzOKcxoOodfTTKYjeo8TMhAswlSkjcPIBlnKbSFcTuVSDaPyQ== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + cssnano-utils "^3.1.0" + postcss-selector-parser "^6.0.5" + +postcss-minify-font-values@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" + integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-minify-gradients@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.0.tgz#de0260a67a13b7b321a8adc3150725f2c6612377" + integrity sha512-J/TMLklkONn3LuL8wCwfwU8zKC1hpS6VcxFkNUNjmVt53uKqrrykR3ov11mdUYyqVMEx67slMce0tE14cE4DTg== + dependencies: + colord "^2.9.1" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-minify-params@^*: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.1.tgz#c5f8e7dac565e577dd99904787fbec576cbdbfb2" + integrity sha512-WCpr+J9Uz8XzMpAfg3UL8z5rde6MifBbh5L8bn8S2F5hq/YDJJzASYCnCHvAB4Fqb94ys8v95ULQkW2EhCFvNg== + dependencies: + browserslist "^4.16.6" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-minify-selectors@^*: + version "5.2.0" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.0.tgz#17c2be233e12b28ffa8a421a02fc8b839825536c" + integrity sha512-vYxvHkW+iULstA+ctVNx0VoRAR4THQQRkG77o0oa4/mBS0OzGvvzLIvHDv/nNEM0crzN2WIyFU5X7wZhaUK3RA== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-nested@5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.6.tgz#466343f7fc8d3d46af3e7dba3fcd47d052a945bc" + integrity sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA== + dependencies: + postcss-selector-parser "^6.0.6" + +postcss-nesting@^10.1.2: + version "10.1.3" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.1.3.tgz#f0b1cd7ae675c697ab6a5a5ca1feea4784a2ef77" + integrity sha512-wUC+/YCik4wH3StsbC5fBG1s2Z3ZV74vjGqBFYtmYKlVxoio5TYGM06AiaKkQPPlkXWn72HKfS7Cw5PYxnoXSw== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-normalize-charset@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" + integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== + +postcss-normalize-display-values@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" + integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-positions@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.0.tgz#902a7cb97cf0b9e8b1b654d4a43d451e48966458" + integrity sha512-8gmItgA4H5xiUxgN/3TVvXRoJxkAWLW6f/KKhdsH03atg0cB8ilXnrB5PpSshwVu/dD2ZsRFQcR1OEmSBDAgcQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-repeat-style@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.0.tgz#f6d6fd5a54f51a741cc84a37f7459e60ef7a6398" + integrity sha512-IR3uBjc+7mcWGL6CtniKNQ4Rr5fTxwkaDHwMBDGGs1x9IVRkYIT/M4NelZWkAOBdV6v3Z9S46zqaKGlyzHSchw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-string@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" + integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-timing-functions@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" + integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-unicode@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz#3d23aede35e160089a285e27bf715de11dc9db75" + integrity sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ== + dependencies: + browserslist "^4.16.6" + postcss-value-parser "^4.2.0" + +postcss-normalize-url@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" + integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== + dependencies: + normalize-url "^6.0.1" + postcss-value-parser "^4.2.0" + +postcss-normalize-whitespace@^*: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" + integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize/-/postcss-normalize-10.0.1.tgz#464692676b52792a06b06880a176279216540dd7" + integrity sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA== + dependencies: + "@csstools/normalize.css" "*" + postcss-browser-comments "^4" + sanitize.css "*" + +postcss-opacity-percentage@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz#bd698bb3670a0a27f6d657cc16744b3ebf3b1145" + integrity sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w== + +postcss-ordered-values@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.0.tgz#04ef429e0991b0292bc918b135cd4c038f7b889f" + integrity sha512-wU4Z4D4uOIH+BUKkYid36gGDJNQtkVJT7Twv8qH6UyfttbbJWyw4/xIPuVEkkCtQLAJ0EdsNSh8dlvqkXb49TA== + dependencies: + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-overflow-shorthand@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz#ebcfc0483a15bbf1b27fdd9b3c10125372f4cbc2" + integrity sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg== + +postcss-page-break@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" + integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== + +postcss-place@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-7.0.4.tgz#eb026650b7f769ae57ca4f938c1addd6be2f62c9" + integrity sha512-MrgKeiiu5OC/TETQO45kV3npRjOFxEHthsqGtkh3I1rPbZSbXGD/lZVi9j13cYh+NA8PIAPyk6sGjT9QbRyvSg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-preset-env@^7.0.1: + version "7.4.2" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.4.2.tgz#2ff3e4787bd9d89710659535855d6ce85ce6110b" + integrity sha512-AmOkb8AeNNQwE/z2fHl1iwOIt8J50V8WR0rmLagcgIDoqlJZWjV3NdtOPnLGco1oN8DZe+Ss5B9ULbBeS6HfeA== + dependencies: + "@csstools/postcss-color-function" "^1.0.2" + "@csstools/postcss-font-format-keywords" "^1.0.0" + "@csstools/postcss-hwb-function" "^1.0.0" + "@csstools/postcss-ic-unit" "^1.0.0" + "@csstools/postcss-is-pseudo-class" "^2.0.0" + "@csstools/postcss-normalize-display-values" "^1.0.0" + "@csstools/postcss-oklab-function" "^1.0.1" + "@csstools/postcss-progressive-custom-properties" "^1.2.0" + autoprefixer "^10.4.2" + browserslist "^4.19.3" + css-blank-pseudo "^3.0.3" + css-has-pseudo "^3.0.4" + css-prefers-color-scheme "^6.0.3" + cssdb "^6.4.0" + postcss-attribute-case-insensitive "^5.0.0" + postcss-color-functional-notation "^4.2.2" + postcss-color-hex-alpha "^8.0.3" + postcss-color-rebeccapurple "^7.0.2" + postcss-custom-media "^8.0.0" + postcss-custom-properties "^12.1.4" + postcss-custom-selectors "^6.0.0" + postcss-dir-pseudo-class "^6.0.4" + postcss-double-position-gradients "^3.1.0" + postcss-env-function "^4.0.5" + postcss-focus-visible "^6.0.4" + postcss-focus-within "^5.0.4" + postcss-font-variant "^5.0.0" + postcss-gap-properties "^3.0.3" + postcss-image-set-function "^4.0.6" + postcss-initial "^4.0.1" + postcss-lab-function "^4.1.1" + postcss-logical "^5.0.4" + postcss-media-minmax "^5.0.0" + postcss-nesting "^10.1.2" + postcss-opacity-percentage "^1.1.2" + postcss-overflow-shorthand "^3.0.3" + postcss-page-break "^3.0.4" + postcss-place "^7.0.4" + postcss-pseudo-class-any-link "^7.1.1" + postcss-replace-overflow-wrap "^4.0.0" + postcss-selector-not "^5.0.0" + postcss-value-parser "^4.2.0" + +postcss-pseudo-class-any-link@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.1.tgz#534eb1dadd9945eb07830dbcc06fb4d5d865b8e0" + integrity sha512-JRoLFvPEX/1YTPxRxp1JO4WxBVXJYrSY7NHeak5LImwJ+VobFMwYDQHvfTXEpcn+7fYIeGkC29zYFhFWIZD8fg== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-reduce-initial@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz#fc31659ea6e85c492fb2a7b545370c215822c5d6" + integrity sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + +postcss-reduce-transforms@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" + integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-replace-overflow-wrap@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" + integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== + +postcss-selector-not@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-5.0.0.tgz#ac5fc506f7565dd872f82f5314c0f81a05630dc7" + integrity sha512-/2K3A4TCP9orP4TNS7u3tGdRFVKqz/E6pX3aGnriPG0jU78of8wsUcqE4QAhWEU0d+WnMSF93Ah3F//vUtK+iQ== + dependencies: + balanced-match "^1.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9: + version "6.0.9" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" + integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-svgo@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" + integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== + dependencies: + postcss-value-parser "^4.2.0" + svgo "^2.7.0" + +postcss-unique-selectors@^*: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" + integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-value-parser@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^7.0.35: + version "7.0.39" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + +postcss@^8.1.0, postcss@^8.3.5, postcss@^8.4.4, postcss@^8.4.6, postcss@^8.4.7: + version "8.4.12" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" + integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== + dependencies: + nanoid "^3.3.1" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.2.1, prettier@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.0.tgz#12f8f504c4d8ddb76475f441337542fa799207d4" + integrity sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A== + +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" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== + dependencies: + lodash "^4.17.20" + renderkid "^3.0.0" + +pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +promise-polyfill@^8.1.3, promise-polyfill@^8.2.1: + version "8.2.3" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.3.tgz#2edc7e4b81aff781c88a0d577e5fe9da822107c6" + integrity sha512-Og0+jCRQetV84U8wVjMNccfGCnMQ9mGs9Hv78QFe+pSDD3gWTpz0y+1QCuxy5d/vBFuZ3iwP2eycAkvqIMPmWg== + +promise@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e" + integrity sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q== + dependencies: + asap "~2.0.6" + +prompts@^2.0.1, prompts@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +prop-types@^15.5.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@6.9.7: + version "6.9.7" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" + integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +raf@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== + dependencies: + performance-now "^2.1.0" + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" + integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== + dependencies: + bytes "3.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-app-polyfill@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz#95221e0a9bd259e5ca6b177c7bb1cb6768f68fd7" + integrity sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w== + dependencies: + core-js "^3.19.2" + object-assign "^4.1.1" + promise "^8.1.0" + raf "^3.4.1" + regenerator-runtime "^0.13.9" + whatwg-fetch "^3.6.2" + +react-dev-utils@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.0.tgz#4eab12cdb95692a077616770b5988f0adf806526" + integrity sha512-xBQkitdxozPxt1YZ9O1097EJiVpwHr9FoAuEVURCKV0Av8NBERovJauzP7bo1ThvuhZ4shsQ1AJiu4vQpoT1AQ== + dependencies: + "@babel/code-frame" "^7.16.0" + address "^1.1.2" + browserslist "^4.18.1" + chalk "^4.1.2" + cross-spawn "^7.0.3" + detect-port-alt "^1.1.6" + escape-string-regexp "^4.0.0" + filesize "^8.0.6" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^6.5.0" + global-modules "^2.0.0" + globby "^11.0.4" + gzip-size "^6.0.0" + immer "^9.0.7" + is-root "^2.1.0" + loader-utils "^3.2.0" + open "^8.4.0" + pkg-up "^3.1.0" + prompts "^2.4.2" + react-error-overlay "^6.0.10" + recursive-readdir "^2.2.2" + shell-quote "^1.7.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +react-dom@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + scheduler "^0.20.2" + +react-error-overlay@^6.0.10: + version "6.0.10" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.10.tgz#0fe26db4fa85d9dbb8624729580e90e7159a59a6" + integrity sha512-mKR90fX7Pm5seCOfz8q9F+66VCc1PGsWSBxKbITjfKVQHMNF2zudxHnMdJiB1fRCb+XsbQV9sO9DCkgsMQgBIA== + +react-is@^16.10.2, react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-is@^17.0.1, react-is@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-modal@^3.12.1, react-modal@^3.14.4: + version "3.14.4" + resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.14.4.tgz#2ca7e8e9a180955e5c9508c228b73167c1e6f6a3" + integrity sha512-8surmulejafYCH9wfUmFyj4UfbSJwjcgbS9gf3oOItu4Hwd6ivJyVBETI0yHRhpJKCLZMUtnhzk76wXTsNL6Qg== + dependencies: + exenv "^1.2.0" + prop-types "^15.7.2" + react-lifecycles-compat "^3.0.0" + warning "^4.0.3" + +react-refresh@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" + integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== + +react-resize-detector@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-7.1.2.tgz#8ef975dd8c3d56f9a5160ac382ef7136dcd2d86c" + integrity sha512-zXnPJ2m8+6oq9Nn8zsep/orts9vQv3elrpA+R8XTcW7DVVUJ9vwDwMXaBtykAYjMnkCIaOoK9vObyR7ZgFNlOw== + dependencies: + lodash "^4.17.21" + +react-router-dom@^6: + version "6.3.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.3.0.tgz#a0216da813454e521905b5fa55e0e5176123f43d" + integrity sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw== + dependencies: + history "^5.2.0" + react-router "6.3.0" + +react-router@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557" + integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ== + dependencies: + history "^5.2.0" + +react-scripts@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-5.0.0.tgz#6547a6d7f8b64364ef95273767466cc577cb4b60" + integrity sha512-3i0L2CyIlROz7mxETEdfif6Sfhh9Lfpzi10CtcGs1emDQStmZfWjJbAIMtRD0opVUjQuFWqHZyRZ9PPzKCFxWg== + dependencies: + "@babel/core" "^7.16.0" + "@pmmmwh/react-refresh-webpack-plugin" "^0.5.3" + "@svgr/webpack" "^5.5.0" + babel-jest "^27.4.2" + babel-loader "^8.2.3" + babel-plugin-named-asset-import "^0.3.8" + babel-preset-react-app "^10.0.1" + bfj "^7.0.2" + browserslist "^4.18.1" + camelcase "^6.2.1" + case-sensitive-paths-webpack-plugin "^2.4.0" + css-loader "^6.5.1" + css-minimizer-webpack-plugin "^3.2.0" + dotenv "^10.0.0" + dotenv-expand "^5.1.0" + eslint "^8.3.0" + eslint-config-react-app "^7.0.0" + eslint-webpack-plugin "^3.1.1" + file-loader "^6.2.0" + fs-extra "^10.0.0" + html-webpack-plugin "^5.5.0" + identity-obj-proxy "^3.0.0" + jest "^27.4.3" + jest-resolve "^27.4.2" + jest-watch-typeahead "^1.0.0" + mini-css-extract-plugin "^2.4.5" + postcss "^8.4.4" + postcss-flexbugs-fixes "^5.0.2" + postcss-loader "^6.2.1" + postcss-normalize "^10.0.1" + postcss-preset-env "^7.0.1" + prompts "^2.4.2" + react-app-polyfill "^3.0.0" + react-dev-utils "^12.0.0" + react-refresh "^0.11.0" + resolve "^1.20.0" + resolve-url-loader "^4.0.0" + sass-loader "^12.3.0" + semver "^7.3.5" + source-map-loader "^3.0.0" + style-loader "^3.3.1" + tailwindcss "^3.0.2" + terser-webpack-plugin "^5.2.5" + webpack "^5.64.4" + webpack-dev-server "^4.6.0" + webpack-manifest-plugin "^4.0.2" + workbox-webpack-plugin "^6.4.1" + optionalDependencies: + fsevents "^2.3.2" + +react-smooth@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.1.tgz#74c7309916d6ccca182c4b30c8992f179e6c5a05" + integrity sha512-Own9TA0GPPf3as4vSwFhDouVfXP15ie/wIHklhyKBH5AN6NFtdk0UpHBnonV11BtqDkAWlt40MOUc+5srmW7NA== + dependencies: + fast-equals "^2.0.0" + react-transition-group "2.9.0" + +react-spring@^9.4.3: + version "9.4.4" + resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-9.4.4.tgz#0a53440013f97c1ebaa739a24a902487f36a5c1e" + integrity sha512-VOqilh9DJBsS6Pf550YLhdReS3j9a2AQVh7NcsNtWoxTYIeuErWi6ym0++6bBhQp4yT5xvVvUDaJ8ez8vrFgaw== + dependencies: + "@react-spring/core" "~9.4.4" + "@react-spring/konva" "~9.4.4" + "@react-spring/native" "~9.4.4" + "@react-spring/three" "~9.4.4" + "@react-spring/web" "~9.4.4" + "@react-spring/zdog" "~9.4.4" + +react-tabs@^3.2.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-3.2.3.tgz#ccbb3e1241ad3f601047305c75db661239977f2f" + integrity sha512-jx325RhRVnS9DdFbeF511z0T0WEqEoMl1uCE3LoZ6VaZZm7ytatxbum0B8bCTmaiV0KsU+4TtLGTGevCic7SWg== + dependencies: + clsx "^1.1.0" + prop-types "^15.5.0" + +react-toast-notifications@^2.4.3: + version "2.5.1" + resolved "https://registry.yarnpkg.com/react-toast-notifications/-/react-toast-notifications-2.5.1.tgz#30216eedb5608ec69719a818b9a2e09283e90074" + integrity sha512-eYuuiSPGLyuMHojRH2U7CbENvFHsvNia39pLM/s10KipIoNs14T7RIJk4aU2N+l++OsSgtJqnFObx9bpwLMU5A== + dependencies: + "@emotion/core" "^10.0.14" + react-transition-group "^4.4.1" + +react-transition-group@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== + dependencies: + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + +react-transition-group@^4.4.1: + version "4.4.2" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470" + integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + +react@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +readable-stream@^2.0.1: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +recharts-scale@^0.4.4: + version "0.4.5" + resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" + integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== + dependencies: + decimal.js-light "^2.4.1" + +recharts@^2.1.13: + version "2.1.13" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.1.13.tgz#61801acf3e13896b07dc6a8b38cbdd648480d0b7" + integrity sha512-9VWu2nzExmfiMFDHKqRFhYlJVmjzQGVKH5rBetXR4EuyEXuu3Y6cVxQuNEdusHhbm4SoPPrVDCwlBdREL3sQPA== + dependencies: + classnames "^2.2.5" + d3-interpolate "^3.0.1" + d3-scale "^4.0.2" + d3-shape "^3.1.0" + eventemitter3 "^4.0.1" + lodash "^4.17.19" + react-is "^16.10.2" + react-resize-detector "^7.1.2" + react-smooth "^2.0.1" + recharts-scale "^0.4.4" + reduce-css-calc "^2.1.8" + +recursive-readdir@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + dependencies: + minimatch "3.0.4" + +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + +reduce-css-calc@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" + integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== + dependencies: + css-unit-converter "^1.1.1" + postcss-value-parser "^3.3.0" + +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.9: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" + integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +regexpu-core@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" + integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== + +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== + 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" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^6.0.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz#d50d4ddc746bb10468443167acf800dcd6c3ad57" + integrity sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA== + dependencies: + adjust-sourcemap-loader "^4.0.0" + convert-source-map "^1.7.0" + loader-utils "^2.0.0" + postcss "^7.0.35" + source-map "0.6.1" + +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + +resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^2.0.0-next.3: + version "2.0.0-next.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" + integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + 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.70.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.70.1.tgz#824b1f1f879ea396db30b0fc3ae8d2fead93523e" + integrity sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA== + 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" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sanitize.css@*: + version "13.0.0" + resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-13.0.0.tgz#2675553974b27964c75562ade3bd85d79879f173" + integrity sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA== + +sass-loader@^12.3.0: + version "12.6.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.6.0.tgz#5148362c8e2cdd4b950f3c63ac5d16dbfed37bcb" + integrity sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA== + dependencies: + klona "^2.0.4" + neo-async "^2.6.2" + +sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + +schema-utils@^2.6.5: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selfsigned@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.0.tgz#e927cd5377cbb0a1075302cff8df1042cc2bce5b" + integrity sha512-cUdFiCbKoa1mZ6osuJs2uDHrs0k0oprsKveFiiaBKCNq3SYyb5gs2HxhQyDNLCmL51ZZThqi4YNDpCK6GOP1iQ== + dependencies: + node-forge "^1.2.0" + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.2, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + 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" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.2" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallowequal@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" + integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== + +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" + +signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +sockjs@^0.3.21: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-list-map@^2.0.0, source-list-map@^2.0.1: + 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-js@^1.0.1, source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-loader@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.1.tgz#9ae5edc7c2d42570934be4c95d1ccc6352eba52d" + integrity sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA== + dependencies: + abab "^2.0.5" + iconv-lite "^0.6.3" + source-map-js "^1.0.1" + +source-map-resolve@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" + integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + +source-map-support@^0.5.6, 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" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, 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.5.0, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +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" + +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== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +stack-utils@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + dependencies: + escape-string-regexp "^2.0.0" + +stackframe@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.1.tgz#1033a3473ee67f08e2f2fc8eba6aef4f845124e1" + integrity sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg== + +"statuses@>= 1.4.0 < 2", "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-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-length@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-5.0.1.tgz#3d647f497b6e8e8d41e422f7e0b23bc536c8381e" + integrity sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow== + dependencies: + char-regex "^2.0.0" + strip-ansi "^7.0.1" + +string-natural-compare@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" + integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.matchall@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa" + integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + get-intrinsic "^1.1.1" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + regexp.prototype.flags "^1.3.1" + side-channel "^1.0.4" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + 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" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.0, strip-ansi@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + dependencies: + ansi-regex "^6.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" + integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + +styled-components@^5.2.1, styled-components@^5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.3.tgz#312a3d9a549f4708f0fb0edc829eb34bde032743" + integrity sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/traverse" "^7.4.5" + "@emotion/is-prop-valid" "^0.8.8" + "@emotion/stylis" "^0.8.4" + "@emotion/unitless" "^0.7.4" + babel-plugin-styled-components ">= 1.12.0" + css-to-react-native "^3.0.0" + hoist-non-react-statics "^3.0.0" + shallowequal "^1.1.0" + supports-color "^5.5.0" + +stylehacks@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" + integrity sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q== + dependencies: + browserslist "^4.16.6" + postcss-selector-parser "^6.0.4" + +supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.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== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svg-parser@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + +svgo@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +svgo@^2.7.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +tailwindcss@^3.0.2: + version "3.0.23" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.0.23.tgz#c620521d53a289650872a66adfcb4129d2200d10" + integrity sha512-+OZOV9ubyQ6oI2BXEhzw4HrqvgcARY38xv3zKcjnWtMIZstEsXdI9xftd1iB7+RbOnj2HOEzkA0OyB5BaSxPQA== + dependencies: + arg "^5.0.1" + chalk "^4.1.2" + chokidar "^3.5.3" + color-name "^1.1.4" + cosmiconfig "^7.0.1" + detective "^5.2.0" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.2.11" + glob-parent "^6.0.2" + is-glob "^4.0.3" + normalize-path "^3.0.0" + object-hash "^2.2.0" + postcss "^8.4.6" + postcss-js "^4.0.0" + postcss-load-config "^3.1.0" + postcss-nested "5.0.6" + postcss-selector-parser "^6.0.9" + postcss-value-parser "^4.2.0" + quick-lru "^5.1.1" + resolve "^1.22.0" + +tapable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + 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" + +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.2.5: + version "5.3.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz#0320dcc270ad5372c1e8993fabbd927929773e54" + integrity sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g== + dependencies: + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + terser "^5.7.2" + +terser@^5.0.0, terser@^5.10.0, terser@^5.7.2: + version "5.14.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== + dependencies: + punycode "^2.1.1" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== + +tsconfig-paths@^3.12.0, tsconfig-paths@^3.9.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.0.tgz#4fcc48f9ccea8826c41b9ca093479de7f5018976" + integrity sha512-cg/1jAZoL57R39+wiw4u/SCC6Ic9Q5NqjBOb+9xISedOYurfog9ZNmKJSxAnb2m/5Bq4lE9lhUcau33Ml8DM0g== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" + integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typescript@^4.4.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4" + integrity sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + 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" + integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.0.0: + version "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-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@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +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= + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +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== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + +walker@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + +watchpack@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" + integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +web-vitals@^2.1.0: + version "2.1.4" + resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-2.1.4.tgz#76563175a475a5e835264d373704f9dde718290c" + integrity sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg== + +webidl-conversions@^3.0.0: + version "3.0.1" + 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== + +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +webpack-dev-middleware@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" + integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== + dependencies: + colorette "^2.0.10" + memfs "^3.4.1" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@^4.6.0: + version "4.7.4" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.4.tgz#d0ef7da78224578384e795ac228d8efb63d5f945" + integrity sha512-nfdsb02Zi2qzkNmgtZjkrMOcXnYZ6FLKcQwpxT7MvmHKc+oTtDsBju8j+NMyAygZ9GW1jMEUpy3itHtqgEhe1A== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.2.2" + ansi-html-community "^0.0.8" + bonjour "^3.5.0" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + default-gateway "^6.0.3" + del "^6.0.0" + express "^4.17.1" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.0" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + portfinder "^1.0.28" + schema-utils "^4.0.0" + selfsigned "^2.0.0" + serve-index "^1.9.1" + sockjs "^0.3.21" + spdy "^4.0.2" + strip-ansi "^7.0.0" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" + +webpack-manifest-plugin@^4.0.2: + version "4.1.1" + resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz#10f8dbf4714ff93a215d5a45bcc416d80506f94f" + integrity sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow== + dependencies: + tapable "^2.0.0" + webpack-sources "^2.2.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@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd" + integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA== + dependencies: + source-list-map "^2.0.1" + 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" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5.64.4: + version "5.70.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.70.0.tgz#3461e6287a72b5e6e2f4872700bc8de0d7500e6d" + integrity sha512-ZMWWy8CeuTTjCxbeaQI21xSswseF2oNOwc70QSKNePvmxE7XW36i7vpBMYZFAUHPwQiEbNGCEYIOOlyRbdGmxw== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.9.2" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.3.1" + webpack-sources "^3.2.3" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-fetch@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + +whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + 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" + +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== + dependencies: + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + +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@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.3, word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +workbox-background-sync@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.5.1.tgz#df79c6a4a22945d8a44493a4947a6ed0f720ef86" + integrity sha512-T5a35fagLXQvV8Dr4+bDU+XYsP90jJ3eBLjZMKuCNELMQZNj+VekCODz1QK44jgoBeQk+vp94pkZV6G+e41pgg== + dependencies: + idb "^6.1.4" + workbox-core "6.5.1" + +workbox-broadcast-update@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-6.5.1.tgz#9aecb116979b0709480b84cfd1beca7a901d01d4" + integrity sha512-mb/oyblyEpDbw167cCTyHnC3RqCnCQHtFYuYZd+QTpuExxM60qZuBH1AuQCgvLtDcztBKdEYK2VFD9SZYgRbaQ== + dependencies: + workbox-core "6.5.1" + +workbox-build@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-6.5.1.tgz#6b5e8f090bb608267868540d3072b44b8531b3bc" + integrity sha512-coDUDzHvFZ1ADOl3wKCsCSyOBvkPKlPgcQDb6LMMShN1zgF31Mev/1HzN3+9T2cjjWAgFwZKkuRyExqc1v21Zw== + 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 "6.5.1" + workbox-broadcast-update "6.5.1" + workbox-cacheable-response "6.5.1" + workbox-core "6.5.1" + workbox-expiration "6.5.1" + workbox-google-analytics "6.5.1" + workbox-navigation-preload "6.5.1" + workbox-precaching "6.5.1" + workbox-range-requests "6.5.1" + workbox-recipes "6.5.1" + workbox-routing "6.5.1" + workbox-strategies "6.5.1" + workbox-streams "6.5.1" + workbox-sw "6.5.1" + workbox-window "6.5.1" + +workbox-cacheable-response@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-6.5.1.tgz#f71d0a75b3d6846e39594955e99ac42fd26f8693" + integrity sha512-3TdtH/luDiytmM+Cn72HCBLZXmbeRNJqZx2yaVOfUZhj0IVwZqQXhNarlGE9/k6U5Jelb+TtpH2mLVhnzfiSMg== + dependencies: + workbox-core "6.5.1" + +workbox-core@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.5.1.tgz#0dba3bccf883a46dfa61cc412eaa3cb09bb549e6" + integrity sha512-qObXZ39aFJ2N8X7IUbGrJHKWguliCuU1jOXM/I4MTT84u9BiKD2rHMkIzgeRP1Ixu9+cXU4/XHJq3Cy0Qqc5hw== + +workbox-expiration@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.5.1.tgz#9f105fcf3362852754884ad153888070ce98b692" + integrity sha512-iY/cTADAQATMmPkUBRmQdacqq0TJd2wMHimBQz+tRnPGHSMH+/BoLPABPnu7O7rT/g/s59CUYYRGxe3mEgoJCA== + dependencies: + idb "^6.1.4" + workbox-core "6.5.1" + +workbox-google-analytics@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-6.5.1.tgz#685224d439c1e7a943f8241d65e2a34ee95a4ba0" + integrity sha512-qZU46/h4dbionYT6Yk6iBkUwpiEzAfnO1W7KkI+AMmY7G9/gA03dQQ7rpTw8F4vWrG7ahTUGWDFv6fERtaw1BQ== + dependencies: + workbox-background-sync "6.5.1" + workbox-core "6.5.1" + workbox-routing "6.5.1" + workbox-strategies "6.5.1" + +workbox-navigation-preload@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-6.5.1.tgz#a244e3bdf99ce86da7210315ca1ba5aef3710825" + integrity sha512-aKrgAbn2IMgzTowTi/ZyKdQUcES2m++9aGtpxqsX7Gn9ovCY8zcssaMEAMMwrIeveij5HiWNBrmj6MWDHi+0rg== + dependencies: + workbox-core "6.5.1" + +workbox-precaching@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-6.5.1.tgz#177b6424f1e71e601b9c3d6864decad2655f9ff9" + integrity sha512-EzlPBxvmjGfE56YZzsT/vpVkpLG1XJhoplgXa5RPyVWLUL1LbwEAxhkrENElSS/R9tgiTw80IFwysidfUqLihg== + dependencies: + workbox-core "6.5.1" + workbox-routing "6.5.1" + workbox-strategies "6.5.1" + +workbox-range-requests@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-6.5.1.tgz#f40f84aa8765940543eba16131d02f12b38e2fdc" + integrity sha512-57Da/qRbd9v33YlHX0rlSUVFmE4THCjKqwkmfhY3tNLnSKN2L5YBS3qhWeDO0IrMNgUj+rGve2moKYXeUqQt4A== + dependencies: + workbox-core "6.5.1" + +workbox-recipes@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-6.5.1.tgz#d2fb21743677cc3ca9e1fc9e3b68f0d1587df205" + integrity sha512-DGsyKygHggcGPQpWafC/Nmbm1Ny3sB2vE9r//3UbeidXiQ+pLF14KEG1/0NNGRaY+lfOXOagq6d1H7SC8KA+rA== + dependencies: + workbox-cacheable-response "6.5.1" + workbox-core "6.5.1" + workbox-expiration "6.5.1" + workbox-precaching "6.5.1" + workbox-routing "6.5.1" + workbox-strategies "6.5.1" + +workbox-routing@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-6.5.1.tgz#5488795ae850fe3ae435241143b54ff25ab0db70" + integrity sha512-yAAncdTwanvlR8KPjubyvFKeAok8ZcIws6UKxvIAg0I+wsf7UYi93DXNuZr6RBSQrByrN6HkCyjuhmk8P63+PA== + dependencies: + workbox-core "6.5.1" + +workbox-strategies@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-6.5.1.tgz#51cabbddad5a1956eb9d51cf6ce01ab0a6372756" + integrity sha512-JNaTXPy8wXzKkr+6za7/eJX9opoZk7UgY261I2kPxl80XQD8lMjz0vo9EOcBwvD72v3ZhGJbW84ZaDwFEhFvWA== + dependencies: + workbox-core "6.5.1" + +workbox-streams@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-6.5.1.tgz#12036817385fa4449a86a3ef77fce1cb00ecad9f" + integrity sha512-7jaTWm6HRGJ/ewECnhb+UgjTT50R42E0/uNCC4eTKQwnLO/NzNGjoXTdQgFjo4zteR+L/K6AtFAiYKH3ZJbAYw== + dependencies: + workbox-core "6.5.1" + workbox-routing "6.5.1" + +workbox-sw@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-6.5.1.tgz#f9256b40f0a7e94656ccd06f127ba19a92cd23c5" + integrity sha512-hVrQa19yo9wzN1fQQ/h2JlkzFpkuH2qzYT2/rk7CLaWt6tLnTJVFCNHlGRRPhytZSf++LoIy7zThT714sowT/Q== + +workbox-webpack-plugin@^6.4.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.1.tgz#da88b4b6d8eff855958f0e7ebb7aa3eea50a8282" + integrity sha512-SHtlQBpKruI16CAYhICDMkgjXE2fH5Yp+D+1UmBfRVhByZYzusVOykvnPm8ObJb9d/tXgn9yoppoxafFS7D4vQ== + dependencies: + fast-json-stable-stringify "^2.1.0" + pretty-bytes "^5.4.1" + upath "^1.2.0" + webpack-sources "^1.4.3" + workbox-build "6.5.1" + +workbox-window@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.5.1.tgz#7b5ca29467b1da45dc9e2b5a1b89159d3eb9957a" + integrity sha512-oRlun9u7b7YEjo2fIDBqJkU2hXtrEljXcOytRhfeQRbqXxjUOpFgXSGRSAkmDx1MlKUNOSbr+zfi8h5n7In3yA== + dependencies: + "@types/trusted-types" "^2.0.2" + workbox-core "6.5.1" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.4.6: + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== + +ws@^8.4.2: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xtend@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==