From 5870a6097a16176feedd83fa9e6ce1c1eaa773ef Mon Sep 17 00:00:00 2001 From: zuomeng wang Date: Mon, 19 Dec 2022 10:50:22 +0800 Subject: [PATCH] Feat/cloud integration (#569) * Chore/unit test (#538) * chore: add unit test * chore: add github action for unit test * feat: init firebase * chore: add development secrets * fix: rename auth -> data-services * feat: update blocksuite 0.3.0-alpha.4 (#543) * feat: add requests * feat: optimize swr cache * feat: add Authorization * feat: add confirm-invitation page * feat: add account sdk api and proxy * docs: update contributing (#550) * docs: update contributing * Update CONTRIBUTING.md * Update CONTRIBUTING.md Co-authored-by: ShortCipher5 * feat: update api * feat: remove babelrc setting * feat: add create workspace ui * feat: choose workspaces * feat: login modal * feat: authorization api * feat: login status * fix: remove unused variables * feat: login button * fix: lint * fix: workspace id * fix: i18n type error Co-authored-by: MingLiang Wang Co-authored-by: ShortCipher5 --- .github/workflows/build-test-version.yml | 11 +- .../workflows/{playwright.yml => tests.yml} | 7 +- docs/CONTRIBUTING.md | 39 +- jest.config.js | 19 + package.json | 9 +- packages/app/.eslintrc.js | 19 +- packages/app/jest.config.js | 5 + packages/app/next.config.js | 10 +- packages/app/package.json | 1 + packages/app/src/components/404/index.tsx | 11 + packages/app/src/components/404/styles.ts | 21 + packages/app/src/components/header/header.tsx | 4 + .../app/src/components/header/sync-icon.tsx | 19 + .../login-modal/LoginOptionButton.tsx | 124 + .../app/src/components/login-modal/google.svg | 6 + .../app/src/components/login-modal/icons.tsx | 42 + .../app/src/components/login-modal/index.tsx | 68 + .../SelectorPopperContent.tsx | 85 + .../CreateWorkspaceItem.tsx | 39 + .../CreateWorkspaceItem/index.ts | 1 + .../workspace-create/index.ts | 1 + .../workspace-create/style.ts | 55 + .../workspace-create/workspace-create.tsx | 58 + .../WorkspaceItem/ListItem.tsx | 37 + .../WorkspaceItem/LoginItem.tsx | 48 + .../WorkspaceItem/PrivateWorkspaceItem.tsx | 44 + .../WorkspaceItem/FooterSetting.tsx | 17 + .../WorkspaceItem/FooterUsers.tsx | 25 + .../WorkspaceItem/WorkspaceItem.tsx | 64 + .../WorkspaceItem/WorkspaceItem/index.ts | 1 + .../WorkspaceSelector/WorkspaceItem/index.ts | 5 + .../WorkspaceSelector/WorkspaceItem/styles.ts | 41 + .../WorkspaceSelector/WorkspaceSelector.tsx | 18 + .../WorkspaceSelector/index.ts | 1 + .../WorkspaceSelector/styles.ts | 38 + .../components/workspace-slider-bar/index.tsx | 7 +- .../components/workspace-slider-bar/style.ts | 4 + packages/app/src/libs/i18n/resources/index.ts | 120 +- packages/app/src/libs/i18n/scripts/api.ts | 162 +- .../app/src/libs/i18n/scripts/download.ts | 196 +- packages/app/src/libs/i18n/scripts/request.ts | 82 +- packages/app/src/libs/i18n/scripts/sync.ts | 230 +- packages/app/src/libs/i18n/scripts/utils.ts | 2 +- .../ConfirmInvitationPage/AlreadyJoined.tsx | 10 + .../ConfirmInvitationPage/Confirm.tsx | 11 + .../ConfirmInvitationPage/LinkExpired.tsx | 8 + .../ConfirmInvitationPage/index.tsx | 21 + packages/app/src/pages/404.tsx | 4 + packages/app/src/pages/_app.tsx | 2 + .../app/src/pages/affine/[workspace_id].tsx | 20 + packages/app/src/pages/confirm-invitation.tsx | 8 + .../app/src/providers/app-state-provider.tsx | 57 + .../src/providers/global-modal-provider.tsx | 14 + packages/app/src/styles/theme.ts | 3 + packages/app/src/styles/types.ts | 1 + packages/app/src/ui/button/icon-button.tsx | 2 +- packages/app/src/ui/button/index.ts | 1 + packages/app/src/ui/button/styles.ts | 66 +- packages/app/src/ui/button/text-button.tsx | 53 + packages/app/src/ui/divider/index.ts | 8 + packages/app/src/ui/input/index.ts | 3 + packages/app/src/ui/input/input.tsx | 37 + packages/app/src/ui/input/style.ts | 30 + .../src/utils/__tests__/get-is-mobile.spec.ts | 12 + packages/app/src/utils/get-is-mobile.ts | 28 +- packages/data-services/package.json | 30 + packages/data-services/src/auth.ts | 41 + packages/data-services/src/index.ts | 3 + .../data-services/src/request/ServiceError.ts | 9 + packages/data-services/src/request/axios.ts | 19 + packages/data-services/src/request/index.ts | 4 + .../request/authorization/authorization.ts | 99 + .../request/request/authorization/events.ts | 28 + .../request/request/authorization/index.ts | 2 + .../request/request/authorization/types.ts | 8 + .../src/request/request/index.ts | 6 + .../src/request/response/handle-error.ts | 15 + .../src/request/response/index.ts | 1 + packages/data-services/src/sdks/account.ts | 90 + packages/data-services/src/sdks/index.ts | 4 + .../data-services/src/sdks/types/account.ts | 33 + .../data-services/src/sdks/types/common.ts | 2 + .../data-services/src/sdks/types/index.ts | 3 + .../data-services/src/sdks/types/workspace.ts | 32 + packages/data-services/src/sdks/user.hook.ts | 45 + packages/data-services/src/sdks/user.ts | 60 + .../data-services/src/sdks/workspace.bak.ts | 106 + .../data-services/src/sdks/workspace.hook.ts | 72 + packages/data-services/src/sdks/workspace.ts | 186 ++ packages/data-services/tsconfig.json | 25 + pnpm-lock.yaml | 2797 ++++++++++++++++- 91 files changed, 5391 insertions(+), 524 deletions(-) rename .github/workflows/{playwright.yml => tests.yml} (87%) create mode 100644 jest.config.js create mode 100644 packages/app/jest.config.js create mode 100644 packages/app/src/components/404/index.tsx create mode 100644 packages/app/src/components/404/styles.ts create mode 100644 packages/app/src/components/header/sync-icon.tsx create mode 100644 packages/app/src/components/login-modal/LoginOptionButton.tsx create mode 100644 packages/app/src/components/login-modal/google.svg create mode 100644 packages/app/src/components/login-modal/icons.tsx create mode 100644 packages/app/src/components/login-modal/index.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/CreateWorkspaceItem.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/index.ts create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/index.ts create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/style.ts create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/ListItem.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/LoginItem.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/PrivateWorkspaceItem.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/FooterSetting.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/FooterUsers.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/WorkspaceItem.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/index.ts create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/index.ts create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/styles.ts create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/index.ts create mode 100644 packages/app/src/components/workspace-slider-bar/WorkspaceSelector/styles.ts create mode 100644 packages/app/src/pages-content/ConfirmInvitationPage/AlreadyJoined.tsx create mode 100644 packages/app/src/pages-content/ConfirmInvitationPage/Confirm.tsx create mode 100644 packages/app/src/pages-content/ConfirmInvitationPage/LinkExpired.tsx create mode 100644 packages/app/src/pages-content/ConfirmInvitationPage/index.tsx create mode 100644 packages/app/src/pages/404.tsx create mode 100644 packages/app/src/pages/affine/[workspace_id].tsx create mode 100644 packages/app/src/pages/confirm-invitation.tsx create mode 100644 packages/app/src/providers/app-state-provider.tsx create mode 100644 packages/app/src/ui/button/text-button.tsx create mode 100644 packages/app/src/ui/divider/index.ts create mode 100644 packages/app/src/ui/input/index.ts create mode 100644 packages/app/src/ui/input/input.tsx create mode 100644 packages/app/src/ui/input/style.ts create mode 100644 packages/app/src/utils/__tests__/get-is-mobile.spec.ts create mode 100644 packages/data-services/package.json create mode 100644 packages/data-services/src/auth.ts create mode 100644 packages/data-services/src/index.ts create mode 100644 packages/data-services/src/request/ServiceError.ts create mode 100644 packages/data-services/src/request/axios.ts create mode 100644 packages/data-services/src/request/index.ts create mode 100644 packages/data-services/src/request/request/authorization/authorization.ts create mode 100644 packages/data-services/src/request/request/authorization/events.ts create mode 100644 packages/data-services/src/request/request/authorization/index.ts create mode 100644 packages/data-services/src/request/request/authorization/types.ts create mode 100644 packages/data-services/src/request/request/index.ts create mode 100644 packages/data-services/src/request/response/handle-error.ts create mode 100644 packages/data-services/src/request/response/index.ts create mode 100644 packages/data-services/src/sdks/account.ts create mode 100644 packages/data-services/src/sdks/index.ts create mode 100644 packages/data-services/src/sdks/types/account.ts create mode 100644 packages/data-services/src/sdks/types/common.ts create mode 100644 packages/data-services/src/sdks/types/index.ts create mode 100644 packages/data-services/src/sdks/types/workspace.ts create mode 100644 packages/data-services/src/sdks/user.hook.ts create mode 100644 packages/data-services/src/sdks/user.ts create mode 100644 packages/data-services/src/sdks/workspace.bak.ts create mode 100644 packages/data-services/src/sdks/workspace.hook.ts create mode 100644 packages/data-services/src/sdks/workspace.ts create mode 100644 packages/data-services/tsconfig.json diff --git a/.github/workflows/build-test-version.yml b/.github/workflows/build-test-version.yml index 265986417d..3862fefa32 100644 --- a/.github/workflows/build-test-version.yml +++ b/.github/workflows/build-test-version.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: tag: - description: "Custom Tag. Set nightly-latest will publish to development." + description: 'Custom Tag. Set nightly-latest will publish to development.' required: true type: string @@ -20,6 +20,7 @@ jobs: build: name: Lint and Build runs-on: self-hosted + environment: development steps: - uses: actions/checkout@v2 @@ -62,6 +63,14 @@ jobs: - name: Build run: pnpm build + env: + NEXT_PUBLIC_FIREBASE_API_KEY: ${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }} + NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: ${{ secrets.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN }} + NEXT_PUBLIC_FIREBASE_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_PROJECT_ID }} + NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET: ${{ secrets.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET }} + NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID }} + NEXT_PUBLIC_FIREBASE_APP_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_APP_ID }} + NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID }} - name: Export run: pnpm export diff --git a/.github/workflows/playwright.yml b/.github/workflows/tests.yml similarity index 87% rename from .github/workflows/playwright.yml rename to .github/workflows/tests.yml index 55246811c3..521cc093d2 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/tests.yml @@ -1,4 +1,4 @@ -name: Playwright Tests +name: E2E & Unit Tests on: push: branches: [pathfinder] @@ -33,5 +33,8 @@ jobs: - name: Install Playwright Browsers run: npx playwright install --with-deps - - name: Run Playwright tests + - name: Run E2E tests run: pnpm run test:e2e + + - name: Run Unit tests + run: pnpm run test:unit diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 543f380686..c278df5d3d 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -10,12 +10,17 @@ Use the table of contents icon on the top left corner of this document to get to ## New contributor guide +Currently we have two versions of AFFiNE: + +- [AFFiNE Pre-Alpha](https://livedemo.affine.pro/). This version users the branch `master`, however is no longer actively developed and will be archived in the future. +- [AFFiNE Alpha](https://pathfinder.affine.pro/). This version uses the 'pathfinder' branch, this is the latest version under active development. We plan to update this to the master branch in the near future. + To get an overview of the project, read the [README](../README.md). Here are some resources to help you get started with open source contributions: -- [Finding ways to contribute to open source on GitHub](https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github) -- [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git) -- [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow) -- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests) +- [Finding ways to contribute to open source on GitHub](https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github) +- [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git) +- [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow) +- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests) ## Getting started @@ -47,15 +52,15 @@ For more information about using a codespace for working on GitHub documentation 2. Fork the repository. -- Using GitHub Desktop: +- Using GitHub Desktop: - - [Getting started with GitHub Desktop](https://docs.github.com/en/desktop/installing-and-configuring-github-desktop/getting-started-with-github-desktop) will guide you through setting up Desktop. - - Once Desktop is set up, you can use it to [fork the repo](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/cloning-and-forking-repositories-from-github-desktop)! + - [Getting started with GitHub Desktop](https://docs.github.com/en/desktop/installing-and-configuring-github-desktop/getting-started-with-github-desktop) will guide you through setting up Desktop. + - Once Desktop is set up, you can use it to [fork the repo](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/cloning-and-forking-repositories-from-github-desktop)! -- Using the command line: - - [Fork the repo](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) so that you can make your changes without affecting the original project until you're ready to merge them. +- Using the command line: + - [Fork the repo](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) so that you can make your changes without affecting the original project until you're ready to merge them. -3. Install or update to **Node.js v16**. For more information, see [the development guide](contributing/development.md). +3. Install or update to **Node.js v16**. 4. Create a working branch and start with your changes! @@ -71,13 +76,13 @@ Once your changes are ready, don't forget to self-review to speed up the review When you're finished with the changes, create a pull request, also known as a PR. -- Fill the "Ready for review" template so that we can review your PR. This template helps reviewers understand your changes as well as the purpose of your pull request. -- Don't forget to [link PR to issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) if you are solving one. -- Enable the checkbox to [allow maintainer edits](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge. - Once you submit your PR, a Docs team member will review your proposal. We may ask questions or request for additional information. -- We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch. -- As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations). -- If you run into any merge issues, checkout this [git tutorial](https://github.com/skills/resolve-merge-conflicts) to help you resolve merge conflicts and other issues. +- Fill the "Ready for review" template so that we can review your PR. This template helps reviewers understand your changes as well as the purpose of your pull request. +- Don't forget to [link PR to issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) if you are solving one. +- Enable the checkbox to [allow maintainer edits](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge. + Once you submit your PR, a Docs team member will review your proposal. We may ask questions or request for additional information. +- We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch. +- As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations). +- If you run into any merge issues, checkout this [git tutorial](https://github.com/skills/resolve-merge-conflicts) to help you resolve merge conflicts and other issues. ### Your PR is merged! diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000000..4423f5ad0b --- /dev/null +++ b/jest.config.js @@ -0,0 +1,19 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + projects: ['/packages/app'], + preset: 'ts-jest', + testEnvironment: 'node', + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + // '^.+\\.[tj]sx?$' to process js/ts with `ts-jest` + // '^.+\\.m?[tj]sx?$' to process js/ts/mjs/mts with `ts-jest` + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + }, + ], + }, +}; diff --git a/package.json b/package.json index 3bf30b441b..712288570f 100644 --- a/package.json +++ b/package.json @@ -8,15 +8,20 @@ "export": "pnpm --filter @pathfinder/app export", "start": "pnpm --filter @pathfinder/app start", "lint": "pnpm --filter @pathfinder/app lint", - "test:e2e": "playwright test" + "test:e2e": "playwright test", + "test:unit": "jest" }, "devDependencies": { + "@jest/globals": "^29.3.1", "@playwright/test": "^1.28.1", "@types/node": "18.7.18", "eslint": "8.22.0", "eslint-config-next": "12.3.1", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.2.1", - "prettier": "^2.7.1" + "jest": "^29.3.1", + "prettier": "^2.7.1", + "ts-jest": "^29.0.3", + "typescript": "^4.9.3" } } diff --git a/packages/app/.eslintrc.js b/packages/app/.eslintrc.js index c76264c249..6dca46e2e5 100644 --- a/packages/app/.eslintrc.js +++ b/packages/app/.eslintrc.js @@ -5,14 +5,15 @@ /** @type { import('eslint').Linter.Config } */ module.exports = { - extends: [ - 'next/core-web-vitals', - 'plugin:@next/next/recommended', - 'plugin:prettier/recommended', - ], - rules: { - 'prettier/prettier': 'warn', - }, + extends: [ + 'next/core-web-vitals', + 'plugin:@next/next/recommended', + 'plugin:prettier/recommended', + // 'next/babel', + ], + rules: { + 'prettier/prettier': 'warn', + }, - reportUnusedDisableDirectives: true, + reportUnusedDisableDirectives: true, }; diff --git a/packages/app/jest.config.js b/packages/app/jest.config.js new file mode 100644 index 0000000000..3745fc2237 --- /dev/null +++ b/packages/app/jest.config.js @@ -0,0 +1,5 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', +}; diff --git a/packages/app/next.config.js b/packages/app/next.config.js index 8e3c3d3fe7..f1648caa68 100644 --- a/packages/app/next.config.js +++ b/packages/app/next.config.js @@ -1,4 +1,3 @@ -// @ts-check const { getGitVersion, getCommitHash } = require('./scripts/gitInfo'); /** @type {import('next').NextConfig} */ @@ -14,6 +13,15 @@ const nextConfig = { VERSION: getGitVersion(), COMMIT_HASH: getCommitHash(), }, + // XXX not test yet + rewrites: async () => { + return [ + { + source: '/api/:path*', + destination: 'http://100.77.180.48:11001/api/:path*', + }, + ]; + }, }; module.exports = nextConfig; diff --git a/packages/app/package.json b/packages/app/package.json index 62aad0592f..98aa2407f2 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -23,6 +23,7 @@ "@mui/icons-material": "^5.10.9", "@mui/material": "^5.8.6", "@toeverything/pathfinder-logger": "workspace:@pathfinder/logger@*", + "@pathfinder/data-services": "workspace:@pathfinder/data-services@*", "cmdk": "^0.1.20", "css-spring": "^4.1.0", "dayjs": "^1.11.7", diff --git a/packages/app/src/components/404/index.tsx b/packages/app/src/components/404/index.tsx new file mode 100644 index 0000000000..e2f828ad9f --- /dev/null +++ b/packages/app/src/components/404/index.tsx @@ -0,0 +1,11 @@ +import { NotFoundTitle, PageContainer } from './styles'; + +export const NotfoundPage = () => { + return ( + + 404 - Page Not Found + + ); +}; + +export default NotfoundPage; diff --git a/packages/app/src/components/404/styles.ts b/packages/app/src/components/404/styles.ts new file mode 100644 index 0000000000..aa6619c558 --- /dev/null +++ b/packages/app/src/components/404/styles.ts @@ -0,0 +1,21 @@ +import { absoluteCenter, displayFlex, styled } from '@/styles'; + +export const PageContainer = styled('div')(({ theme }) => { + return { + width: '100%', + height: 'calc(100vh)', + backgroundColor: theme.colors.pageBackground, + }; +}); + +export const NotFoundTitle = styled('h1')(({ theme }) => { + return { + position: 'relative', + top: 'calc(50% - 100px)', + height: '100px', + fontSize: '60px', + lineHeight: '100px', + color: theme.colors.textColor, + textAlign: 'center', + }; +}); diff --git a/packages/app/src/components/header/header.tsx b/packages/app/src/components/header/header.tsx index 7859953dbc..331f9bfd3d 100644 --- a/packages/app/src/components/header/header.tsx +++ b/packages/app/src/components/header/header.tsx @@ -22,6 +22,9 @@ import { getWarningMessage, shouldShowWarning } from './utils'; import { Menu, MenuItem } from '@/ui/menu'; import { useRouter } from 'next/router'; import { useConfirm } from '@/providers/confirm-provider'; +import { useModal } from '@/providers/global-modal-provider'; +import { useAppState } from '@/providers/app-state-provider'; +import { SyncIcon } from './sync-icon'; const PopoverContent = () => { const { editor, mode, setMode } = useEditor(); @@ -131,6 +134,7 @@ const HeaderRight = () => { } return ( <> + } placement="bottom-end"> diff --git a/packages/app/src/components/header/sync-icon.tsx b/packages/app/src/components/header/sync-icon.tsx new file mode 100644 index 0000000000..618ee7b37d --- /dev/null +++ b/packages/app/src/components/header/sync-icon.tsx @@ -0,0 +1,19 @@ +import { CloudUnsyncedIcon, CloudInsyncIcon } from '@blocksuite/icons'; +import { useModal } from '@/providers/global-modal-provider'; +import { useAppState } from '@/providers/app-state-provider'; +import { IconButton } from '@/ui/button'; + +export const SyncIcon = () => { + const { triggerLoginModal } = useModal(); + const appState = useAppState(); + + return appState.user ? ( + + + + ) : ( + + + + ); +}; diff --git a/packages/app/src/components/login-modal/LoginOptionButton.tsx b/packages/app/src/components/login-modal/LoginOptionButton.tsx new file mode 100644 index 0000000000..8070e51254 --- /dev/null +++ b/packages/app/src/components/login-modal/LoginOptionButton.tsx @@ -0,0 +1,124 @@ +import { signInWithGoogle, login, setToken } from '@pathfinder/data-services'; +import { styled } from '@/styles'; +import { Button } from '@/ui/button'; +import { useModal } from '@/providers/global-modal-provider'; +import { GoogleIcon, StayLogOutIcon } from './icons'; + +export const GoogleLoginButton = () => { + const { triggerLoginModal } = useModal(); + return ( + { + signInWithGoogle() + .then(async user => { + const idToken = await user.user.getIdToken(); + const token = await login({ token: idToken, type: 'Google' }); + setToken({ + accessToken: token.token, + refreshToken: token.refresh, + }); + triggerLoginModal(); + }) + .catch(error => { + console.log('sign google error', error); + }); + }} + > + + + + + + Continue with Google + Set up an AFFINE account to sync data + + + + ); +}; + +export const StayLogOutButton = () => { + return ( + + + + + + + Stay logged out + All changes are saved locally + + + + ); +}; + +const StyledGoogleButton = styled(Button)(({ theme }) => { + return { + width: '361px', + height: '56px', + padding: '4px', + background: '#6880FF', + color: '#fff', + + '& > span': { + marginLeft: 0, + }, + + ':hover': { + background: '#516BF4', + color: '#fff', + }, + }; +}); + +const StyledStayLogOutButton = styled(Button)(({ theme }) => { + return { + width: '361px', + height: '56px', + padding: '4px', + + '& > span': { + marginLeft: 0, + }, + + ':hover': { + borderColor: '#6880FF', + }, + }; +}); + +const ButtonWrapper = styled('div')({ + display: 'flex', + flexDirection: 'row', +}); + +const IconWrapper = styled('div')({ + width: '48px', + height: '48px', + flex: '0 48px', + borderRadius: '5px', + overflow: 'hidden', + marginRight: '12px', +}); + +const TextWrapper = styled('div')({ + flex: 1, + textAlign: 'left', +}); + +const Title = styled('h1')(({ theme }) => { + return { + fontSize: '18px', + lineHeight: '26px', + fontWeight: 500, + }; +}); + +const Description = styled('p')(({ theme }) => { + return { + fontSize: '16px', + lineHeight: '22px', + fontWeight: 400, + }; +}); diff --git a/packages/app/src/components/login-modal/google.svg b/packages/app/src/components/login-modal/google.svg new file mode 100644 index 0000000000..23af746fed --- /dev/null +++ b/packages/app/src/components/login-modal/google.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/app/src/components/login-modal/icons.tsx b/packages/app/src/components/login-modal/icons.tsx new file mode 100644 index 0000000000..a6c694c876 --- /dev/null +++ b/packages/app/src/components/login-modal/icons.tsx @@ -0,0 +1,42 @@ +import { CloudUnsyncedIcon } from '@blocksuite/icons'; +import { styled } from '@/styles'; +import GoogleSvg from './google.svg'; + +export const GoogleIcon = () => { + return ( + + + Google + + + ); +}; + +const GoogleIconWrapper = styled('div')(({ theme }) => ({ + width: '48px', + height: '48px', + background: theme.colors.pageBackground, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', +})); + +export const StayLogOutIcon = () => { + return ( + + + + ); +}; + +const StayLogOutWrapper = styled('div')(({ theme }) => { + return { + width: '48px', + height: '48px', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + fontSize: '24px', + background: theme.colors.hoverBackground, + }; +}); diff --git a/packages/app/src/components/login-modal/index.tsx b/packages/app/src/components/login-modal/index.tsx new file mode 100644 index 0000000000..3aa71a2f2b --- /dev/null +++ b/packages/app/src/components/login-modal/index.tsx @@ -0,0 +1,68 @@ +import { ResetIcon } from '@blocksuite/icons'; +import { styled } from '@/styles'; +import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal'; +import { TextButton, Button } from '@/ui/button'; +import { GoogleLoginButton, StayLogOutButton } from './LoginOptionButton'; + +interface LoginModalProps { + open: boolean; + onClose: () => void; +} + +export const LoginModal = ({ open, onClose }: LoginModalProps) => { + return ( + + +
+ { + onClose(); + }} + /> +
+ + Currently not logged in + + + +
+ }>Clear local data +
+
+
+ ); +}; + +const Header = styled('div')({ + position: 'relative', + height: '44px', +}); + +const Content = styled('div')({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: '16px', +}); + +const ContentTitle = styled('h1')({ + fontSize: '20px', + lineHeight: '28px', + fontWeight: 600, + textAlign: 'center', + paddingBottom: '16px', +}); + +const Footer = styled('div')({ + height: '70px', + paddingLeft: '24px', + marginTop: '32px', +}); + +const StyledResetIcon = styled(ResetIcon)({ + marginRight: '12px', + width: '20px', + height: '20px', +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx new file mode 100644 index 0000000000..b94815f666 --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx @@ -0,0 +1,85 @@ +import { InformationIcon, LogOutIcon } from '@blocksuite/icons'; +import { styled } from '@/styles'; +import { Divider } from '@/ui/divider'; +import { useAppState } from '@/providers/app-state-provider'; +import { SelectorPopperContainer } from './styles'; +import { + PrivateWorkspaceItem, + WorkspaceItem, + CreateWorkspaceItem, + ListItem, + LoginItem, +} from './WorkspaceItem'; + +const workspaces = [ + { + name: 'Design', + icon: '', + }, + { + name: 'Operation', + icon: '', + }, + { + name: 'Something is too long to show in this box', + icon: '', + }, +]; + +export const SelectorPopperContent = () => { + const { user, workspaces } = useAppState(); + return !user ? ( + + + + } + name="About AFFiNE" + onClick={() => console.log('About AFFiNE')} + /> + + ) : ( + + + + Workspace + {workspaces.map(workspace => { + return ( + + ); + })} + + + } + name="About AFFiNE" + onClick={() => console.log('About AFFiNE')} + /> + } + name="Sign out" + onClick={() => console.log('Sign out')} + /> + + ); +}; + +const StyledDivider = styled(Divider)({ + margin: '8px 12px', + width: 'calc(100% - 24px)', +}); + +const WorkspaceGroupTitle = styled('div')(({ theme }) => { + return { + color: theme.colors.iconColor, + fontSize: theme.font.sm, + lineHeight: '30px', + height: '30px', + padding: '0 12px', + }; +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/CreateWorkspaceItem.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/CreateWorkspaceItem.tsx new file mode 100644 index 0000000000..ccb6526691 --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/CreateWorkspaceItem.tsx @@ -0,0 +1,39 @@ +import { useState } from 'react'; +import { AddIcon } from '@blocksuite/icons'; +import { styled } from '@/styles'; +import { + WorkspaceItemAvatar, + WorkspaceItemWrapper, + WorkspaceItemContent, +} from '../styles'; +import { WorkspaceCreate } from './workspace-create'; + +const name = 'Create new Workspace'; + +export const CreateWorkspaceItem = () => { + const [open, setOpen] = useState(false); + return ( + <> + setOpen(true)}> + + + + + {name} + + + setOpen(false)} /> + + ); +}; + +const Name = styled('div')(({ theme }) => { + return { + color: theme.colors.quoteColor, + fontSize: theme.font.base, + fontWeight: 400, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }; +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/index.ts b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/index.ts new file mode 100644 index 0000000000..8db80b1dc7 --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/index.ts @@ -0,0 +1 @@ +export * from './CreateWorkspaceItem'; diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/index.ts b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/index.ts new file mode 100644 index 0000000000..38645e20c1 --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/index.ts @@ -0,0 +1 @@ +export * from './workspace-create'; diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/style.ts b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/style.ts new file mode 100644 index 0000000000..81c3f1d13c --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/style.ts @@ -0,0 +1,55 @@ +import { styled } from '@/styles'; + +export const StyledModalWrapper = styled('div')(({ theme }) => { + return { + position: 'relative', + padding: '0px', + width: '460px', + background: theme.colors.popoverBackground, + borderRadius: '12px', + }; +}); + +export const StyledModalHeader = styled('div')(({ theme }) => { + return { + margin: '44px 0px 12px 0px', + width: '460px', + fontWeight: '600', + fontSize: '20px;', + textAlign: 'center', + color: theme.colors.popoverColor, + }; +}); + +// export const StyledModalContent = styled('div')(({ theme }) => {}); + +export const StyledTextContent = styled('div')(({ theme }) => { + return { + margin: 'auto', + width: '425px', + fontFamily: 'Avenir Next', + fontStyle: 'normal', + fontWeight: '400', + fontSize: '18px', + lineHeight: '26px', + textAlign: 'center', + }; +}); + +export const StyledInputContent = styled('div')(({ theme }) => { + return { + display: 'flex', + flexDirection: 'row', + justifyContent: 'center', + margin: '40px 0 24px 0', + }; +}); + +export const StyledButtonContent = styled('div')(({ theme }) => { + return { + display: 'flex', + flexDirection: 'row', + justifyContent: 'center', + margin: '0px 0 32px 0', + }; +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx new file mode 100644 index 0000000000..e4b5b5902b --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx @@ -0,0 +1,58 @@ +import { createWorkspace } from '@pathfinder/data-services'; +import Modal from '@/ui/modal'; +import Input from '@/ui/input'; +import { Button } from '@/ui/button'; +import { + StyledModalHeader, + StyledTextContent, + StyledModalWrapper, + StyledInputContent, + StyledButtonContent, +} from './style'; +import { useState } from 'react'; +import { ModalCloseButton } from '@/ui/modal'; + +interface WorkspaceCreateProps { + open: boolean; + onClose: () => void; +} + +export const WorkspaceCreate = ({ open, onClose }: WorkspaceCreateProps) => { + const [workspaceName, setWorkspaceId] = useState(''); + const handlerInputChange = (workspaceName: string) => { + setWorkspaceId(workspaceName); + }; + console.log('workspaceName', workspaceName); + return ( + + + + Create new Workspace + + Workspaces are shared environments where teams can collaborate. After + creating a Workspace, you can invite others to join. + + + + + + + + + + ); +}; + +export default WorkspaceCreate; diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/ListItem.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/ListItem.tsx new file mode 100644 index 0000000000..120a003953 --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/ListItem.tsx @@ -0,0 +1,37 @@ +import type { ReactNode } from 'react'; +import { styled } from '@/styles'; +import { WorkspaceItemWrapper, WorkspaceItemContent } from './styles'; + +interface ListItemProps { + name: string; + icon: ReactNode; + onClick: () => void; +} + +export const ListItem = ({ name, icon, onClick }: ListItemProps) => { + return ( + + {icon} + + {name} + + + ); +}; + +const Name = styled('div')(({ theme }) => { + return { + color: theme.colors.quoteColor, + fontSize: theme.font.sm, + fontWeight: 400, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }; +}); + +const StyledIconWrapper = styled('div')({ + width: '20px', + height: '20px', + fontSize: '20px', +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/LoginItem.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/LoginItem.tsx new file mode 100644 index 0000000000..c800c31aee --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/LoginItem.tsx @@ -0,0 +1,48 @@ +import { useModal } from '@/providers/global-modal-provider'; +import { styled } from '@/styles'; +import { + WorkspaceItemAvatar, + LoginItemWrapper, + WorkspaceItemContent, +} from './styles'; + +export const LoginItem = () => { + const { triggerLoginModal } = useModal(); + return ( + triggerLoginModal()}> + + A + + + AFFiNE + + Log in to sync with affine + + + + ); +}; + +const Name = styled('div')(({ theme }) => { + return { + color: theme.colors.quoteColor, + fontSize: theme.font.base, + fontWeight: 500, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }; +}); + +const Description = styled('div')(({ theme }) => { + return { + color: theme.colors.iconColor, + fontSize: theme.font.sm, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }; +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/PrivateWorkspaceItem.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/PrivateWorkspaceItem.tsx new file mode 100644 index 0000000000..791ac45e1f --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/PrivateWorkspaceItem.tsx @@ -0,0 +1,44 @@ +import { styled } from '@/styles'; +import { useAppState } from '@/providers/app-state-provider'; +import { + WorkspaceItemAvatar, + PrivateWorkspaceWrapper, + WorkspaceItemContent, +} from './styles'; + +export const PrivateWorkspaceItem = () => { + const { user } = useAppState(); + + return !user ? null : ( + + + {user.name.charAt(0)} + + + {user.name} + {user.email} + + + ); +}; + +const Name = styled('div')(({ theme }) => { + return { + color: theme.colors.quoteColor, + fontSize: theme.font.base, + fontWeight: 500, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }; +}); + +const Email = styled('div')(({ theme }) => { + return { + color: theme.colors.iconColor, + fontSize: theme.font.sm, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }; +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/FooterSetting.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/FooterSetting.tsx new file mode 100644 index 0000000000..346b50ebac --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/FooterSetting.tsx @@ -0,0 +1,17 @@ +import { SettingsIcon } from '@blocksuite/icons'; +import { styled } from '@/styles'; +import { IconButton } from '@/ui/button'; + +export const FooterSetting = () => { + return ( + + + + ); +}; + +const Wrapper = styled(IconButton)(({ theme }) => { + return { + fontSize: '20px', + }; +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/FooterUsers.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/FooterUsers.tsx new file mode 100644 index 0000000000..1a067faa9b --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/FooterUsers.tsx @@ -0,0 +1,25 @@ +import { UsersIcon } from '@blocksuite/icons'; +import { styled } from '@/styles'; +import { IconButton } from '@/ui/button'; + +export const FooterUsers = () => { + return ( + + <> + + 99+ + + + ); +}; + +const Wrapper = styled(IconButton)({ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + fontSize: '16px', +}); + +const Tip = styled('span')({ + fontSize: '12px', +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/WorkspaceItem.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/WorkspaceItem.tsx new file mode 100644 index 0000000000..9f0e6d735e --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/WorkspaceItem.tsx @@ -0,0 +1,64 @@ +import { styled } from '@/styles'; +import { + WorkspaceItemAvatar, + WorkspaceItemWrapper, + WorkspaceItemContent, +} from '../styles'; +import { FooterSetting } from './FooterSetting'; +import { FooterUsers } from './FooterUsers'; + +interface WorkspaceItemProps { + id: string; + name: string; + icon: string; +} + +export const WorkspaceItem = ({ name, icon }: WorkspaceItemProps) => { + return ( + + + {name.charAt(0)} + + + {name} + +
+ + +
+
+ ); +}; + +const Name = styled('div')(({ theme }) => { + return { + color: theme.colors.quoteColor, + fontSize: theme.font.sm, + fontWeight: 400, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }; +}); + +const StyledWrapper = styled(WorkspaceItemWrapper)({ + '& .footer-setting': { + display: 'none', + }, + ':hover .footer-users': { + display: 'none', + }, + ':hover .footer-setting': { + display: 'block', + }, +}); + +const Footer = styled('div')({ + width: '42px', + flex: '0 42px', + fontSize: '20px', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + marginLeft: '12px', +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/index.ts b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/index.ts new file mode 100644 index 0000000000..60080d5a77 --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/index.ts @@ -0,0 +1 @@ +export * from './WorkspaceItem'; diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/index.ts b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/index.ts new file mode 100644 index 0000000000..35bf8e4cf9 --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/index.ts @@ -0,0 +1,5 @@ +export * from './PrivateWorkspaceItem'; +export * from './WorkspaceItem'; +export * from './CreateWorkspaceItem'; +export * from './ListItem'; +export * from './LoginItem'; diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/styles.ts b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/styles.ts new file mode 100644 index 0000000000..add82c90c7 --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/styles.ts @@ -0,0 +1,41 @@ +import MuiAvatar from '@mui/material/Avatar'; +import { styled } from '@/styles'; + +export const WorkspaceItemWrapper = styled('div')(({ theme }) => ({ + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + cursor: 'pointer', + borderRadius: '5px', + padding: '6px 12px', + + ':hover': { + color: theme.colors.primaryColor, + backgroundColor: theme.colors.hoverBackground, + }, +})); + +export const PrivateWorkspaceWrapper = styled(WorkspaceItemWrapper)({ + padding: '10px 12px', +}); + +export const LoginItemWrapper = styled(WorkspaceItemWrapper)(({ theme }) => { + return { + padding: '10px 12px', + + ':hover .login-description': { + color: theme.colors.primaryColor, + }, + }; +}); + +export const WorkspaceItemAvatar = styled(MuiAvatar)({ + height: '40px', + width: '40px', +}); + +export const WorkspaceItemContent = styled('div')({ + minWidth: 0, + marginLeft: '12px', + flexGrow: 1, +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx new file mode 100644 index 0000000000..b6bd822717 --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx @@ -0,0 +1,18 @@ +import { Popper } from '@/ui/popper'; +import { Avatar, WorkspaceName, SelectorWrapper } from './styles'; +import { SelectorPopperContent } from './SelectorPopperContent'; + +export const WorkspaceSelector = () => { + return ( + } + zIndex={1000} + placement="bottom-start" + > + + + AFFiNE + + + ); +}; diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/index.ts b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/index.ts new file mode 100644 index 0000000000..7de8a3ee0a --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/index.ts @@ -0,0 +1 @@ +export * from './WorkspaceSelector'; diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/styles.ts b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/styles.ts new file mode 100644 index 0000000000..75d16aa3ff --- /dev/null +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/styles.ts @@ -0,0 +1,38 @@ +import MuiAvatar from '@mui/material/Avatar'; +import { styled } from '@/styles'; +import { StyledPopperContainer } from '@/ui/shared/Container'; + +export const SelectorWrapper = styled('div')({ + width: '100%', + height: '100%', + display: 'flex', + flexDirection: 'row', + alignItems: 'center', +}); + +export const Avatar = styled(MuiAvatar)({ + height: '28px', + width: '28px', +}); + +export const WorkspaceName = styled('span')(({ theme }) => { + return { + marginLeft: '12px', + lineHeight: 1, + fontSize: '18px', + fontWeight: 500, + color: theme.colors.iconColor, + }; +}); + +export const SelectorPopperContainer = styled(StyledPopperContainer)( + ({ theme }) => { + return { + width: '334px', + boxShadow: theme.shadow.tooltip, + padding: '24px 12px', + backgroundColor: theme.colors.pageBackground, + fontSize: theme.font.xs, + }; + } +); diff --git a/packages/app/src/components/workspace-slider-bar/index.tsx b/packages/app/src/components/workspace-slider-bar/index.tsx index 1ceff4ecb0..b7d4914375 100644 --- a/packages/app/src/components/workspace-slider-bar/index.tsx +++ b/packages/app/src/components/workspace-slider-bar/index.tsx @@ -4,6 +4,7 @@ import { StyledArrowButton, StyledLink, StyledListItem, + StyledListItemForWorkspace, StyledNewPageButton, StyledSliderBar, StyledSubListItem, @@ -25,6 +26,7 @@ import { useEditor } from '@/providers/editor-provider'; import { useModal } from '@/providers/global-modal-provider'; import { IconButton } from '@/ui/button'; +import { WorkspaceSelector } from './WorkspaceSelector'; import useLocalStorage from '@/hooks/use-local-storage'; import { useTranslation } from '@/libs/i18n'; const FavoriteList = ({ showList }: { showList: boolean }) => { @@ -69,6 +71,9 @@ export const WorkSpaceSliderBar = () => { return ( <> + + + { @@ -80,7 +85,7 @@ export const WorkSpaceSliderBar = () => { - {t('All pages')} + All pages diff --git a/packages/app/src/components/workspace-slider-bar/style.ts b/packages/app/src/components/workspace-slider-bar/style.ts index 229565ff2d..08c32092ec 100644 --- a/packages/app/src/components/workspace-slider-bar/style.ts +++ b/packages/app/src/components/workspace-slider-bar/style.ts @@ -67,6 +67,10 @@ export const StyledListItem = styled.button<{ active?: boolean }>( } ); +export const StyledListItemForWorkspace = styled(StyledListItem)({ + height: '52px', +}); + export const StyledLink = styled(Link)(({ theme }) => { return { flexGrow: 1, diff --git a/packages/app/src/libs/i18n/resources/index.ts b/packages/app/src/libs/i18n/resources/index.ts index 134a47c9c0..329fa9c679 100644 --- a/packages/app/src/libs/i18n/resources/index.ts +++ b/packages/app/src/libs/i18n/resources/index.ts @@ -9,64 +9,64 @@ import fr from './fr.json'; import bn from './bn.json'; export const LOCALES = [ - { - id: 1000016008, - name: 'English', - tag: 'en', - originalName: 'English', - flagEmoji: '🇬🇧', - base: true, - completeRate: 1, - res: en, - }, - { - id: 1000016009, - name: 'Simplified Chinese', - tag: 'zh-Hans', - originalName: '简体中文', - flagEmoji: '🇨🇳', - base: false, - completeRate: 1, - res: zh_Hans, - }, - { - id: 1000016012, - name: 'Traditional Chinese', - tag: 'zh-Hant', - originalName: '繁體中文', - flagEmoji: '🇭🇰', - base: false, - completeRate: 1, - res: zh_Hant, - }, - { - id: 1000034005, - name: 'Serbian', - tag: 'sr', - originalName: 'српски', - flagEmoji: '🇷🇸', - base: false, - completeRate: 0.9166666666666666, - res: sr, - }, - { - id: 1000034008, - name: 'French', - tag: 'fr', - originalName: 'français', - flagEmoji: '🇫🇷', - base: false, - completeRate: 1, - res: fr, - }, - { - id: 1000034010, - name: 'Bangla', - tag: 'bn', - originalName: 'বাংলা', - flagEmoji: '🇧🇩', - base: false, - completeRate: 0.7083333333333334, - res: bn, - }, + { + id: 1000016008, + name: 'English', + tag: 'en', + originalName: 'English', + flagEmoji: '🇬🇧', + base: true, + completeRate: 1, + res: en, + }, + { + id: 1000016009, + name: 'Simplified Chinese', + tag: 'zh-Hans', + originalName: '简体中文', + flagEmoji: '🇨🇳', + base: false, + completeRate: 1, + res: zh_Hans, + }, + { + id: 1000016012, + name: 'Traditional Chinese', + tag: 'zh-Hant', + originalName: '繁體中文', + flagEmoji: '🇭🇰', + base: false, + completeRate: 1, + res: zh_Hant, + }, + { + id: 1000034005, + name: 'Serbian', + tag: 'sr', + originalName: 'српски', + flagEmoji: '🇷🇸', + base: false, + completeRate: 0.9166666666666666, + res: sr, + }, + { + id: 1000034008, + name: 'French', + tag: 'fr', + originalName: 'français', + flagEmoji: '🇫🇷', + base: false, + completeRate: 1, + res: fr, + }, + { + id: 1000034010, + name: 'Bangla', + tag: 'bn', + originalName: 'বাংলা', + flagEmoji: '🇧🇩', + base: false, + completeRate: 0.7083333333333334, + res: bn, + }, ] as const; diff --git a/packages/app/src/libs/i18n/scripts/api.ts b/packages/app/src/libs/i18n/scripts/api.ts index b38ad5875b..44f8a574fd 100644 --- a/packages/app/src/libs/i18n/scripts/api.ts +++ b/packages/app/src/libs/i18n/scripts/api.ts @@ -44,26 +44,25 @@ import { fetchTolgee } from './request'; * ``` */ export const getAllProjectLanguages = async (size = 1000) => { - const url = `/languages?size=${size}`; - const resp = await fetchTolgee(url); - if (resp.status < 200 || resp.status >= 300) { - throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); - } - const json: { - // eslint-disable-next-line @typescript-eslint/naming-convention - _embedded: { - languages: { - id: number; - name: string; - tag: string; - originalName: string; - flagEmoji: string; - base: boolean; - }[]; - }; - page: unknown; - } = await resp.json(); - return json._embedded.languages; + const url = `/languages?size=${size}`; + const resp = await fetchTolgee(url); + if (resp.status < 200 || resp.status >= 300) { + throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); + } + const json: { + _embedded: { + languages: { + id: number; + name: string; + tag: string; + originalName: string; + flagEmoji: string; + base: boolean; + }[]; + }; + page: unknown; + } = await resp.json(); + return json._embedded.languages; }; /** @@ -72,13 +71,13 @@ export const getAllProjectLanguages = async (size = 1000) => { * See https://tolgee.io/api#operation/getTranslations_ */ export const getTranslations = async () => { - const url = '/translations'; - const resp = await fetchTolgee(url); - if (resp.status < 200 || resp.status >= 300) { - throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); - } - const json = await resp.json(); - return json; + const url = '/translations'; + const resp = await fetchTolgee(url); + if (resp.status < 200 || resp.status >= 300) { + throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); + } + const json = await resp.json(); + return json; }; /** @@ -87,25 +86,24 @@ export const getTranslations = async () => { * See https://tolgee.io/api#operation/getAllTranslations_1 */ export const getLanguagesTranslations = async ( - languages: T + languages: T ) => { - const url = `/translations/${languages}`; - const resp = await fetchTolgee(url); - if (resp.status < 200 || resp.status >= 300) { - throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); - } - const json: { [key in T]?: Record } = await resp.json(); - return json; + const url = `/translations/${languages}`; + const resp = await fetchTolgee(url); + if (resp.status < 200 || resp.status >= 300) { + throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); + } + const json: { [key in T]?: Record } = await resp.json(); + return json; }; export const getRemoteTranslations = async (languages: string) => { - const translations = await getLanguagesTranslations(languages); - if (!(languages in translations)) { - return {}; - } - // The assert is safe because we checked above - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return translations[languages]!; + const translations = await getLanguagesTranslations(languages); + if (!(languages in translations)) { + return {}; + } + // The assert is safe because we checked above + return translations[languages]!; }; /** @@ -114,19 +112,19 @@ export const getRemoteTranslations = async (languages: string) => { * See https://tolgee.io/api#operation/create_2 */ export const createsNewKey = async ( - key: string, - translations: Record + key: string, + translations: Record ) => { - const url = '/translations/keys/create'; - const resp = await fetchTolgee(url, { - method: 'POST', - body: JSON.stringify({ name: key, translations }), - }); - if (resp.status < 200 || resp.status >= 300) { - throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); - } - const json = await resp.json(); - return json; + const url = '/translations/keys/create'; + const resp = await fetchTolgee(url, { + method: 'POST', + body: JSON.stringify({ name: key, translations }), + }); + if (resp.status < 200 || resp.status >= 300) { + throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); + } + const json = await resp.json(); + return json; }; /** @@ -135,16 +133,16 @@ export const createsNewKey = async ( * See https://tolgee.io/api#operation/tagKey_1 */ export const addTag = async (keyId: string, tagName: string) => { - const url = `/keys/${keyId}/tags`; - const resp = await fetchTolgee(url, { - method: 'PUT', - body: JSON.stringify({ name: tagName }), - }); - if (resp.status < 200 || resp.status >= 300) { - throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); - } - const json = await resp.json(); - return json; + const url = `/keys/${keyId}/tags`; + const resp = await fetchTolgee(url, { + method: 'PUT', + body: JSON.stringify({ name: tagName }), + }); + if (resp.status < 200 || resp.status >= 300) { + throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); + } + const json = await resp.json(); + return json; }; /** @@ -153,21 +151,21 @@ export const addTag = async (keyId: string, tagName: string) => { * See https://tolgee.io/api#operation/tagKey_1 */ export const removeTag = async (keyId: string, tagId: number) => { - const url = `/keys/${keyId}/tags/${tagId}`; - const resp = await fetchTolgee(url, { - method: 'DELETE', - }); - if (resp.status < 200 || resp.status >= 300) { - throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); - } - const json = await resp.json(); - return json; + const url = `/keys/${keyId}/tags/${tagId}`; + const resp = await fetchTolgee(url, { + method: 'DELETE', + }); + if (resp.status < 200 || resp.status >= 300) { + throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); + } + const json = await resp.json(); + return json; }; export const addTagByKey = async (key: string, tag: string) => { - // TODO get key id by key name - // const keyId = - // addTag(keyId, tag); + // TODO get key id by key name + // const keyId = + // addTag(keyId, tag); }; /** @@ -176,11 +174,11 @@ export const addTagByKey = async (key: string, tag: string) => { * See https://tolgee.io/api#operation/export_1 */ export const exportResources = async () => { - const url = `/export`; - const resp = await fetchTolgee(url); + const url = `/export`; + const resp = await fetchTolgee(url); - if (resp.status < 200 || resp.status >= 300) { - throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); - } - return resp; + if (resp.status < 200 || resp.status >= 300) { + throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); + } + return resp; }; diff --git a/packages/app/src/libs/i18n/scripts/download.ts b/packages/app/src/libs/i18n/scripts/download.ts index f45261c258..11e819f83b 100644 --- a/packages/app/src/libs/i18n/scripts/download.ts +++ b/packages/app/src/libs/i18n/scripts/download.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ // cSpell:ignore Tolgee import fs from 'node:fs/promises'; import path from 'node:path'; @@ -9,126 +8,123 @@ import type { TranslationRes } from './utils'; const RES_DIR = path.resolve(process.cwd(), 'src', 'resources'); const countKeys = (obj: TranslationRes) => { - let count = 0; - Object.entries(obj).forEach(([key, value]) => { - if (typeof value === 'string') { - count++; - } else { - count += countKeys(value); - } - }); - return count; + let count = 0; + Object.entries(obj).forEach(([key, value]) => { + if (typeof value === 'string') { + count++; + } else { + count += countKeys(value); + } + }); + return count; }; const getBaseTranslations = async (baseLanguage: { tag: string }) => { - try { - const baseTranslationsStr = await fs.readFile( - path.resolve(RES_DIR, `${baseLanguage.tag}.json`), - { encoding: 'utf8' } - ); - const baseTranslations = JSON.parse(baseTranslationsStr); - return baseTranslations; - } catch (e) { - console.error('base language:', JSON.stringify(baseLanguage)); - console.error('Failed to read base language', e); - const translations = await getRemoteTranslations(baseLanguage.tag); - await fs.writeFile( - path.resolve(RES_DIR, `${baseLanguage.tag}.json`), - JSON.stringify(translations, null, 4) - ); - } + try { + const baseTranslationsStr = await fs.readFile( + path.resolve(RES_DIR, `${baseLanguage.tag}.json`), + { encoding: 'utf8' } + ); + const baseTranslations = JSON.parse(baseTranslationsStr); + return baseTranslations; + } catch (e) { + console.error('base language:', JSON.stringify(baseLanguage)); + console.error('Failed to read base language', e); + const translations = await getRemoteTranslations(baseLanguage.tag); + await fs.writeFile( + path.resolve(RES_DIR, `${baseLanguage.tag}.json`), + JSON.stringify(translations, null, 4) + ); + } }; const main = async () => { - console.log('Loading project languages...'); - const languages = await getAllProjectLanguages(); - const baseLanguage = languages.find(language => language.base); - if (!baseLanguage) { - console.error(JSON.stringify(languages)); - throw new Error('Could not find base language'); - } - console.log( - `Loading ${baseLanguage.tag} languages translations as base...` - ); + console.log('Loading project languages...'); + const languages = await getAllProjectLanguages(); + const baseLanguage = languages.find(language => language.base); + if (!baseLanguage) { + console.error(JSON.stringify(languages)); + throw new Error('Could not find base language'); + } + console.log(`Loading ${baseLanguage.tag} languages translations as base...`); - const baseTranslations = await getBaseTranslations(baseLanguage); - const baseKeyNum = countKeys(baseTranslations); - const languagesWithTranslations = await Promise.all( - languages.map(async language => { - console.log(`Loading ${language.tag} translations...`); - const translations = await getRemoteTranslations(language.tag); - const keyNum = countKeys(translations); + const baseTranslations = await getBaseTranslations(baseLanguage); + const baseKeyNum = countKeys(baseTranslations); + const languagesWithTranslations = await Promise.all( + languages.map(async language => { + console.log(`Loading ${language.tag} translations...`); + const translations = await getRemoteTranslations(language.tag); + const keyNum = countKeys(translations); - return { - ...language, - translations, - completeRate: keyNum / baseKeyNum, - }; - }) - ); + return { + ...language, + translations, + completeRate: keyNum / baseKeyNum, + }; + }) + ); - const availableLanguages = languagesWithTranslations.filter( - language => language.completeRate > 0 - ); + const availableLanguages = languagesWithTranslations.filter( + language => language.completeRate > 0 + ); - availableLanguages - // skip base language - .filter(i => !i.base) - .forEach(async language => { - await fs.writeFile( - path.resolve(RES_DIR, `${language.tag}.json`), - JSON.stringify( - { - // eslint-disable-next-line @typescript-eslint/naming-convention - '// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.': - '', - ...language.translations, - }, - null, - 4 - ) + '\n' - ); - }); + availableLanguages + // skip base language + .filter(i => !i.base) + .forEach(async language => { + await fs.writeFile( + path.resolve(RES_DIR, `${language.tag}.json`), + JSON.stringify( + { + '// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.': + '', + ...language.translations, + }, + null, + 4 + ) + '\n' + ); + }); - console.log('Generating meta data...'); - const code = `// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + console.log('Generating meta data...'); + const code = `// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. // Run \`pnpm run download-resources\` to regenerate. // To overwrite this, please overwrite ${path.basename(__filename)} ${availableLanguages - .map( - language => - `import ${language.tag.replaceAll('-', '_')} from './${ - language.tag - }.json'` - ) - .join('\n')} + .map( + language => + `import ${language.tag.replaceAll('-', '_')} from './${ + language.tag + }.json'` + ) + .join('\n')} export const LOCALES = [ ${availableLanguages - .map(({ translations, ...language }) => - JSON.stringify({ - ...language, - res: '__RES_PLACEHOLDER', - }).replace( - '"__RES_PLACEHOLDER"', - language.tag.replaceAll('-', '_') - ) + .map(({ translations, ...language }) => + JSON.stringify({ + ...language, + res: '__RES_PLACEHOLDER', + }).replace( + '"__RES_PLACEHOLDER"', + language.tag.replaceAll('-', '_') ) - .join(',\n')} + ) + .join(',\n')} ] as const; `; - await fs.writeFile( - path.resolve(RES_DIR, 'index.ts'), - format(code, { - parser: 'typescript', - singleQuote: true, - trailingComma: 'es5', - tabWidth: 4, - arrowParens: 'avoid', - }) - ); - console.log('Done'); + await fs.writeFile( + path.resolve(RES_DIR, 'index.ts'), + format(code, { + parser: 'typescript', + singleQuote: true, + trailingComma: 'es5', + tabWidth: 4, + arrowParens: 'avoid', + }) + ); + console.log('Done'); }; main(); diff --git a/packages/app/src/libs/i18n/scripts/request.ts b/packages/app/src/libs/i18n/scripts/request.ts index b599c71957..717477d389 100644 --- a/packages/app/src/libs/i18n/scripts/request.ts +++ b/packages/app/src/libs/i18n/scripts/request.ts @@ -3,53 +3,53 @@ const TOLGEE_API_KEY = process.env['TOLGEE_API_KEY']; const TOLGEE_API_URL = 'https://i18n.affine.pro'; if (!TOLGEE_API_KEY) { - throw new Error(`Please set "TOLGEE_API_KEY" as environment variable!`); + throw new Error(`Please set "TOLGEE_API_KEY" as environment variable!`); } const withTolgee = ( - fetch: typeof globalThis.fetch + fetch: typeof globalThis.fetch ): typeof globalThis.fetch => { - const baseUrl = `${TOLGEE_API_URL}/v2/projects`; - const headers = new Headers({ - 'X-API-Key': TOLGEE_API_KEY, - 'Content-Type': 'application/json', - }); + const baseUrl = `${TOLGEE_API_URL}/v2/projects`; + const headers = new Headers({ + 'X-API-Key': TOLGEE_API_KEY, + 'Content-Type': 'application/json', + }); - const isRequest = (input: RequestInfo | URL): input is Request => { - return typeof input === 'object' && !('href' in input); - }; + const isRequest = (input: RequestInfo | URL): input is Request => { + return typeof input === 'object' && !('href' in input); + }; - return new Proxy(fetch, { - apply( - target, - thisArg: unknown, - argArray: Parameters - ) { - if (isRequest(argArray[0])) { - // Request - if (!argArray[0].headers) { - argArray[0] = { - ...argArray[0], - url: `${baseUrl}${argArray[0].url}`, - headers, - }; - } - } else { - // URL or URLLike + ?RequestInit - if (typeof argArray[0] === 'string') { - argArray[0] = `${baseUrl}${argArray[0]}`; - } - if (!argArray[1]) { - argArray[1] = {}; - } - if (!argArray[1].headers) { - argArray[1].headers = headers; - } - } - // console.log('fetch', argArray); - return target.apply(thisArg, argArray); - }, - }); + return new Proxy(fetch, { + apply( + target, + thisArg: unknown, + argArray: Parameters + ) { + if (isRequest(argArray[0])) { + // Request + if (!argArray[0].headers) { + argArray[0] = { + ...argArray[0], + url: `${baseUrl}${argArray[0].url}`, + headers, + }; + } + } else { + // URL or URLLike + ?RequestInit + if (typeof argArray[0] === 'string') { + argArray[0] = `${baseUrl}${argArray[0]}`; + } + if (!argArray[1]) { + argArray[1] = {}; + } + if (!argArray[1].headers) { + argArray[1].headers = headers; + } + } + // console.log('fetch', argArray); + return target.apply(thisArg, argArray); + }, + }); }; export const fetchTolgee = withTolgee(globalThis.fetch); diff --git a/packages/app/src/libs/i18n/scripts/sync.ts b/packages/app/src/libs/i18n/scripts/sync.ts index c2ba692dc5..0a9a96b415 100644 --- a/packages/app/src/libs/i18n/scripts/sync.ts +++ b/packages/app/src/libs/i18n/scripts/sync.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ // cSpell:ignore Tolgee import { readFile } from 'fs/promises'; import path from 'path'; @@ -6,10 +5,10 @@ import { addTagByKey, createsNewKey, getRemoteTranslations } from './api'; import type { TranslationRes } from './utils'; const BASE_JSON_PATH = path.resolve( - process.cwd(), - 'src', - 'resources', - 'en.json' + process.cwd(), + 'src', + 'resources', + 'en.json' ); const BASE_LANGUAGES = 'en' as const; @@ -23,142 +22,135 @@ const DEPRECATED_TAG_NAME = 'unused' as const; * ``` */ const flatRes = (obj: TranslationRes) => { - const getEntries = (o: TranslationRes, prefix = ''): [string, string][] => - Object.entries(o).flatMap<[string, string]>(([k, v]) => - typeof v !== 'string' - ? getEntries(v, `${prefix}${k}.`) - : [[`${prefix}${k}`, v]] - ); - return Object.fromEntries(getEntries(obj)); + const getEntries = (o: TranslationRes, prefix = ''): [string, string][] => + Object.entries(o).flatMap<[string, string]>(([k, v]) => + typeof v !== 'string' + ? getEntries(v, `${prefix}${k}.`) + : [[`${prefix}${k}`, v]] + ); + return Object.fromEntries(getEntries(obj)); }; const differenceObject = ( - newObj: Record, - oldObj: Record + newObj: Record, + oldObj: Record ) => { - const add: string[] = []; - const remove: string[] = []; - const modify: string[] = []; - const both: string[] = []; + const add: string[] = []; + const remove: string[] = []; + const modify: string[] = []; + const both: string[] = []; - Object.keys(newObj).forEach(key => { - if (!(key in oldObj)) { - add.push(key); - } else { - both.push(key); - } - }); + Object.keys(newObj).forEach(key => { + if (!(key in oldObj)) { + add.push(key); + } else { + both.push(key); + } + }); - Object.keys(oldObj).forEach(key => { - if (!(key in newObj)) { - remove.push(key); - } - }); + Object.keys(oldObj).forEach(key => { + if (!(key in newObj)) { + remove.push(key); + } + }); - both.forEach(key => { - if (!(key in newObj) || !(key in oldObj)) { - throw new Error('Unreachable'); - } - const newVal = newObj[key]; - const oldVal = oldObj[key]; - if (newVal !== oldVal) { - modify.push(key); - } - }); - return { add, remove, modify }; + both.forEach(key => { + if (!(key in newObj) || !(key in oldObj)) { + throw new Error('Unreachable'); + } + const newVal = newObj[key]; + const oldVal = oldObj[key]; + if (newVal !== oldVal) { + modify.push(key); + } + }); + return { add, remove, modify }; }; function warnDiff(diff: { add: string[]; remove: string[]; modify: string[] }) { - if (diff.add.length) { - console.log('New keys found:', diff.add.join(', ')); - //See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-a-notice-message - process.env['CI'] && - console.log( - `::notice file=${BASE_JSON_PATH},line=1,title=New keys::${diff.add.join( - ', ' - )}` - ); - } - if (diff.remove.length) { - console.warn('[WARN]', 'Unused keys found:', diff.remove.join(', ')); - process.env['CI'] && - console.warn( - `::notice file=${BASE_JSON_PATH},line=1,title=Unused keys::${diff.remove.join( - ', ' - )}` - ); - } - if (diff.modify.length) { - console.warn( - '[WARN]', - 'Inconsistent keys found:', - diff.modify.join(', ') - ); - process.env['CI'] && - console.warn( - `::warning file=${BASE_JSON_PATH},line=1,title=Inconsistent keys::${diff.modify.join( - ', ' - )}` - ); - } + if (diff.add.length) { + console.log('New keys found:', diff.add.join(', ')); + //See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-a-notice-message + process.env['CI'] && + console.log( + `::notice file=${BASE_JSON_PATH},line=1,title=New keys::${diff.add.join( + ', ' + )}` + ); + } + if (diff.remove.length) { + console.warn('[WARN]', 'Unused keys found:', diff.remove.join(', ')); + process.env['CI'] && + console.warn( + `::notice file=${BASE_JSON_PATH},line=1,title=Unused keys::${diff.remove.join( + ', ' + )}` + ); + } + if (diff.modify.length) { + console.warn('[WARN]', 'Inconsistent keys found:', diff.modify.join(', ')); + process.env['CI'] && + console.warn( + `::warning file=${BASE_JSON_PATH},line=1,title=Inconsistent keys::${diff.modify.join( + ', ' + )}` + ); + } } const main = async () => { - console.log('Loading local base translations...'); - const baseLocalTranslations = JSON.parse( - await readFile(BASE_JSON_PATH, { - encoding: 'utf8', - }) - ); - const flatLocalTranslations = flatRes(baseLocalTranslations); - console.log( - `Loading local base translations success! Total ${ - Object.keys(flatLocalTranslations).length - } keys` - ); + console.log('Loading local base translations...'); + const baseLocalTranslations = JSON.parse( + await readFile(BASE_JSON_PATH, { + encoding: 'utf8', + }) + ); + const flatLocalTranslations = flatRes(baseLocalTranslations); + console.log( + `Loading local base translations success! Total ${ + Object.keys(flatLocalTranslations).length + } keys` + ); - console.log('Fetch remote base translations...'); - const baseRemoteTranslations = await getRemoteTranslations(BASE_LANGUAGES); - const flatRemoteTranslations = flatRes(baseRemoteTranslations); - console.log( - `Fetch remote base translations success! Total ${ - Object.keys(flatRemoteTranslations).length - } keys` - ); + console.log('Fetch remote base translations...'); + const baseRemoteTranslations = await getRemoteTranslations(BASE_LANGUAGES); + const flatRemoteTranslations = flatRes(baseRemoteTranslations); + console.log( + `Fetch remote base translations success! Total ${ + Object.keys(flatRemoteTranslations).length + } keys` + ); - const diff = differenceObject( - flatLocalTranslations, - flatRemoteTranslations - ); + const diff = differenceObject(flatLocalTranslations, flatRemoteTranslations); - console.log(''); // new line - warnDiff(diff); - console.log(''); // new line + console.log(''); // new line + warnDiff(diff); + console.log(''); // new line - if (process.argv.slice(2).includes('--check')) { - // check mode - return; - } + if (process.argv.slice(2).includes('--check')) { + // check mode + return; + } - diff.add.forEach(async key => { - const val = flatLocalTranslations[key]; - console.log(`Creating new key: ${key} -> ${val}`); - await createsNewKey(key, { [BASE_LANGUAGES]: val }); - }); + diff.add.forEach(async key => { + const val = flatLocalTranslations[key]; + console.log(`Creating new key: ${key} -> ${val}`); + await createsNewKey(key, { [BASE_LANGUAGES]: val }); + }); - // TODO remove unused tags from used keys + // TODO remove unused tags from used keys - diff.remove.forEach(key => { - // TODO set unused tag - // console.log(`Add ${DEPRECATED_TAG_NAME} to ${key}`); - addTagByKey(key, DEPRECATED_TAG_NAME); - }); + diff.remove.forEach(key => { + // TODO set unused tag + // console.log(`Add ${DEPRECATED_TAG_NAME} to ${key}`); + addTagByKey(key, DEPRECATED_TAG_NAME); + }); - diff.modify.forEach(key => { - // TODO warn different between local and remote base translations - }); + diff.modify.forEach(key => { + // TODO warn different between local and remote base translations + }); - // TODO send notification + // TODO send notification }; main(); diff --git a/packages/app/src/libs/i18n/scripts/utils.ts b/packages/app/src/libs/i18n/scripts/utils.ts index 129a8febc3..c17e3446be 100644 --- a/packages/app/src/libs/i18n/scripts/utils.ts +++ b/packages/app/src/libs/i18n/scripts/utils.ts @@ -1,3 +1,3 @@ export interface TranslationRes { - [x: string]: string | TranslationRes; + [x: string]: string | TranslationRes; } diff --git a/packages/app/src/pages-content/ConfirmInvitationPage/AlreadyJoined.tsx b/packages/app/src/pages-content/ConfirmInvitationPage/AlreadyJoined.tsx new file mode 100644 index 0000000000..d3812e9451 --- /dev/null +++ b/packages/app/src/pages-content/ConfirmInvitationPage/AlreadyJoined.tsx @@ -0,0 +1,10 @@ +export const AlreadyJoined = () => { + return ( +
+

+ You are already a member of Workspace name +

+ +
+ ); +}; diff --git a/packages/app/src/pages-content/ConfirmInvitationPage/Confirm.tsx b/packages/app/src/pages-content/ConfirmInvitationPage/Confirm.tsx new file mode 100644 index 0000000000..b447026044 --- /dev/null +++ b/packages/app/src/pages-content/ConfirmInvitationPage/Confirm.tsx @@ -0,0 +1,11 @@ +export const Confirm = () => { + return ( +
+

Inviter name

+

+ invite you to join in Workspace name +

+ +
+ ); +}; diff --git a/packages/app/src/pages-content/ConfirmInvitationPage/LinkExpired.tsx b/packages/app/src/pages-content/ConfirmInvitationPage/LinkExpired.tsx new file mode 100644 index 0000000000..8bdd4e6d54 --- /dev/null +++ b/packages/app/src/pages-content/ConfirmInvitationPage/LinkExpired.tsx @@ -0,0 +1,8 @@ +export const LinkExpired = () => { + return ( +
+

The current invitation link has expired.

+ Back to home +
+ ); +}; diff --git a/packages/app/src/pages-content/ConfirmInvitationPage/index.tsx b/packages/app/src/pages-content/ConfirmInvitationPage/index.tsx new file mode 100644 index 0000000000..2bf8010c70 --- /dev/null +++ b/packages/app/src/pages-content/ConfirmInvitationPage/index.tsx @@ -0,0 +1,21 @@ +import { useRouter } from 'next/router'; +import { AlreadyJoined } from './AlreadyJoined'; +import { Confirm } from './Confirm'; +import { LinkExpired } from './LinkExpired'; + +export const ConfirmInvitation = () => { + const router = useRouter(); + // Temporary code. The code should be returned by request. + const { code } = router.query; + const Component = { + '-1': LinkExpired, + 0: Confirm, + 1: AlreadyJoined, + }[code as string]; + return ( +
+

Confirm Invitation

+ {Component ? : null} +
+ ); +}; diff --git a/packages/app/src/pages/404.tsx b/packages/app/src/pages/404.tsx new file mode 100644 index 0000000000..87ab0471be --- /dev/null +++ b/packages/app/src/pages/404.tsx @@ -0,0 +1,4 @@ +import NotfoundPage from '@/components/404'; +export default function Custom404() { + return ; +} diff --git a/packages/app/src/pages/_app.tsx b/packages/app/src/pages/_app.tsx index eda404eee2..765e8324d8 100644 --- a/packages/app/src/pages/_app.tsx +++ b/packages/app/src/pages/_app.tsx @@ -5,6 +5,7 @@ import '../../public/variable.css'; import './temporary.css'; import { EditorProvider } from '@/providers/editor-provider'; import { ModalProvider } from '@/providers/global-modal-provider'; +import { AppStateProvider } from '@/providers/app-state-provider'; import { Logger } from '@toeverything/pathfinder-logger'; import { WorkSpaceSliderBar } from '@/components/workspace-slider-bar'; import '@fontsource/space-mono'; @@ -49,6 +50,7 @@ function MyApp({ Component, pageProps }: AppProps) { , , , + , ]} > diff --git a/packages/app/src/pages/affine/[workspace_id].tsx b/packages/app/src/pages/affine/[workspace_id].tsx new file mode 100644 index 0000000000..875928acf9 --- /dev/null +++ b/packages/app/src/pages/affine/[workspace_id].tsx @@ -0,0 +1,20 @@ +// for dynamic route get workspace id maybe path will change +import { useRouter } from 'next/router'; + +const Post = () => { + const router = useRouter(); + const { workspace_id } = router.query; + + return ( +

+ workspace_id: {workspace_id}, +

+ ); +}; + +export default Post; diff --git a/packages/app/src/pages/confirm-invitation.tsx b/packages/app/src/pages/confirm-invitation.tsx new file mode 100644 index 0000000000..ce3b436745 --- /dev/null +++ b/packages/app/src/pages/confirm-invitation.tsx @@ -0,0 +1,8 @@ +import type { NextPage } from 'next'; +import { ConfirmInvitation } from '../pages-content/ConfirmInvitationPage'; + +const ConfirmInvitationPage: NextPage = () => { + return ; +}; + +export default ConfirmInvitationPage; diff --git a/packages/app/src/providers/app-state-provider.tsx b/packages/app/src/providers/app-state-provider.tsx new file mode 100644 index 0000000000..28967ee5cc --- /dev/null +++ b/packages/app/src/providers/app-state-provider.tsx @@ -0,0 +1,57 @@ +import { createContext, useMemo, useContext, useState, useEffect } from 'react'; +import type { ReactNode } from 'react'; +import { + authorizationEvent, + AccessTokenMessage, + getWorkspaces, +} from '@pathfinder/data-services'; +import type { Workspace } from '@pathfinder/data-services'; + +interface AppStateValue { + user: AccessTokenMessage | null; + workspaces: Workspace[]; +} + +interface AppStateContext extends AppStateValue { + setState: (state: AppStateValue) => void; +} + +const AppState = createContext({ + user: null, + workspaces: [], + setState: () => {}, +}); + +export const AppStateProvider = ({ children }: { children?: ReactNode }) => { + const [state, setState] = useState({ + user: null, + workspaces: [], + }); + + useEffect(() => { + const callback = async (user: AccessTokenMessage | null) => { + const workspaces = user ? await getWorkspaces() : []; + setState(state => ({ ...state, user: user, workspaces })); + }; + authorizationEvent.onChange(callback); + + return () => { + authorizationEvent.removeCallback(callback); + }; + }, []); + + const context = useMemo( + () => ({ + ...state, + setState, + }), + [state, setState] + ); + + return {children}; +}; + +export const useAppState = () => { + const state = useContext(AppState); + return state; +}; diff --git a/packages/app/src/providers/global-modal-provider.tsx b/packages/app/src/providers/global-modal-provider.tsx index 7c998a94a6..1db3698f20 100644 --- a/packages/app/src/providers/global-modal-provider.tsx +++ b/packages/app/src/providers/global-modal-provider.tsx @@ -4,12 +4,14 @@ import ShortcutsModal from '@/components/shortcuts-modal'; import ContactModal from '@/components/contact-modal'; import QuickSearch from '@/components/quick-search'; import { ImportModal } from '@/components/import'; +import { LoginModal } from '@/components/login-modal'; type ModalContextValue = { triggerShortcutsModal: () => void; triggerContactModal: () => void; triggerQuickSearchModal: (visible?: boolean) => void; triggerImportModal: () => void; + triggerLoginModal: () => void; }; type ModalContextProps = PropsWithChildren<{}>; type ModalMap = { @@ -17,6 +19,7 @@ type ModalMap = { shortcuts: boolean; quickSearch: boolean; import: boolean; + login: boolean; }; export const ModalContext = createContext({ @@ -24,6 +27,7 @@ export const ModalContext = createContext({ triggerContactModal: () => {}, triggerQuickSearchModal: (visible?) => {}, triggerImportModal: () => {}, + triggerLoginModal: () => {}, }); export const useModal = () => useContext(ModalContext); @@ -36,6 +40,7 @@ export const ModalProvider = ({ shortcuts: false, quickSearch: false, import: false, + login: false, }); const triggerHandler = (key: keyof ModalMap, visible?: boolean) => { @@ -60,6 +65,9 @@ export const ModalProvider = ({ triggerImportModal: () => { triggerHandler('import'); }, + triggerLoginModal: () => { + triggerHandler('login'); + }, }} > + { + triggerHandler('login', false); + }} + /> {children} ); diff --git a/packages/app/src/styles/theme.ts b/packages/app/src/styles/theme.ts index 54ca29691a..87917c981d 100644 --- a/packages/app/src/styles/theme.ts +++ b/packages/app/src/styles/theme.ts @@ -30,6 +30,7 @@ export const getLightTheme = ( linkColor2: '#6880FF', linkVisitedColor: '#ABB8FE', popoverColor: '#4C6275', + inputColor: '#4C6275', tooltipColor: '#fff', codeColor: '#517ea6', quoteColor: '#4C6275', @@ -105,6 +106,7 @@ export const getDarkTheme = ( linkColor2: '#6880FF', linkVisitedColor: '#505FAB', popoverColor: '#C6CBD9', + inputColor: '#C6CBD9', tooltipColor: '#fff', codeColor: editorMode === 'edgeless' ? lightTheme.colors.codeColor : '#BDDBFD', @@ -150,6 +152,7 @@ export const globalThemeVariables: ( '--affine-link-visited-color': theme.colors.linkVisitedColor, '--affine-icon-color': theme.colors.iconColor, '--affine-popover-color': theme.colors.popoverColor, + '--affine-input-color': theme.colors.inputColor, '--affine-code-color': theme.colors.codeColor, '--affine-quote-color': theme.colors.quoteColor, '--affine-selected-color': theme.colors.selectedColor, diff --git a/packages/app/src/styles/types.ts b/packages/app/src/styles/types.ts index b3c615009f..091fef98a1 100644 --- a/packages/app/src/styles/types.ts +++ b/packages/app/src/styles/types.ts @@ -37,6 +37,7 @@ export interface AffineTheme { linkVisitedColor: string; iconColor: string; popoverColor: string; + inputColor: string; tooltipColor: string; codeColor: string; quoteColor: string; diff --git a/packages/app/src/ui/button/icon-button.tsx b/packages/app/src/ui/button/icon-button.tsx index da40fbda57..79c3c48834 100644 --- a/packages/app/src/ui/button/icon-button.tsx +++ b/packages/app/src/ui/button/icon-button.tsx @@ -39,7 +39,7 @@ export type IconButtonProps = { | typeof SIZE_NORMAL | [number, number]; disabled?: boolean; - hoverBackground?: string; + hoverBackground?: CSSProperties['background']; hoverColor?: string; hoverStyle?: CSSProperties; children: ReactElement, 'svg'>; diff --git a/packages/app/src/ui/button/index.ts b/packages/app/src/ui/button/index.ts index 765395ea09..2e3ce65c43 100644 --- a/packages/app/src/ui/button/index.ts +++ b/packages/app/src/ui/button/index.ts @@ -1,2 +1,3 @@ export * from './icon-button'; export * from './button'; +export * from './text-button'; diff --git a/packages/app/src/ui/button/styles.ts b/packages/app/src/ui/button/styles.ts index 4400984446..9604266baa 100644 --- a/packages/app/src/ui/button/styles.ts +++ b/packages/app/src/ui/button/styles.ts @@ -21,7 +21,7 @@ export const StyledIconButton = styled('button', { height: number; borderRadius: number; disabled?: boolean; - hoverBackground?: string; + hoverBackground?: CSSProperties['background']; hoverColor?: string; hoverStyle?: CSSProperties; }>( @@ -68,6 +68,70 @@ export const StyledIconButton = styled('button', { }; } ); + +export const StyledTextButton = styled('button', { + shouldForwardProp: prop => { + return ![ + 'borderRadius', + 'top', + 'right', + 'width', + 'height', + 'hoverBackground', + 'hoverColor', + 'hoverStyle', + ].includes(prop); + }, +})< + Pick< + ButtonProps, + | 'size' + | 'disabled' + | 'hoverBackground' + | 'hoverColor' + | 'hoverStyle' + | 'shape' + | 'type' + | 'bold' + > +>( + ({ + theme, + size = 'default', + disabled, + hoverBackground, + hoverColor, + hoverStyle, + bold = false, + shape = 'default', + // TODO: Implement type + type = 'default', + }) => { + const { fontSize, borderRadius, padding, height } = getSize(size); + console.log('size', size, height); + + return { + height, + paddingLeft: padding, + paddingRight: padding, + ...displayInlineFlex('flex-start', 'center'), + position: 'relative', + ...(disabled ? { cursor: 'not-allowed', pointerEvents: 'none' } : {}), + transition: 'background .15s', + // TODO: Implement circle shape + borderRadius: shape === 'default' ? borderRadius : height / 2, + fontSize, + fontWeight: bold ? '500' : '400', + + ':hover': { + color: hoverColor ?? theme.colors.primaryColor, + background: hoverBackground ?? theme.colors.hoverBackground, + ...(hoverStyle ?? {}), + }, + }; + } +); + export const StyledButton = styled('button', { shouldForwardProp: prop => { return !['hoverBackground', 'hoverColor', 'hoverStyle', 'type'].includes( diff --git a/packages/app/src/ui/button/text-button.tsx b/packages/app/src/ui/button/text-button.tsx new file mode 100644 index 0000000000..7673ea13b7 --- /dev/null +++ b/packages/app/src/ui/button/text-button.tsx @@ -0,0 +1,53 @@ +import { cloneElement, Children, forwardRef } from 'react'; +import { StyledTextButton } from './styles'; + +import { ButtonProps } from './interface'; +import { getSize } from './utils'; + +export const TextButton = forwardRef( + ( + { + size = 'default', + disabled = false, + hoverBackground, + hoverColor, + hoverStyle, + shape = 'default', + icon, + type = 'default', + children, + bold = false, + ...props + }, + ref + ) => { + const { iconSize } = getSize(size); + + return ( + + {icon && + cloneElement(Children.only(icon), { + width: iconSize, + height: iconSize, + className: `affine-button-icon ${icon.props.className ?? ''}`, + })} + {children && {children}} + + ); + } +); +TextButton.displayName = 'TextButton'; + +export default TextButton; diff --git a/packages/app/src/ui/divider/index.ts b/packages/app/src/ui/divider/index.ts new file mode 100644 index 0000000000..9dd7505d63 --- /dev/null +++ b/packages/app/src/ui/divider/index.ts @@ -0,0 +1,8 @@ +import MuiDivider from '@mui/material/Divider'; +import { styled } from '@/styles'; + +export const Divider = styled(MuiDivider)(({ theme }) => { + return { + borderColor: theme.colors.borderColor, + }; +}); diff --git a/packages/app/src/ui/input/index.ts b/packages/app/src/ui/input/index.ts new file mode 100644 index 0000000000..faaa2f016e --- /dev/null +++ b/packages/app/src/ui/input/index.ts @@ -0,0 +1,3 @@ +export * from './input'; +import { Input } from './input'; +export default Input; diff --git a/packages/app/src/ui/input/input.tsx b/packages/app/src/ui/input/input.tsx new file mode 100644 index 0000000000..5cda33d51e --- /dev/null +++ b/packages/app/src/ui/input/input.tsx @@ -0,0 +1,37 @@ +import { InputHTMLAttributes, useState } from 'react'; +import { StyledInput } from './style'; + +type inputProps = { + value?: string; + placeholder?: string; + disabled?: boolean; + width?: number; + maxLength?: number; + onChange?: (value: string) => void; +}; + +export const Input = (props: inputProps) => { + const { + disabled, + value: valueProp, + placeholder, + maxLength, + width = 260, + onChange, + } = props; + const [value, setValue] = useState(valueProp || ''); + const handleChange: InputHTMLAttributes['onChange'] = e => { + setValue(e.target.value); + onChange && onChange(e.target.value); + }; + return ( + + ); +}; diff --git a/packages/app/src/ui/input/style.ts b/packages/app/src/ui/input/style.ts new file mode 100644 index 0000000000..fd0e4d21f1 --- /dev/null +++ b/packages/app/src/ui/input/style.ts @@ -0,0 +1,30 @@ +import { styled } from '@/styles'; + +export const StyledInput = styled('input')<{ + disabled?: boolean; + value?: string; + width: number; +}>(({ theme, width, disabled }) => { + const fontWeight = 400; + const fontSize = '16px'; + return { + width: `${width}px`, + lineHeight: '22px', + padding: '8px 12px', + fontWeight, + fontSize, + color: disabled ? theme.colors.disableColor : theme.colors.inputColor, + border: `1px solid`, + borderColor: theme.colors.borderColor, // TODO: check out disableColor, + backgroundColor: theme.colors.popoverBackground, + borderRadius: '10px', + '&::placeholder': { + fontWeight, + fontSize, + color: theme.colors.placeHolderColor, + }, + '&:focus': { + borderColor: theme.colors.primaryColor, + }, + }; +}); diff --git a/packages/app/src/utils/__tests__/get-is-mobile.spec.ts b/packages/app/src/utils/__tests__/get-is-mobile.spec.ts new file mode 100644 index 0000000000..bef77b03ba --- /dev/null +++ b/packages/app/src/utils/__tests__/get-is-mobile.spec.ts @@ -0,0 +1,12 @@ +import { describe, test, expect } from '@jest/globals'; +import { isMobile } from '../get-is-mobile'; + +describe('get-is-mobile', () => { + test('get-is-mobile', () => { + expect( + isMobile( + 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1' + ) + ).toBe(true); + }); +}); diff --git a/packages/app/src/utils/get-is-mobile.ts b/packages/app/src/utils/get-is-mobile.ts index 4cf4080490..b3a66796fe 100644 --- a/packages/app/src/utils/get-is-mobile.ts +++ b/packages/app/src/utils/get-is-mobile.ts @@ -1,17 +1,19 @@ // Inspire by https://stackoverflow.com/a/11381730/8415727 -export const getIsMobile = function () { - let check = false; - (function (a) { - if ( - /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test( - a - ) || - /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test( - a.substr(0, 4) - ) +export function isMobile(userAgent: string) { + return !!( + /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test( + userAgent + ) || + /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test( + userAgent.substr(0, 4) ) - check = true; - })(navigator?.userAgent || navigator?.vendor || (window as any)?.opera); - return check; + ); +} + +export const getIsMobile = function () { + return isMobile( + navigator?.userAgent || navigator?.vendor || (window as any)?.opera + ); }; + export default getIsMobile; diff --git a/packages/data-services/package.json b/packages/data-services/package.json new file mode 100644 index 0000000000..6dc645fdd4 --- /dev/null +++ b/packages/data-services/package.json @@ -0,0 +1,30 @@ +{ + "name": "@pathfinder/data-services", + "version": "1.0.0", + "description": "", + "type": "module", + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts", + "exports": { + "./src/*": "./dist/src/*.js", + ".": "./dist/src/index.js" + }, + "scripts": { + "build": "tsc --project ./tsconfig.json" + }, + "keywords": [], + "author": "", + "repository": { + "type": "git", + "url": "git+https://github.com/toeverything/AFFINE.git" + }, + "devDependencies": { + "typescript": "^4.8.4" + }, + "dependencies": { + "axios": "^1.2.0", + "encoding": "^0.1.13", + "firebase": "^9.13.0", + "swr": "^2.0.0" + } +} diff --git a/packages/data-services/src/auth.ts b/packages/data-services/src/auth.ts new file mode 100644 index 0000000000..9896fc7757 --- /dev/null +++ b/packages/data-services/src/auth.ts @@ -0,0 +1,41 @@ +import { initializeApp } from 'firebase/app'; +import { + getAuth, + createUserWithEmailAndPassword, + signInWithEmailAndPassword, + GoogleAuthProvider, + signInWithPopup, +} from 'firebase/auth'; +import type { User } from 'firebase/auth'; + +/** + * firebaseConfig reference: https://firebase.google.com/docs/web/setup#add_firebase_to_your_app + */ +const app = initializeApp({ + apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, + authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, + projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, + storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, + messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, + appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, + measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID, +}); + +export const firebaseAuth = getAuth(app); + +const signUp = (email: string, password: string) => { + return createUserWithEmailAndPassword(firebaseAuth, email, password); +}; + +const signIn = (email: string, password: string) => { + return signInWithEmailAndPassword(firebaseAuth, email, password); +}; + +const googleAuthProvider = new GoogleAuthProvider(); +export const signInWithGoogle = () => { + return signInWithPopup(firebaseAuth, googleAuthProvider); +}; + +export const onAuthStateChanged = (callback: (user: User | null) => void) => { + firebaseAuth.onAuthStateChanged(callback); +}; diff --git a/packages/data-services/src/index.ts b/packages/data-services/src/index.ts new file mode 100644 index 0000000000..a5958a67cc --- /dev/null +++ b/packages/data-services/src/index.ts @@ -0,0 +1,3 @@ +export { signInWithGoogle, onAuthStateChanged } from './auth'; +export * from './request'; +export * from './sdks'; diff --git a/packages/data-services/src/request/ServiceError.ts b/packages/data-services/src/request/ServiceError.ts new file mode 100644 index 0000000000..07ba217007 --- /dev/null +++ b/packages/data-services/src/request/ServiceError.ts @@ -0,0 +1,9 @@ +export class ServiceError extends Error { + public message: string; + public code: string; + constructor(code: string, message: string) { + super(message); + this.message = message; + this.code = code; + } +} diff --git a/packages/data-services/src/request/axios.ts b/packages/data-services/src/request/axios.ts new file mode 100644 index 0000000000..807cee8534 --- /dev/null +++ b/packages/data-services/src/request/axios.ts @@ -0,0 +1,19 @@ +import axios from 'axios'; +import { setAuthorization } from './request'; +import { handleResponseError } from './response'; + +declare module 'axios' { + interface AxiosRequestConfig { + /** + * If true, request will send with Authorization header. + */ + withAuthorization?: boolean; + } +} + +export const request = axios.create({ + withAuthorization: true, +}); + +request.interceptors.request.use(setAuthorization); +request.interceptors.response.use(handleResponseError); diff --git a/packages/data-services/src/request/index.ts b/packages/data-services/src/request/index.ts new file mode 100644 index 0000000000..281037ca4e --- /dev/null +++ b/packages/data-services/src/request/index.ts @@ -0,0 +1,4 @@ +export { request } from './axios'; +export { ServiceError } from './ServiceError'; +export { setToken, authorizationEvent } from './request'; +export type { AccessTokenMessage } from './request'; diff --git a/packages/data-services/src/request/request/authorization/authorization.ts b/packages/data-services/src/request/request/authorization/authorization.ts new file mode 100644 index 0000000000..b581bd5ac8 --- /dev/null +++ b/packages/data-services/src/request/request/authorization/authorization.ts @@ -0,0 +1,99 @@ +import type { AxiosRequestConfig } from 'axios'; +import { login } from '../../../sdks'; +import { AuthorizationEvent } from './events'; +import type { AccessTokenMessage } from './types'; + +const TOKEN_KEY = 'affine_token'; + +export const authorizationEvent = new AuthorizationEvent(); +authorizationEvent.triggerChange( + parseAccessToken(getToken()?.accessToken || '') +); + +interface Token { + accessToken: string; + refreshToken: string; +} + +/** + * set null to clear token + */ +export function setToken(token: Token | null): void { + if (token === null) { + window.localStorage.removeItem(TOKEN_KEY); + authorizationEvent.triggerChange(null); + return; + } + window.localStorage.setItem(TOKEN_KEY, JSON.stringify(token)); + authorizationEvent.triggerChange(parseAccessToken(token.accessToken)); +} + +function getToken(): { accessToken: string; refreshToken: string } | null { + try { + return JSON.parse(window.localStorage.getItem(TOKEN_KEY) || ''); + } catch (error) { + return null; + } +} + +function parseAccessToken(token: string): AccessTokenMessage | null { + try { + const message: AccessTokenMessage = JSON.parse( + window.atob(token.split('.')[1]) + ); + return message; + } catch (error) { + return null; + } +} + +function isAccessTokenExpired(token: string) { + const message = parseAccessToken(token); + if (!message) { + return true; + } + return Date.now() - message.create_at > message.exp; +} + +async function isLoggedIn(): Promise { + const token = getToken(); + if (!token) { + return false; + } + return isAccessTokenExpired(token.accessToken); +} + +let refreshingToken: ReturnType | undefined; + +export async function setAuthorization(config: AxiosRequestConfig) { + if (!config.headers) { + config.headers = {}; + } + + if (config.withAuthorization) { + let token = getToken(); + if (!token) { + throw new Error('No authorization token.'); + } + if (isAccessTokenExpired(token.accessToken)) { + if (!refreshingToken) { + refreshingToken = login({ + type: 'Refresh', + token: token.refreshToken, + }); + } + const newToken = await refreshingToken; + token = { + accessToken: newToken.token, + refreshToken: newToken.refresh, + }; + setToken(token); + refreshingToken = undefined; + } + if (!config.headers) { + config.headers = {}; + } + config.headers['Authorization'] = token.accessToken; + } + return config; +} diff --git a/packages/data-services/src/request/request/authorization/events.ts b/packages/data-services/src/request/request/authorization/events.ts new file mode 100644 index 0000000000..e8d65b8259 --- /dev/null +++ b/packages/data-services/src/request/request/authorization/events.ts @@ -0,0 +1,28 @@ +import type { AccessTokenMessage } from './types'; + +type Callback = (user: AccessTokenMessage | null) => void; + +export class AuthorizationEvent { + private callbacks: Callback[] = []; + private lastState: AccessTokenMessage | null = null; + + /** + * Callback will execute when call this function. + */ + onChange(callback: Callback) { + this.callbacks.push(callback); + callback(this.lastState); + } + + triggerChange(user: AccessTokenMessage | null) { + this.lastState = user; + this.callbacks.forEach(callback => callback(user)); + } + + removeCallback(callback: Callback) { + const index = this.callbacks.indexOf(callback); + if (index > -1) { + this.callbacks.splice(index, 1); + } + } +} diff --git a/packages/data-services/src/request/request/authorization/index.ts b/packages/data-services/src/request/request/authorization/index.ts new file mode 100644 index 0000000000..fbac5e9287 --- /dev/null +++ b/packages/data-services/src/request/request/authorization/index.ts @@ -0,0 +1,2 @@ +export * from './authorization'; +export type { AccessTokenMessage } from './types'; diff --git a/packages/data-services/src/request/request/authorization/types.ts b/packages/data-services/src/request/request/authorization/types.ts new file mode 100644 index 0000000000..a8e70044d5 --- /dev/null +++ b/packages/data-services/src/request/request/authorization/types.ts @@ -0,0 +1,8 @@ +export interface AccessTokenMessage { + create_at: number; + exp: number; + email: string; + id: number; + name: string; + avatar_url: string; +} diff --git a/packages/data-services/src/request/request/index.ts b/packages/data-services/src/request/request/index.ts new file mode 100644 index 0000000000..1607b6b9a0 --- /dev/null +++ b/packages/data-services/src/request/request/index.ts @@ -0,0 +1,6 @@ +export { + setAuthorization, + setToken, + authorizationEvent, +} from './authorization'; +export type { AccessTokenMessage } from './authorization'; diff --git a/packages/data-services/src/request/response/handle-error.ts b/packages/data-services/src/request/response/handle-error.ts new file mode 100644 index 0000000000..5d9bee6a91 --- /dev/null +++ b/packages/data-services/src/request/response/handle-error.ts @@ -0,0 +1,15 @@ +import type { AxiosResponse } from 'axios'; +import { ServiceError } from '../ServiceError'; + +export function handleResponseError(response: AxiosResponse) { + const { data, status } = response; + if (status === 200) { + if (data.error) { + // TODO - common error handling + const error = new ServiceError(data.error.message, data.error.code); + throw error; + } + return response; + } + return response; +} diff --git a/packages/data-services/src/request/response/index.ts b/packages/data-services/src/request/response/index.ts new file mode 100644 index 0000000000..6180a3906c --- /dev/null +++ b/packages/data-services/src/request/response/index.ts @@ -0,0 +1 @@ +export { handleResponseError } from './handle-error'; diff --git a/packages/data-services/src/sdks/account.ts b/packages/data-services/src/sdks/account.ts new file mode 100644 index 0000000000..b7c91d09d2 --- /dev/null +++ b/packages/data-services/src/sdks/account.ts @@ -0,0 +1,90 @@ +import useSWR, { SWRConfiguration } from 'swr'; +import { request, ServiceError } from '../request'; +import type { + RequestAcceptInviting, + RequestInviteCollaborator, + RequestRemoveCollaborator, + ResponseInviteCollaborator, +} from './types'; + +const COLLABORATOR_INVITE_URL = '/api/account/invite'; +const REMOVE_COLLABORATOR_URL = '/api/account/remove_collaborator'; + +async function doInviteCollaborator( + url: string, + req: RequestInviteCollaborator +) { + const { data } = await request.post(url, req); + return data; +} + +export async function inviteCollaborator(req: RequestInviteCollaborator) { + return await doInviteCollaborator(COLLABORATOR_INVITE_URL, req); +} + +async function doRemoveCollaborator( + url: string, + req: RequestRemoveCollaborator +) { + return request.post(url, req); +} + +export async function removeCollaborator(req: RequestRemoveCollaborator) { + return await doRemoveCollaborator(REMOVE_COLLABORATOR_URL, req); +} + +function doAcceptInviting(url: string, req: RequestAcceptInviting) { + return request.post(url, req); +} + +export async function acceptInviting(req: RequestAcceptInviting) { + return await doAcceptInviting(COLLABORATOR_INVITE_URL, req); +} + +export function useInviteCollaborator( + req: RequestInviteCollaborator, + config?: SWRConfiguration +) { + const { data, error } = useSWR( + [COLLABORATOR_INVITE_URL, req], + doInviteCollaborator, + config + ); + return { + data, + isLoading: !error && !data, + isError: error, + }; +} + +export function useRemoveCollaborator( + req: RequestRemoveCollaborator, + config?: SWRConfiguration +) { + const { data, error } = useSWR( + [REMOVE_COLLABORATOR_URL, req], + doRemoveCollaborator, + config + ); + return { + data, + isLoading: !error && !data, + isError: error, + }; +} + +export function useAcceptInviting( + req: RequestAcceptInviting, + config?: SWRConfiguration +) { + const { data, error } = useSWR( + [COLLABORATOR_INVITE_URL, req], + doAcceptInviting, + config + ); + return { + data, + isLoading: !error && !data, + isError: error, + }; +} diff --git a/packages/data-services/src/sdks/index.ts b/packages/data-services/src/sdks/index.ts new file mode 100644 index 0000000000..b55b3d62ac --- /dev/null +++ b/packages/data-services/src/sdks/index.ts @@ -0,0 +1,4 @@ +export * from './workspace'; +export * from './workspace.hook'; +export * from './user'; +export * from './user.hook'; diff --git a/packages/data-services/src/sdks/types/account.ts b/packages/data-services/src/sdks/types/account.ts new file mode 100644 index 0000000000..8f1fb5f6a8 --- /dev/null +++ b/packages/data-services/src/sdks/types/account.ts @@ -0,0 +1,33 @@ +enum WorkspacePermission { + read = 'read', + write = 'write', +} + +export type RequestInviteCollaborator = { + email: string; + workspace_id: string; +}; + +export type ResponseInviteCollaborator = { + inviting_code: string; +}; + +export type RequestRemoveCollaborator = { + user_id: string; + workspace_id: string; +}; + +export type ResponseRemoveCollaborator = { + workspace_id: string; +}; + +export type RequestAcceptInviting = { + inviting_code: string; +}; + +export type ResponseAcceptInviting = { + workspace_id: string; + name: string; + avatar_url: string; + permissions: WorkspacePermission; +}; diff --git a/packages/data-services/src/sdks/types/common.ts b/packages/data-services/src/sdks/types/common.ts new file mode 100644 index 0000000000..348bd13c91 --- /dev/null +++ b/packages/data-services/src/sdks/types/common.ts @@ -0,0 +1,2 @@ +export type CommonError = { error: { code: string; message: string } }; +export type MayError = Partial; diff --git a/packages/data-services/src/sdks/types/index.ts b/packages/data-services/src/sdks/types/index.ts new file mode 100644 index 0000000000..25b1f4eba7 --- /dev/null +++ b/packages/data-services/src/sdks/types/index.ts @@ -0,0 +1,3 @@ +export * from './common'; +export * from './workspace'; +export * from './account'; diff --git a/packages/data-services/src/sdks/types/workspace.ts b/packages/data-services/src/sdks/types/workspace.ts new file mode 100644 index 0000000000..0a6f25ae99 --- /dev/null +++ b/packages/data-services/src/sdks/types/workspace.ts @@ -0,0 +1,32 @@ +enum WorkspaceType { + 'personal' = 'personal', + 'team' = 'team', +} + +export type Workspace = { + id: string; + name: string; + workspace_type: WorkspaceType; + avatar_url?: string; + public: boolean; +}; + +export type ResponseGetWorkspaces = { + create: Array; + read: Array; + write: Array; +}; + +export type RequestCreateWorkspace = { + name: string; + avatar_url?: string; + workspace_type: WorkspaceType; +}; + +export type RequestUpdateWorkspace = { + workspace_type?: WorkspaceType; + avatar_url?: string; + public?: boolean; +}; + +export type ResponseCreateWorkspace = any; diff --git a/packages/data-services/src/sdks/user.hook.ts b/packages/data-services/src/sdks/user.hook.ts new file mode 100644 index 0000000000..e6997c4765 --- /dev/null +++ b/packages/data-services/src/sdks/user.hook.ts @@ -0,0 +1,45 @@ +import useSWR from 'swr'; +import type { SWRConfiguration } from 'swr'; +import { login, getUserByEmail } from './user'; +import type { + LoginParams, + LoginResponse, + GetUserByEmailParams, + User, +} from './user'; + +export const LOGIN_SWR_KEY = 'user.token'; +export function useLogin(params: LoginParams, config?: SWRConfiguration) { + const { data, error, isValidating, isLoading, mutate } = + useSWR( + [LOGIN_SWR_KEY, params], + ([_, params]) => login(params), + config + ); + + return { + loading: isLoading, + data, + error, + mutate, + }; +} + +export const GET_USER_BY_EMAIL_SWR_TOKEN = 'user.getUserByEmail'; +export function useGetUserByEmail( + params: GetUserByEmailParams, + config?: SWRConfiguration +) { + const { data, error, isLoading, mutate } = useSWR( + [GET_USER_BY_EMAIL_SWR_TOKEN, params], + ([_, params]) => getUserByEmail(params), + config + ); + + return { + loading: isLoading, + data, + error, + mutate, + }; +} diff --git a/packages/data-services/src/sdks/user.ts b/packages/data-services/src/sdks/user.ts new file mode 100644 index 0000000000..d91babb5b3 --- /dev/null +++ b/packages/data-services/src/sdks/user.ts @@ -0,0 +1,60 @@ +import { request } from '../request'; + +export interface ExchangeToken { + type: 'Google'; + /** + * Token from firebase. + */ + token: string; +} + +export interface RefreshToken { + type: 'Refresh'; + token: string; +} + +export type LoginParams = ExchangeToken | RefreshToken; + +export interface LoginResponse { + /** + * JWT, expires in a very short time + */ + token: string; + /** + * Refresh token + */ + refresh: string; +} + +export async function login(params: LoginParams): Promise { + const data = await request({ + url: '/api/user/token', + method: 'POST', + data: params, + withAuthorization: false, + }); + return data.data; +} + +export interface GetUserByEmailParams { + email: string; +} + +export interface User { + id: number; + name: string; + email: string; + avatar_url: string; + create_at: string; +} + +export async function getUserByEmail( + params: GetUserByEmailParams +): Promise { + const data = await request({ + url: '/api/user', + method: 'GET', + params, + }); + return data.data; +} diff --git a/packages/data-services/src/sdks/workspace.bak.ts b/packages/data-services/src/sdks/workspace.bak.ts new file mode 100644 index 0000000000..adbd3c9d77 --- /dev/null +++ b/packages/data-services/src/sdks/workspace.bak.ts @@ -0,0 +1,106 @@ +import useSWR, { SWRConfiguration } from 'swr'; +import type { + MayError, + RequestCreateWorkspace, + RequestUpdateWorkspace, + ResponseCreateWorkspace, + ResponseGetWorkspaces, +} from './types'; +import { request, ServiceError } from '../request'; + +const WORKSPACE_URL = '/api/workspace'; + +async function doGetWorkSpaces(url: string) { + const { data } = await request.get(url); + return data; +} + +export async function getWorkSpaces() { + return await doGetWorkSpaces(WORKSPACE_URL); +} + +async function doCreateWorkspace(url: string, req: RequestCreateWorkspace) { + const { data } = await request.put(url, req); + return data; +} + +export async function createWorkspace(req: RequestCreateWorkspace) { + doCreateWorkspace(WORKSPACE_URL, req); +} + +async function doUpdateWorkspace(url: string, req: RequestUpdateWorkspace) { + const { data } = await request.post(url, req); + return data; +} + +export function updateWorkspace(id: string, req: RequestUpdateWorkspace) { + return doUpdateWorkspace(`${WORKSPACE_URL}${id}`, req); +} + +async function doDeleteWorkspace(url: string) { + const { data } = await request.delete(url); + return data; +} + +export function deleteWorkspace(id: string) { + return doDeleteWorkspace(`${WORKSPACE_URL}${id}`); +} + +export function useGetWorkspaces(config?: SWRConfiguration) { + const { data, error } = useSWR( + WORKSPACE_URL, + doGetWorkSpaces, + config + ); + return { + data, + isLoading: !data, + isError: data && !error, + }; +} + +export function useCreateWorkspace( + req: RequestCreateWorkspace, + config?: SWRConfiguration +) { + const { data, error } = useSWR( + [WORKSPACE_URL, req], + doCreateWorkspace, + config + ); + return { + data, + isLoading: !error && !data, + isError: error, + }; +} + +export function useUpdateWorkspace( + id: string, + req: RequestCreateWorkspace, + config?: SWRConfiguration +) { + const { data, error } = useSWR( + [`${WORKSPACE_URL}${id}`, req], + doUpdateWorkspace, + config + ); + return { + data, + isLoading: !error && !data, + isError: error, + }; +} + +export function useDeleteWorkspace(id: string, config?: SWRConfiguration) { + const { data, error } = useSWR( + `${WORKSPACE_URL}${id}`, + doDeleteWorkspace, + config + ); + return { + data, + isLoading: !error && !data, + isError: error, + }; +} diff --git a/packages/data-services/src/sdks/workspace.hook.ts b/packages/data-services/src/sdks/workspace.hook.ts new file mode 100644 index 0000000000..91fa3b9f3e --- /dev/null +++ b/packages/data-services/src/sdks/workspace.hook.ts @@ -0,0 +1,72 @@ +import useSWR from 'swr'; +import type { SWRConfiguration } from 'swr'; +import { + getWorkspaceDetail, + updateWorkspace, + deleteWorkspace, + inviteMember, + Workspace, +} from './workspace'; +import { + GetWorkspaceDetailParams, + WorkspaceDetail, + UpdateWorkspaceParams, + DeleteWorkspaceParams, + InviteMemberParams, + getWorkspaces, +} from './workspace'; + +export const GET_WORKSPACE_DETAIL_SWR_TOKEN = 'workspace.getWorkspaceDetail'; +export function useGetWorkspaceDetail( + params: GetWorkspaceDetailParams, + config?: SWRConfiguration +) { + const { data, error, isLoading, mutate } = useSWR( + [GET_WORKSPACE_DETAIL_SWR_TOKEN, params], + ([_, params]) => getWorkspaceDetail(params), + config + ); + + return { + data, + error, + loading: isLoading, + mutate, + }; +} + +export const GET_WORKSPACES_SWR_TOKEN = 'workspace.getWorkspaces'; +export function useGetWorkspaces(config?: SWRConfiguration) { + const { data, error, isLoading } = useSWR( + [GET_WORKSPACES_SWR_TOKEN], + () => getWorkspaces(), + config + ); + + return { + data, + error, + loading: isLoading, + }; +} + +export const UPDATE_WORKSPACE_SWR_TOKEN = 'workspace.updateWorkspace'; +/** + * I don't think a hook needed for update workspace. + * If you figure out the scene, please implement this function. + */ +export function useUpdateWorkspace() {} + +export const DELETE_WORKSPACE_SWR_TOKEN = 'workspace.deleteWorkspace'; +/** + * I don't think a hook needed for delete workspace. + * If you figure out the scene, please implement this function. + */ +export function useDeleteWorkspace() {} + +export const INVITE_MEMBER_SWR_TOKEN = 'workspace.inviteMember'; +/** + * I don't think a hook needed for invite member. + * If you figure out the scene, please implement this function. + */ +export function useInviteMember() {} diff --git a/packages/data-services/src/sdks/workspace.ts b/packages/data-services/src/sdks/workspace.ts new file mode 100644 index 0000000000..23796dea9a --- /dev/null +++ b/packages/data-services/src/sdks/workspace.ts @@ -0,0 +1,186 @@ +import { request } from '../request'; +import { User } from './user'; + +export interface GetWorkspaceDetailParams { + id: string; +} + +export enum WorkspaceType { + Private = 0, + Normal = 1, +} + +export enum PermissionType { + Read = 0, + Write = 1, + Admin = 2, + Owner = 3, +} + +export interface Workspace { + id: string; + type: WorkspaceType; + public: boolean; + permission_type: PermissionType; + create_at: number; +} + +export async function getWorkspaces(): Promise { + const data = await request({ + url: '/api/workspace', + method: 'GET', + }); + + return data.data; +} + +export interface WorkspaceDetail extends Workspace { + owner: User; + member_count: number; +} + +export async function getWorkspaceDetail( + params: GetWorkspaceDetailParams +): Promise { + const data = await request({ + url: `/api/workspace/${params.id}`, + method: 'PUT', + }); + + return data.data; +} + +export interface Permission { + id: number; + type: PermissionType; + workspace_id: string; + accepted: boolean; + create_at: number; +} + +export interface RegisteredUser extends User { + type: 'Registered'; +} + +export interface UnregisteredUser { + type: 'Unregistered'; + email: string; +} + +export interface Member extends Permission { + user: RegisteredUser | UnregisteredUser; +} + +export interface GetWorkspaceMembersParams { + id: string; +} + +export async function getWorkspaceMembers( + params: GetWorkspaceDetailParams +): Promise { + const data = await request({ + url: `/api/workspace/${params.id}/permission`, + method: 'GET', + }); + + return data.data; +} + +export interface CreateWorkspaceParams { + name: string; + avatar: string; +} + +export async function createWorkspace( + params: CreateWorkspaceParams +): Promise { + const data = await request({ + url: '/api/workspace', + method: 'POST', + data: params, + }); + + return data.data; +} + +export interface UpdateWorkspaceParams { + id: string; + public: boolean; +} + +export async function updateWorkspace( + params: UpdateWorkspaceParams +): Promise { + const data = await request({ + url: `/api/workspace/${params.id}`, + method: 'POST', + data: { + public: params.public, + }, + }); + + return data.data; +} + +export interface DeleteWorkspaceParams { + id: string; +} + +export async function deleteWorkspace( + params: DeleteWorkspaceParams +): Promise { + const data = await request({ + url: `/api/workspace/${params.id}`, + method: 'DELETE', + }); + + return data.data; +} + +export interface InviteMemberParams { + id: string; + email: string; +} + +/** + * Notice: Only support normal(contrast to private) workspace. + */ +export async function inviteMember(params: InviteMemberParams): Promise { + const data = await request({ + url: `/api/workspace/${params.id}/permission`, + method: 'POST', + data: { + email: params.email, + }, + }); + + return data.data; +} + +export interface RemoveMemberParams { + permissionId: number; +} + +export async function removeMember(params: RemoveMemberParams): Promise { + const data = await request({ + url: `/api/permission/${params.permissionId}`, + method: 'DELETE', + }); + + return data.data; +} + +export interface AcceptInvitingParams { + invitingCode: string; +} + +export async function acceptInviting( + params: AcceptInvitingParams +): Promise { + const data = await request({ + url: `/api/invite/${params.invitingCode}`, + method: 'POST', + }); + + return data.data; +} diff --git a/packages/data-services/tsconfig.json b/packages/data-services/tsconfig.json new file mode 100644 index 0000000000..063354ba92 --- /dev/null +++ b/packages/data-services/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": false, + "esModuleInterop": true, + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "experimentalDecorators": true, + "declaration": true, + "baseUrl": ".", + "rootDir": ".", + "outDir": "./dist" + }, + "include": ["next-env.d.ts", "src/**/*.ts", "pages/**/*.tsx"], + "exclude": ["node_modules", "dist"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a19ed8534..76e94ee371 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,21 +4,29 @@ importers: .: specifiers: + '@jest/globals': ^29.3.1 '@playwright/test': ^1.28.1 '@types/node': 18.7.18 eslint: 8.22.0 eslint-config-next: 12.3.1 eslint-config-prettier: ^8.5.0 eslint-plugin-prettier: ^4.2.1 + jest: ^29.3.1 prettier: ^2.7.1 + ts-jest: ^29.0.3 + typescript: ^4.9.3 devDependencies: + '@jest/globals': 29.3.1 '@playwright/test': 1.28.1 '@types/node': 18.7.18 eslint: 8.22.0 - eslint-config-next: 12.3.1_eslint@8.22.0 + eslint-config-next: 12.3.1_tg6quxtr5dyl3tikvj7rwonxxi eslint-config-prettier: 8.5.0_eslint@8.22.0 eslint-plugin-prettier: 4.2.1_i2cojdczqdiurzgttlwdgf764e + jest: 29.3.1_@types+node@18.7.18 prettier: 2.7.1 + ts-jest: 29.0.3_4f6uxrzmuwipl5rr3bcogf6k74 + typescript: 4.9.3 packages/app: specifiers: @@ -35,6 +43,7 @@ importers: '@mui/base': ^5.0.0-alpha.87 '@mui/icons-material': ^5.10.9 '@mui/material': ^5.8.6 + '@pathfinder/data-services': workspace:@pathfinder/data-services@* '@toeverything/pathfinder-logger': workspace:@pathfinder/logger@* '@types/node': 18.7.18 '@types/react': 18.0.20 @@ -70,6 +79,7 @@ importers: '@mui/base': 5.0.0-alpha.101_7ey2zzynotv32rpkwno45fsx4e '@mui/icons-material': 5.10.9_5fncb4nagb4cvvcnwamw2rozfa '@mui/material': 5.10.9_af5ln35zuaotaffazii6n6bke4 + '@pathfinder/data-services': link:../data-services '@toeverything/pathfinder-logger': link:../logger cmdk: 0.1.20_7ey2zzynotv32rpkwno45fsx4e css-spring: 4.1.0 @@ -93,6 +103,21 @@ importers: eslint-plugin-prettier: 4.2.1_i2cojdczqdiurzgttlwdgf764e typescript: 4.8.3 + packages/data-services: + specifiers: + axios: ^1.2.0 + encoding: ^0.1.13 + firebase: ^9.13.0 + swr: ^2.0.0 + typescript: ^4.8.4 + dependencies: + axios: 1.2.0 + encoding: 0.1.13 + firebase: 9.13.0_encoding@0.1.13 + swr: 2.0.0 + devDependencies: + typescript: 4.9.3 + packages/logger: specifiers: '@types/react': ^18.0.21 @@ -110,34 +135,153 @@ importers: packages: + /@ampproject/remapping/2.2.0: + resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.1.1 + '@jridgewell/trace-mapping': 0.3.17 + dev: true + /@babel/code-frame/7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.18.6 - dev: false + + /@babel/compat-data/7.20.5: + resolution: {integrity: sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core/7.20.5: + resolution: {integrity: sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helpers': 7.20.6 + '@babel/parser': 7.20.5 + '@babel/template': 7.18.10 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator/7.20.5: + resolution: {integrity: sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + '@jridgewell/gen-mapping': 0.3.2 + jsesc: 2.5.2 + dev: true + + /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.5: + resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-validator-option': 7.18.6 + browserslist: 4.21.4 + semver: 6.3.0 + dev: true + + /@babel/helper-environment-visitor/7.18.9: + resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-function-name/7.19.0: + resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.10 + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-hoist-variables/7.18.6: + resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.19.4 - dev: false + '@babel/types': 7.20.5 + + /@babel/helper-module-transforms/7.20.2: + resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-simple-access': 7.20.2 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 + '@babel/template': 7.18.10 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 + transitivePeerDependencies: + - supports-color + dev: true /@babel/helper-plugin-utils/7.19.0: resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} engines: {node: '>=6.9.0'} - dev: false + + /@babel/helper-simple-access/7.20.2: + resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-split-export-declaration/7.18.6: + resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true /@babel/helper-string-parser/7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} engines: {node: '>=6.9.0'} - dev: false /@babel/helper-validator-identifier/7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} - dev: false + + /@babel/helper-validator-option/7.18.6: + resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers/7.20.6: + resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.10 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 + transitivePeerDependencies: + - supports-color + dev: true /@babel/highlight/7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} @@ -146,7 +290,59 @@ packages: '@babel/helper-validator-identifier': 7.19.1 chalk: 2.4.2 js-tokens: 4.0.0 - dev: false + + /@babel/parser/7.20.5: + resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.20.5: + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.20.5: + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.20.5: + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true /@babel/plugin-syntax-jsx/7.18.6: resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} @@ -157,6 +353,90 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: false + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.20.5: + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.20.5: + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.20.5: + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-typescript/7.20.0_@babel+core@7.20.5: + resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + /@babel/runtime-corejs3/7.19.1: resolution: {integrity: sha512-j2vJGnkopRzH+ykJ8h68wrHnEUmtK//E723jjixiAl/PPf6FhqY/vYRcMVlNydRKQjQsTsYEjpx+DZMIvnGk/g==} engines: {node: '>=6.9.0'} @@ -171,6 +451,33 @@ packages: dependencies: regenerator-runtime: 0.13.9 + /@babel/template/7.18.10: + resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 + dev: true + + /@babel/traverse/7.20.5: + resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.20.5 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/types/7.19.4: resolution: {integrity: sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==} engines: {node: '>=6.9.0'} @@ -178,7 +485,19 @@ packages: '@babel/helper-string-parser': 7.19.4 '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 - dev: false + dev: true + + /@babel/types/7.20.5: + resolution: {integrity: sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + + /@bcoe/v8-coverage/0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true /@blocksuite/blocks/0.3.0-alpha.11: resolution: {integrity: sha512-SwOTu9Ph5zsxczzPL0RoSfQKZLrrgEPhXiZycbv+tvsaXSwHq27JALJFh+G+HHP0uJvt/vSYfXzHck+3J1m+4Q==} @@ -414,6 +733,473 @@ packages: - supports-color dev: true + /@firebase/analytics-compat/0.1.17_uhwflrzfcfz2g667jhvqg7sd7i: + resolution: {integrity: sha512-36ByEDsH6/3YNuD6yig30s2A/+E1pt333r8SJirUE8+aHYl/DGX0PXplKvJWDGamYYjMwet3Kt4XRrB1NY8mLg==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/analytics': 0.8.4_@firebase+app@0.8.3 + '@firebase/analytics-types': 0.7.1 + '@firebase/app-compat': 0.1.38 + '@firebase/component': 0.5.21 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app' + dev: false + + /@firebase/analytics-types/0.7.1: + resolution: {integrity: sha512-a1INLjelc1Mqrt2CbGmGdlNBj0zsvwBv0K5q5C6Fje8GSXBMc3+iQQQjzYe/4KkK6nL54UP7ZMeI/Q3VEW72FA==} + dev: false + + /@firebase/analytics/0.8.4_@firebase+app@0.8.3: + resolution: {integrity: sha512-Bgr2tMexv0YrL6kjrOF1xVRts8PM6WWmROpfRQjh0xFU4QSoofBJhkVn2NXDXkHWrr5slFfqB5yOnmgAIsHiMw==} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.8.3 + '@firebase/component': 0.5.21 + '@firebase/installations': 0.5.16_@firebase+app@0.8.3 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + dev: false + + /@firebase/app-check-compat/0.2.16_uhwflrzfcfz2g667jhvqg7sd7i: + resolution: {integrity: sha512-XxG0gag6In1JPFdANdzhD3neYrXoNTmvSE1+c8PWjnwqBfaNooP6mrwrzIyNTRHderWCnjRlUWvaAKnsprC2Jg==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/app-check': 0.5.16_@firebase+app@0.8.3 + '@firebase/app-check-types': 0.4.1 + '@firebase/app-compat': 0.1.38 + '@firebase/component': 0.5.21 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app' + dev: false + + /@firebase/app-check-interop-types/0.1.1: + resolution: {integrity: sha512-QpYh5GmiLA9ob8NWAZpHbNNl9TzxxZI4NLevT6MYPRDXKG9BSmBI7FATRfm5uv2QQUVSQrESKog5CCmU16v+7Q==} + dev: false + + /@firebase/app-check-types/0.4.1: + resolution: {integrity: sha512-4X79w2X0H5i5qvaho3qkjZg5qdERnKR4gCfy/fxDmdMMP4QgNJHJ9IBk1E+c4cm5HlaZVcLq9K6z8xaRqjZhyw==} + dev: false + + /@firebase/app-check/0.5.16_@firebase+app@0.8.3: + resolution: {integrity: sha512-dW5b/wlrqDKrdRcIQwnWNzrEK2kH1k+wwy21qOnGnHstrKPfxjgz+HAgTptQLJq1yLjoorksNOq8uie0EsWDrQ==} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.8.3 + '@firebase/component': 0.5.21 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + dev: false + + /@firebase/app-compat/0.1.38: + resolution: {integrity: sha512-vw+Hu69cNSOgcATV7MH5tBkCxDzjD/M9CROW5n5F58c3K2Lhnhil0T7IbfFhr475kONeD5NKkdRGUqan86pSTg==} + dependencies: + '@firebase/app': 0.8.3 + '@firebase/component': 0.5.21 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + dev: false + + /@firebase/app-types/0.8.1: + resolution: {integrity: sha512-p75Ow3QhB82kpMzmOntv866wH9eZ3b4+QbUY+8/DA5Zzdf1c8Nsk8B7kbFpzJt4wwHMdy5LTF5YUnoTc1JiWkw==} + dev: false + + /@firebase/app/0.8.3: + resolution: {integrity: sha512-+YT+DX4m1VAZY6JE5gMt+Xz7O34Y01pqUqoaVO6nbzuohgdcQ57YBL3T26tYqg5JapuwU7CNkFTZOvRc3pYi6g==} + dependencies: + '@firebase/component': 0.5.21 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + idb: 7.0.1 + tslib: 2.4.0 + dev: false + + /@firebase/auth-compat/0.2.24_6e25ipnw6ok3e747dgryxrjf7m: + resolution: {integrity: sha512-IuZQScjtoOLkUHtmIUJ2F3E2OpDOyap6L/9HL/DX3nzEA1LrX7wlpeU6OF2jS9E0KLueWKIrSkIQOOsKoQj/sA==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/app-compat': 0.1.38 + '@firebase/auth': 0.20.11_fg26na3iiuycy3cwzcyxqwfb2e + '@firebase/auth-types': 0.11.1_ng4u4jtoxpyfdkxsmbmyeoj754 + '@firebase/component': 0.5.21 + '@firebase/util': 1.7.3 + node-fetch: 2.6.7_encoding@0.1.13 + selenium-webdriver: 4.5.0 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app' + - '@firebase/app-types' + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@firebase/auth-interop-types/0.1.7_ng4u4jtoxpyfdkxsmbmyeoj754: + resolution: {integrity: sha512-yA/dTveGGPcc85JP8ZE/KZqfGQyQTBCV10THdI8HTlP1GDvNrhr//J5jAt58MlsCOaO3XmC4DqScPBbtIsR/EA==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 1.x + dependencies: + '@firebase/app-types': 0.8.1 + '@firebase/util': 1.7.3 + dev: false + + /@firebase/auth-types/0.11.1_ng4u4jtoxpyfdkxsmbmyeoj754: + resolution: {integrity: sha512-ud7T39VG9ptTrC2fOy/XlU+ubC+BVuBJPteuzsPZSa9l7gkntvWgVb3Z/3FxqqRPlkVUYiyvmsbRN3DE1He2ow==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 1.x + dependencies: + '@firebase/app-types': 0.8.1 + '@firebase/util': 1.7.3 + dev: false + + /@firebase/auth/0.20.11_fg26na3iiuycy3cwzcyxqwfb2e: + resolution: {integrity: sha512-cKy91l4URDG3yWfPK7tjUySh2wCLxtTilsR59jiqQJLReBrQsKP79eFDJ6jqWwbEh3+f1lmoH1nKswwbo9XdmA==} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.8.3 + '@firebase/component': 0.5.21 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + node-fetch: 2.6.7_encoding@0.1.13 + selenium-webdriver: 4.5.0 + tslib: 2.4.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@firebase/component/0.5.21: + resolution: {integrity: sha512-12MMQ/ulfygKpEJpseYMR0HunJdlsLrwx2XcEs40M18jocy2+spyzHHEwegN3x/2/BLFBjR5247Etmz0G97Qpg==} + dependencies: + '@firebase/util': 1.7.3 + tslib: 2.4.0 + dev: false + + /@firebase/database-compat/0.2.10_@firebase+app-types@0.8.1: + resolution: {integrity: sha512-fK+IgUUqVKcWK/gltzDU+B1xauCOfY6vulO8lxoNTkcCGlSxuTtwsdqjGkFmgFRMYjXFWWJ6iFcJ/vXahzwCtA==} + dependencies: + '@firebase/component': 0.5.21 + '@firebase/database': 0.13.10_@firebase+app-types@0.8.1 + '@firebase/database-types': 0.9.17 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app-types' + dev: false + + /@firebase/database-types/0.9.17: + resolution: {integrity: sha512-YQm2tCZyxNtEnlS5qo5gd2PAYgKCy69tUKwioGhApCFThW+mIgZs7IeYeJo2M51i4LCixYUl+CvnOyAnb/c3XA==} + dependencies: + '@firebase/app-types': 0.8.1 + '@firebase/util': 1.7.3 + dev: false + + /@firebase/database/0.13.10_@firebase+app-types@0.8.1: + resolution: {integrity: sha512-KRucuzZ7ZHQsRdGEmhxId5jyM2yKsjsQWF9yv0dIhlxYg0D8rCVDZc/waoPKA5oV3/SEIoptF8F7R1Vfe7BCQA==} + dependencies: + '@firebase/auth-interop-types': 0.1.7_ng4u4jtoxpyfdkxsmbmyeoj754 + '@firebase/component': 0.5.21 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + faye-websocket: 0.11.4 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app-types' + dev: false + + /@firebase/firestore-compat/0.2.2_6e25ipnw6ok3e747dgryxrjf7m: + resolution: {integrity: sha512-QKgQjyKxx9PxbUebDlKsUinA4Yyvs3m+dH8fJFW1RnQ0SbufCE0vmoJQs+TSZ53Nw8NH2NyVGmXt2aZXiBpnQQ==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/app-compat': 0.1.38 + '@firebase/component': 0.5.21 + '@firebase/firestore': 3.7.2_fg26na3iiuycy3cwzcyxqwfb2e + '@firebase/firestore-types': 2.5.1_ng4u4jtoxpyfdkxsmbmyeoj754 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app' + - '@firebase/app-types' + - encoding + dev: false + + /@firebase/firestore-types/2.5.1_ng4u4jtoxpyfdkxsmbmyeoj754: + resolution: {integrity: sha512-xG0CA6EMfYo8YeUxC8FeDzf6W3FX1cLlcAGBYV6Cku12sZRI81oWcu61RSKM66K6kUENP+78Qm8mvroBcm1whw==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 1.x + dependencies: + '@firebase/app-types': 0.8.1 + '@firebase/util': 1.7.3 + dev: false + + /@firebase/firestore/3.7.2_fg26na3iiuycy3cwzcyxqwfb2e: + resolution: {integrity: sha512-PFTwzgRxCmUKb0jDx5zEAXpl/8dv8+Y0GBMghL9D7kt2ZeIA05yzo05yOKL/d5lShOPJ76/5dkOJty8zg1IBtw==} + engines: {node: '>=10.10.0'} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.8.3 + '@firebase/component': 0.5.21 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + '@firebase/webchannel-wrapper': 0.8.1 + '@grpc/grpc-js': 1.7.3 + '@grpc/proto-loader': 0.6.13 + node-fetch: 2.6.7_encoding@0.1.13 + tslib: 2.4.0 + transitivePeerDependencies: + - encoding + dev: false + + /@firebase/functions-compat/0.2.8_6e25ipnw6ok3e747dgryxrjf7m: + resolution: {integrity: sha512-5w668whT+bm6oVcFqIxfFbn9N77WycpNCfZNg1l0iC+5RLSt53RTVu43pqi43vh23Vp4ad+SRBgZiQGAMen5wA==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/app-compat': 0.1.38 + '@firebase/component': 0.5.21 + '@firebase/functions': 0.8.8_qxaep7pmgqjgshotoaytuprcse + '@firebase/functions-types': 0.5.1 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app' + - '@firebase/app-types' + - encoding + dev: false + + /@firebase/functions-types/0.5.1: + resolution: {integrity: sha512-olEJnTuULM/ws0pwhHA0Ze5oIdpFbZsdBGCaBhyL4pm1NUR4Moh0cyAsqr+VtqHCNMGquHU1GJ77qITkoonp0w==} + dev: false + + /@firebase/functions/0.8.8_qxaep7pmgqjgshotoaytuprcse: + resolution: {integrity: sha512-weNcDQJcH3/2YFaXd5dF5pUk3IQdZY60QNuWpq7yS+uaPlCRHjT0K989Q3ZcmYwXz7mHTfhlQamXdA4Yobgt+Q==} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.8.3 + '@firebase/app-check-interop-types': 0.1.1 + '@firebase/auth-interop-types': 0.1.7_ng4u4jtoxpyfdkxsmbmyeoj754 + '@firebase/component': 0.5.21 + '@firebase/messaging-interop-types': 0.1.1 + '@firebase/util': 1.7.3 + node-fetch: 2.6.7_encoding@0.1.13 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app-types' + - encoding + dev: false + + /@firebase/installations-compat/0.1.16_h7lquf2icoxthdkgvez4xhlpaa: + resolution: {integrity: sha512-Xp7s3iUMZ6/TN0a+g1kpHNEn7h59kSxi44/2I7bd3X6xwHnxMu0TqYB7U9WfqEhqiI9iKulL3g06wIZqaklElw==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/app-compat': 0.1.38 + '@firebase/component': 0.5.21 + '@firebase/installations': 0.5.16_@firebase+app@0.8.3 + '@firebase/installations-types': 0.4.1_@firebase+app-types@0.8.1 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app' + - '@firebase/app-types' + dev: false + + /@firebase/installations-types/0.4.1_@firebase+app-types@0.8.1: + resolution: {integrity: sha512-ac906QcmipomZjSasGDYNS1LDy4JNGzQ4VXHpFtoOrI6U2QGFkRezZpI+5bzfU062JOD+doO6irYC6Uwnv/GnA==} + peerDependencies: + '@firebase/app-types': 0.x + dependencies: + '@firebase/app-types': 0.8.1 + dev: false + + /@firebase/installations/0.5.16_@firebase+app@0.8.3: + resolution: {integrity: sha512-k3iyjr+yZnDOcJbP+CCZW3/zQJf9gYL2CNBJs9QbmFJoLz7cgIcnAT/XNDMudxcggF1goLfq4+MygpzHD0NzLA==} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.8.3 + '@firebase/component': 0.5.21 + '@firebase/util': 1.7.3 + idb: 7.0.1 + tslib: 2.4.0 + dev: false + + /@firebase/logger/0.3.4: + resolution: {integrity: sha512-hlFglGRgZEwoyClZcGLx/Wd+zoLfGmbDkFx56mQt/jJ0XMbfPqwId1kiPl0zgdWZX+D8iH+gT6GuLPFsJWgiGw==} + dependencies: + tslib: 2.4.0 + dev: false + + /@firebase/messaging-compat/0.1.20_uhwflrzfcfz2g667jhvqg7sd7i: + resolution: {integrity: sha512-eRKqWetb6VgseMMVJGYqsvl+GMmtSaoVMXOdw3ZqEqeh8rsEaMRyQXpfn5wj+gzTn6JhW2UHdsRUc++qYZcsnw==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/app-compat': 0.1.38 + '@firebase/component': 0.5.21 + '@firebase/messaging': 0.10.0_@firebase+app@0.8.3 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app' + dev: false + + /@firebase/messaging-interop-types/0.1.1: + resolution: {integrity: sha512-7XuY87zPh01EBaeS3s6co31Il5oGbPl5MxAg6Uj3fPv7PqJQlbwQ+B5k7CKSF/Y26tRxp+u+usxIvIWCSEA8CQ==} + dev: false + + /@firebase/messaging/0.10.0_@firebase+app@0.8.3: + resolution: {integrity: sha512-1LREZ2IX6kzrne/mAhbUEFRFzTZkhyh6bYjAdUnaYrvHNwm0Y2x88WIJVJmGC7rroxJxbeGZMQ+cL/r9rBAwPA==} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.8.3 + '@firebase/component': 0.5.21 + '@firebase/installations': 0.5.16_@firebase+app@0.8.3 + '@firebase/messaging-interop-types': 0.1.1 + '@firebase/util': 1.7.3 + idb: 7.0.1 + tslib: 2.4.0 + dev: false + + /@firebase/performance-compat/0.1.16_uhwflrzfcfz2g667jhvqg7sd7i: + resolution: {integrity: sha512-ViGASnBVZrhoDC879fzdsvmPEFRMBgJ/Y4MuBkkg7Y4/Sd3SAB2IOhVn92oyPdYr8FeIoH7irN66zNnljKsXEg==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/app-compat': 0.1.38 + '@firebase/component': 0.5.21 + '@firebase/logger': 0.3.4 + '@firebase/performance': 0.5.16_@firebase+app@0.8.3 + '@firebase/performance-types': 0.1.1 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app' + dev: false + + /@firebase/performance-types/0.1.1: + resolution: {integrity: sha512-wiJRLBg8EPaYSGJqx7aqkZ3L5fULfZa9zOTs4C06K020g0zzJh9kUUO/0U3wvHz7zRQjJxTO8Jw4SDjxs3EZrA==} + dev: false + + /@firebase/performance/0.5.16_@firebase+app@0.8.3: + resolution: {integrity: sha512-6099wYEh5Fmm9ZHRcl8uUPsWkzbYkpLSZyMfyJKHTseQeOLE5OYPzKgia8fYAHlP2dID3cylyXfZTJo/Eak8wQ==} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.8.3 + '@firebase/component': 0.5.21 + '@firebase/installations': 0.5.16_@firebase+app@0.8.3 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + dev: false + + /@firebase/remote-config-compat/0.1.16_uhwflrzfcfz2g667jhvqg7sd7i: + resolution: {integrity: sha512-BWonzeqODnGki/fZ17zOnjJFR5CWbIOU0PmYGjWBnbkWxpFDdE3zNsz8JTVd/Mkt7y2PHFMYpLsyZ473E/62FQ==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/app-compat': 0.1.38 + '@firebase/component': 0.5.21 + '@firebase/logger': 0.3.4 + '@firebase/remote-config': 0.3.15_@firebase+app@0.8.3 + '@firebase/remote-config-types': 0.2.1 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app' + dev: false + + /@firebase/remote-config-types/0.2.1: + resolution: {integrity: sha512-1PGx4vKtMMd5uB6G1Nj2b8fOnJx7mIJGzkdyfhIM1oQx9k3dJ+pVu4StrNm46vHaD8ZlOQLr91YfUE43xSXwSg==} + dev: false + + /@firebase/remote-config/0.3.15_@firebase+app@0.8.3: + resolution: {integrity: sha512-ZCyqoCaftoNvc2r4zPaqNV4OgC4sRHjcQI+agzXESnhDLnTY8DpCaQ0m9j6deHuxxDOgu8QPDb8psLbjR+9CgQ==} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.8.3 + '@firebase/component': 0.5.21 + '@firebase/installations': 0.5.16_@firebase+app@0.8.3 + '@firebase/logger': 0.3.4 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + dev: false + + /@firebase/storage-compat/0.1.21_6e25ipnw6ok3e747dgryxrjf7m: + resolution: {integrity: sha512-/HWdKKykNSY0xcwyAf+Fooq8VK+fjaRc7oRZ7PM+ovGb6rnqINIiRUxVudFOdEvqN5ftiVY0vSKdTYzbmeBr+w==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/app-compat': 0.1.38 + '@firebase/component': 0.5.21 + '@firebase/storage': 0.9.13_fg26na3iiuycy3cwzcyxqwfb2e + '@firebase/storage-types': 0.6.1_ng4u4jtoxpyfdkxsmbmyeoj754 + '@firebase/util': 1.7.3 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app' + - '@firebase/app-types' + - encoding + dev: false + + /@firebase/storage-types/0.6.1_ng4u4jtoxpyfdkxsmbmyeoj754: + resolution: {integrity: sha512-/pkNzKiGCSjdBBZHPvWL1kkPZfM3pFJ38HPJE1xTHwLBwdrFb4JrmY+5/E4ma5ePsbejecIOD1SZhEKDB/JwUQ==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 1.x + dependencies: + '@firebase/app-types': 0.8.1 + '@firebase/util': 1.7.3 + dev: false + + /@firebase/storage/0.9.13_fg26na3iiuycy3cwzcyxqwfb2e: + resolution: {integrity: sha512-FZKF35rPidxRc1ZgOYLJt9nEfA30HAa/tZ9IhzVTKmqB4p7P13QCxMQphOMcucbCf84IsuGWu/YwYc/EtvhwRw==} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.8.3 + '@firebase/component': 0.5.21 + '@firebase/util': 1.7.3 + node-fetch: 2.6.7_encoding@0.1.13 + tslib: 2.4.0 + transitivePeerDependencies: + - encoding + dev: false + + /@firebase/util/1.7.3: + resolution: {integrity: sha512-wxNqWbqokF551WrJ9BIFouU/V5SL1oYCGx1oudcirdhadnQRFH5v1sjgGL7cUV/UsekSycygphdrF2lxBxOYKg==} + dependencies: + tslib: 2.4.0 + dev: false + + /@firebase/webchannel-wrapper/0.8.1: + resolution: {integrity: sha512-CJW8vxt6bJaBeco2VnlJjmCmAkrrtIdf0GGKvpAB4J5gw8Gi0rHb+qsgKp6LsyS5W6ALPLawLs7phZmw02dvLw==} + dev: false + /@fontsource/poppins/4.5.10: resolution: {integrity: sha512-oYZVHsnlwV3VWM1SE/m6SUxVh0QLk5+2wB+lBiXcI7N/0KVQWmV9YykaPqfJHBLvmdya+MAOnv+BQHeLU1vOOw==} dev: false @@ -422,6 +1208,38 @@ packages: resolution: {integrity: sha512-OTrWNdcPp01bZjEbSu52vMu9PaReUFylHAMI4lctKVbYUnm+e7a4eG6YcnRvDrJEMYHBDtEWLAsqGVldV5r1EQ==} dev: false + /@grpc/grpc-js/1.7.3: + resolution: {integrity: sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog==} + engines: {node: ^8.13.0 || >=10.10.0} + dependencies: + '@grpc/proto-loader': 0.7.3 + '@types/node': 18.7.18 + dev: false + + /@grpc/proto-loader/0.6.13: + resolution: {integrity: sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==} + engines: {node: '>=6'} + hasBin: true + dependencies: + '@types/long': 4.0.2 + lodash.camelcase: 4.3.0 + long: 4.0.0 + protobufjs: 6.11.3 + yargs: 16.2.0 + dev: false + + /@grpc/proto-loader/0.7.3: + resolution: {integrity: sha512-5dAvoZwna2Py3Ef96Ux9jIkp3iZ62TUsV00p3wVBPNX5K178UbNi8Q7gQVqwXT1Yq9RejIGG9G2IPEo93T6RcA==} + engines: {node: '>=6'} + hasBin: true + dependencies: + '@types/long': 4.0.2 + lodash.camelcase: 4.3.0 + long: 4.0.0 + protobufjs: 7.1.2 + yargs: 16.2.0 + dev: false + /@humanwhocodes/config-array/0.10.4: resolution: {integrity: sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==} engines: {node: '>=10.10.0'} @@ -441,6 +1259,273 @@ packages: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true + /@istanbuljs/load-nyc-config/1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema/0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/console/29.3.1: + resolution: {integrity: sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + chalk: 4.1.2 + jest-message-util: 29.3.1 + jest-util: 29.3.1 + slash: 3.0.0 + dev: true + + /@jest/core/29.3.1: + resolution: {integrity: sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 29.3.1 + '@jest/reporters': 29.3.1 + '@jest/test-result': 29.3.1 + '@jest/transform': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.7.0 + exit: 0.1.2 + graceful-fs: 4.2.10 + jest-changed-files: 29.2.0 + jest-config: 29.3.1_@types+node@18.7.18 + jest-haste-map: 29.3.1 + jest-message-util: 29.3.1 + jest-regex-util: 29.2.0 + jest-resolve: 29.3.1 + jest-resolve-dependencies: 29.3.1 + jest-runner: 29.3.1 + jest-runtime: 29.3.1 + jest-snapshot: 29.3.1 + jest-util: 29.3.1 + jest-validate: 29.3.1 + jest-watcher: 29.3.1 + micromatch: 4.0.5 + pretty-format: 29.3.1 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + + /@jest/environment/29.3.1: + resolution: {integrity: sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/fake-timers': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + jest-mock: 29.3.1 + dev: true + + /@jest/expect-utils/29.3.1: + resolution: {integrity: sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.2.0 + dev: true + + /@jest/expect/29.3.1: + resolution: {integrity: sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + expect: 29.3.1 + jest-snapshot: 29.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/fake-timers/29.3.1: + resolution: {integrity: sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.3.1 + '@sinonjs/fake-timers': 9.1.2 + '@types/node': 18.7.18 + jest-message-util: 29.3.1 + jest-mock: 29.3.1 + jest-util: 29.3.1 + dev: true + + /@jest/globals/29.3.1: + resolution: {integrity: sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.3.1 + '@jest/expect': 29.3.1 + '@jest/types': 29.3.1 + jest-mock: 29.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/reporters/29.3.1: + resolution: {integrity: sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.3.1 + '@jest/test-result': 29.3.1 + '@jest/transform': 29.3.1 + '@jest/types': 29.3.1 + '@jridgewell/trace-mapping': 0.3.17 + '@types/node': 18.7.18 + chalk: 4.1.2 + collect-v8-coverage: 1.0.1 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 5.2.1 + istanbul-lib-report: 3.0.0 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.5 + jest-message-util: 29.3.1 + jest-util: 29.3.1 + jest-worker: 29.3.1 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/schemas/29.0.0: + resolution: {integrity: sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.24.51 + dev: true + + /@jest/source-map/29.2.0: + resolution: {integrity: sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.17 + callsites: 3.1.0 + graceful-fs: 4.2.10 + dev: true + + /@jest/test-result/29.3.1: + resolution: {integrity: sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.3.1 + '@jest/types': 29.3.1 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.1 + dev: true + + /@jest/test-sequencer/29.3.1: + resolution: {integrity: sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.3.1 + graceful-fs: 4.2.10 + jest-haste-map: 29.3.1 + slash: 3.0.0 + dev: true + + /@jest/transform/29.3.1: + resolution: {integrity: sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.20.5 + '@jest/types': 29.3.1 + '@jridgewell/trace-mapping': 0.3.17 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.10 + jest-haste-map: 29.3.1 + jest-regex-util: 29.2.0 + jest-util: 29.3.1 + micromatch: 4.0.5 + pirates: 4.0.5 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types/29.3.1: + resolution: {integrity: sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.0.0 + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 18.7.18 + '@types/yargs': 17.0.15 + chalk: 4.1.2 + dev: true + + /@jridgewell/gen-mapping/0.1.1: + resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@jridgewell/gen-mapping/0.3.2: + resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/trace-mapping': 0.3.17 + dev: true + + /@jridgewell/resolve-uri/3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array/1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec/1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@jridgewell/trace-mapping/0.3.17: + resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + /@lit/reactive-element/1.4.1: resolution: {integrity: sha512-qDv4851VFSaBWzpS02cXHclo40jsbAjRXnebNXpm0uVg32kCneZPo9RYVQtrTNICtZ+1wAYHu1ZtxWSWMbKrBw==} dev: false @@ -902,6 +1987,49 @@ packages: resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==} dev: false + /@protobufjs/aspromise/1.1.2: + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + dev: false + + /@protobufjs/base64/1.1.2: + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + dev: false + + /@protobufjs/codegen/2.0.4: + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + dev: false + + /@protobufjs/eventemitter/1.1.0: + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + dev: false + + /@protobufjs/fetch/1.1.0: + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + dev: false + + /@protobufjs/float/1.0.2: + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + dev: false + + /@protobufjs/inquire/1.1.0: + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + dev: false + + /@protobufjs/path/1.1.2: + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + dev: false + + /@protobufjs/pool/1.1.0: + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + dev: false + + /@protobufjs/utf8/1.1.0: + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + dev: false + /@radix-ui/primitive/1.0.0: resolution: {integrity: sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==} dependencies: @@ -1091,6 +2219,22 @@ packages: resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==} dev: true + /@sinclair/typebox/0.24.51: + resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} + dev: true + + /@sinonjs/commons/1.8.6: + resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers/9.1.2: + resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==} + dependencies: + '@sinonjs/commons': 1.8.6 + dev: true + /@swc/helpers/0.4.11: resolution: {integrity: sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==} dependencies: @@ -1107,18 +2251,76 @@ packages: resolution: {integrity: sha512-GiS5Df3CzXY/fPBFcM0CKFERZfI4Cg1X33VPZX+NLo7Fwm/h9zu/aU24N1mG75Q9LuMnwKm7woxKr8BiUXGYCg==} dev: false + /@types/babel__core/7.1.20: + resolution: {integrity: sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==} + dependencies: + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.18.3 + dev: true + + /@types/babel__generator/7.6.4: + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@types/babel__template/7.4.1: + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + dependencies: + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 + dev: true + + /@types/babel__traverse/7.18.3: + resolution: {integrity: sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@types/graceful-fs/4.1.5: + resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} + dependencies: + '@types/node': 18.7.18 + dev: true + + /@types/istanbul-lib-coverage/2.0.4: + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + dev: true + + /@types/istanbul-lib-report/3.0.0: + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + dev: true + + /@types/istanbul-reports/3.0.1: + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + dependencies: + '@types/istanbul-lib-report': 3.0.0 + dev: true + /@types/json5/0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true + /@types/long/4.0.2: + resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} + dev: false + /@types/node/18.7.18: resolution: {integrity: sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==} - dev: true /@types/parse-json/4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} dev: false + /@types/prettier/2.7.1: + resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==} + dev: true + /@types/prop-types/15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} @@ -1158,10 +2360,24 @@ packages: /@types/scheduler/0.16.2: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} + /@types/stack-utils/2.0.1: + resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + dev: true + /@types/trusted-types/2.0.2: resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==} dev: false + /@types/yargs-parser/21.0.0: + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + dev: true + + /@types/yargs/17.0.15: + resolution: {integrity: sha512-ZHc4W2dnEQPfhn06TBEdWaiUHEZAocYaiVMfwOipY5jcJt/251wVrKCBWBetGZWO5CF8tdb7L3DmdxVlZ2BOIg==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true + /@typescript-eslint/parser/5.38.0_76twfck5d7crjqrmw4yltga7zm: resolution: {integrity: sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1182,7 +2398,7 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.38.0_eslint@8.22.0: + /@typescript-eslint/parser/5.38.0_tg6quxtr5dyl3tikvj7rwonxxi: resolution: {integrity: sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1194,9 +2410,10 @@ packages: dependencies: '@typescript-eslint/scope-manager': 5.38.0 '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/typescript-estree': 5.38.0 + '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.9.3 debug: 4.3.4 eslint: 8.22.0 + typescript: 4.9.3 transitivePeerDependencies: - supports-color dev: true @@ -1214,26 +2431,6 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.38.0: - resolution: {integrity: sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/visitor-keys': 5.38.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.3.7 - tsutils: 3.21.0 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/typescript-estree/5.38.0_typescript@4.8.3: resolution: {integrity: sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1255,6 +2452,27 @@ packages: - supports-color dev: true + /@typescript-eslint/typescript-estree/5.38.0_typescript@4.9.3: + resolution: {integrity: sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.38.0 + '@typescript-eslint/visitor-keys': 5.38.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.7 + tsutils: 3.21.0_typescript@4.9.3 + typescript: 4.9.3 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/visitor-keys/5.38.0: resolution: {integrity: sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1309,23 +2527,46 @@ packages: uri-js: 4.4.1 dev: true + /ansi-escapes/4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + /ansi-regex/5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - dev: true /ansi-styles/3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} dependencies: color-convert: 1.9.3 - dev: false /ansi-styles/4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} dependencies: color-convert: 2.0.1 + + /ansi-styles/5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /anymatch/3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /argparse/1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 dev: true /argparse/2.0.1: @@ -1400,15 +2641,70 @@ packages: dev: false optional: true + /asynckit/0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + /axe-core/4.4.3: resolution: {integrity: sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==} engines: {node: '>=4'} dev: true + /axios/1.2.0: + resolution: {integrity: sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==} + dependencies: + follow-redirects: 1.15.2 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + /axobject-query/2.2.0: resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} dev: true + /babel-jest/29.3.1_@babel+core@7.20.5: + resolution: {integrity: sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.20.5 + '@jest/transform': 29.3.1 + '@types/babel__core': 7.1.20 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.2.0_@babel+core@7.20.5 + chalk: 4.1.2 + graceful-fs: 4.2.10 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-istanbul/6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.19.0 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist/29.2.0: + resolution: {integrity: sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/template': 7.18.10 + '@babel/types': 7.20.5 + '@types/babel__core': 7.1.20 + '@types/babel__traverse': 7.18.3 + dev: true + /babel-plugin-macros/3.1.0: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} @@ -1418,9 +2714,39 @@ packages: resolve: 1.22.1 dev: false + /babel-preset-current-node-syntax/1.0.1_@babel+core@7.20.5: + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.5 + '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.5 + '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.5 + dev: true + + /babel-preset-jest/29.2.0_@babel+core@7.20.5: + resolution: {integrity: sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + babel-plugin-jest-hoist: 29.2.0 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.5 + dev: true + /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true /base64-js/1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -1431,7 +2757,6 @@ packages: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - dev: true /braces/3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -1440,10 +2765,38 @@ packages: fill-range: 7.0.1 dev: true + /browserslist/4.21.4: + resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001419 + electron-to-chromium: 1.4.284 + node-releases: 2.0.6 + update-browserslist-db: 1.0.10_browserslist@4.21.4 + dev: true + + /bs-logger/0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + dependencies: + fast-json-stable-stringify: 2.1.0 + dev: true + + /bser/2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + /buffer-from/0.1.2: resolution: {integrity: sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==} dev: false + /buffer-from/1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + /buffer/5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} dependencies: @@ -1469,9 +2822,18 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + /camelcase/5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase/6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + /caniuse-lite/1.0.30001419: resolution: {integrity: sha512-aFO1r+g6R7TW+PNQxKzjITwLOyDhVRLjW0LcwS/HCZGUUKTGNp9+IwLC4xyDSZBygVL/mxaFR3HIV6wEKQuSzw==} - dev: false /chalk/2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -1480,7 +2842,6 @@ packages: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 - dev: false /chalk/4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -1490,10 +2851,41 @@ packages: supports-color: 7.2.0 dev: true + /char-regex/1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + + /ci-info/3.7.0: + resolution: {integrity: sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==} + engines: {node: '>=8'} + dev: true + + /cjs-module-lexer/1.2.2: + resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} + dev: true + /client-only/0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} dev: false + /cliui/7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: false + + /cliui/8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + /clone/2.1.2: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} @@ -1518,26 +2910,38 @@ packages: - '@types/react' dev: false + /co/4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + + /collect-v8-coverage/1.0.1: + resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} + dev: true + /color-convert/1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 - dev: false /color-convert/2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 - dev: true /color-name/1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: false /color-name/1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true + + /combined-stream/1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false /command-score/0.1.2: resolution: {integrity: sha512-VtDvQpIJBvBatnONUsPzXYFVKQQAhuf3XTNOAsdBxCNO/QCtUUd8LSgjn0GVarBkCad6aJCZfXgrjYbl/KRr7w==} @@ -1545,11 +2949,13 @@ packages: /concat-map/0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} - dev: true /convert-source-map/1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: false + + /convert-source-map/2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true /core-js-pure/3.25.2: resolution: {integrity: sha512-ItD7YpW1cUB4jaqFLZXe1AXkyqIxz6GqPnsDV4uF4hVcWh/WAGIqSqw5p0/WdsILM0Xht9s3Koyw05R3K6RtiA==} @@ -1630,6 +3036,10 @@ packages: dependencies: ms: 2.1.2 + /dedent/0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + dev: true + /deep-equal/1.1.1: resolution: {integrity: sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==} dependencies: @@ -1645,6 +3055,11 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /deepmerge/4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + dev: true + /deferred-leveldown/5.3.0: resolution: {integrity: sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==} engines: {node: '>=6'} @@ -1661,10 +3076,25 @@ packages: has-property-descriptors: 1.0.0 object-keys: 1.1.1 + /delayed-stream/1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /detect-newline/3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + /detect-node-es/1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} dev: false + /diff-sequences/29.3.1: + resolution: {integrity: sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /dir-glob/3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -1703,6 +3133,18 @@ packages: readable-stream: 2.3.7 dev: false + /electron-to-chromium/1.4.284: + resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} + dev: true + + /emittery/0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + dev: true + + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + /emoji-regex/9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true @@ -1718,6 +3160,12 @@ packages: dev: false optional: true + /encoding/0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + dependencies: + iconv-lite: 0.6.3 + dev: false + /err-code/3.0.1: resolution: {integrity: sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==} dev: false @@ -1734,7 +3182,6 @@ packages: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: is-arrayish: 0.2.1 - dev: false /es-abstract/1.20.2: resolution: {integrity: sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==} @@ -1780,10 +3227,18 @@ packages: is-symbol: 1.0.4 dev: true + /escalade/3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + /escape-string-regexp/1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} - dev: false + + /escape-string-regexp/2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true /escape-string-regexp/4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} @@ -1814,7 +3269,7 @@ packages: - supports-color dev: true - /eslint-config-next/12.3.1_eslint@8.22.0: + /eslint-config-next/12.3.1_tg6quxtr5dyl3tikvj7rwonxxi: resolution: {integrity: sha512-EN/xwKPU6jz1G0Qi6Bd/BqMnHLyRAL0VsaQaWA7F3KkjAgZHi4f1uL1JKGWNxdQpHTW/sdGONBd0bzxUka/DJg==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 @@ -1825,7 +3280,7 @@ packages: dependencies: '@next/eslint-plugin-next': 12.3.1 '@rushstack/eslint-patch': 1.2.0 - '@typescript-eslint/parser': 5.38.0_eslint@8.22.0 + '@typescript-eslint/parser': 5.38.0_tg6quxtr5dyl3tikvj7rwonxxi eslint: 8.22.0 eslint-import-resolver-node: 0.3.6 eslint-import-resolver-typescript: 2.7.1_2iahngt3u2tkbdlu6s4gkur3pu @@ -1833,6 +3288,7 @@ packages: eslint-plugin-jsx-a11y: 6.6.1_eslint@8.22.0 eslint-plugin-react: 7.31.8_eslint@8.22.0 eslint-plugin-react-hooks: 4.6.0_eslint@8.22.0 + typescript: 4.9.3 transitivePeerDependencies: - eslint-import-resolver-webpack - supports-color @@ -1895,7 +3351,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.38.0_eslint@8.22.0 + '@typescript-eslint/parser': 5.38.0_tg6quxtr5dyl3tikvj7rwonxxi debug: 3.2.7 eslint: 8.22.0 eslint-import-resolver-node: 0.3.6 @@ -1914,7 +3370,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.38.0_eslint@8.22.0 + '@typescript-eslint/parser': 5.38.0_tg6quxtr5dyl3tikvj7rwonxxi array-includes: 3.1.5 array.prototype.flat: 1.3.0 debug: 2.6.9 @@ -2090,6 +3546,12 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /esprima/4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + /esquery/1.4.0: resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} engines: {node: '>=0.10'} @@ -2118,6 +3580,37 @@ packages: resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==} dev: false + /execa/5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /exit/0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + dev: true + + /expect/29.3.1: + resolution: {integrity: sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.3.1 + jest-get-type: 29.2.0 + jest-matcher-utils: 29.3.1 + jest-message-util: 29.3.1 + jest-util: 29.3.1 + dev: true + /extend/3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: false @@ -2159,6 +3652,19 @@ packages: reusify: 1.0.4 dev: true + /faye-websocket/0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + dependencies: + websocket-driver: 0.7.4 + dev: false + + /fb-watchman/2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + dependencies: + bser: 2.1.1 + dev: true + /file-entry-cache/6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -2177,6 +3683,14 @@ packages: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} dev: false + /find-up/4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + /find-up/5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -2185,6 +3699,41 @@ packages: path-exists: 4.0.0 dev: true + /firebase/9.13.0_encoding@0.1.13: + resolution: {integrity: sha512-xaw5DVbjuT9fbTx+ko/l828LA75zC7H2CJIdRSqMiYmYJjEuNIEb6HHFKUElKn7WmYIF62F2zXe1O8rfP9whgw==} + dependencies: + '@firebase/analytics': 0.8.4_@firebase+app@0.8.3 + '@firebase/analytics-compat': 0.1.17_uhwflrzfcfz2g667jhvqg7sd7i + '@firebase/app': 0.8.3 + '@firebase/app-check': 0.5.16_@firebase+app@0.8.3 + '@firebase/app-check-compat': 0.2.16_uhwflrzfcfz2g667jhvqg7sd7i + '@firebase/app-compat': 0.1.38 + '@firebase/app-types': 0.8.1 + '@firebase/auth': 0.20.11_fg26na3iiuycy3cwzcyxqwfb2e + '@firebase/auth-compat': 0.2.24_6e25ipnw6ok3e747dgryxrjf7m + '@firebase/database': 0.13.10_@firebase+app-types@0.8.1 + '@firebase/database-compat': 0.2.10_@firebase+app-types@0.8.1 + '@firebase/firestore': 3.7.2_fg26na3iiuycy3cwzcyxqwfb2e + '@firebase/firestore-compat': 0.2.2_6e25ipnw6ok3e747dgryxrjf7m + '@firebase/functions': 0.8.8_qxaep7pmgqjgshotoaytuprcse + '@firebase/functions-compat': 0.2.8_6e25ipnw6ok3e747dgryxrjf7m + '@firebase/installations': 0.5.16_@firebase+app@0.8.3 + '@firebase/installations-compat': 0.1.16_h7lquf2icoxthdkgvez4xhlpaa + '@firebase/messaging': 0.10.0_@firebase+app@0.8.3 + '@firebase/messaging-compat': 0.1.20_uhwflrzfcfz2g667jhvqg7sd7i + '@firebase/performance': 0.5.16_@firebase+app@0.8.3 + '@firebase/performance-compat': 0.1.16_uhwflrzfcfz2g667jhvqg7sd7i + '@firebase/remote-config': 0.3.15_@firebase+app@0.8.3 + '@firebase/remote-config-compat': 0.1.16_uhwflrzfcfz2g667jhvqg7sd7i + '@firebase/storage': 0.9.13_fg26na3iiuycy3cwzcyxqwfb2e + '@firebase/storage-compat': 0.1.21_6e25ipnw6ok3e747dgryxrjf7m + '@firebase/util': 1.7.3 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + /flat-cache/3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -2201,9 +3750,35 @@ packages: resolution: {integrity: sha512-W7cHV7Hrwjid6lWmy0IhsWDFQboWSng25U3VVywpHOTJnnAZNPScog67G+cVpeX9f7yDD21ih0WDrMMT+JoaYg==} dev: false + /follow-redirects/1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data/4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true dev: true + optional: true /function-bind/1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} @@ -2225,10 +3800,19 @@ packages: /functions-have-names/1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + /gensync/1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + /get-browser-rtc/1.1.0: resolution: {integrity: sha512-MghbMJ61EJrRsDe7w1Bvqt3ZsBuqhce5nrn/XAwgwOXhcsz53/ltdxOse1h/8eKXj5slzxdsz56g5rzOFSGwfQ==} dev: false + /get-caller-file/2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + /get-intrinsic/1.1.3: resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} dependencies: @@ -2241,6 +3825,16 @@ packages: engines: {node: '>=6'} dev: false + /get-package-type/0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-stream/6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + /get-symbol-description/1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} @@ -2283,6 +3877,10 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 + + /globals/11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} dev: true /globals/13.17.0: @@ -2304,6 +3902,10 @@ packages: slash: 3.0.0 dev: true + /graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true + /grapheme-splitter/1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true @@ -2315,7 +3917,6 @@ packages: /has-flag/3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} - dev: false /has-flag/4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} @@ -2358,6 +3959,10 @@ packages: resolution: {integrity: sha512-20xeVdOqcgTkMox0+BqFwADZP7+5dy/9CFPpAinSMh2d0s3b0Hs2V2D+lMh4Hphkf7VE9pwnOl58eP1te+REcg==} dev: false + /html-escaper/2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + /html-parse-stringify/3.0.1: resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} dependencies: @@ -2374,18 +3979,38 @@ packages: through2: 0.4.2 dev: false + /http-parser-js/0.5.8: + resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} + dev: false + + /human-signals/2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + /i18next/21.10.0: resolution: {integrity: sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==} dependencies: '@babel/runtime': 7.19.0 dev: false + /iconv-lite/0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: false + /idb-keyval/6.2.0: resolution: {integrity: sha512-uw+MIyQn2jl3+hroD7hF8J7PUviBU7BPKWw4f/ISf32D4LoGu98yHjrzWWJDASu9QNrX10tCJqk9YY0ClWm8Ng==} dependencies: safari-14-idb-fix: 3.0.0 dev: false + /idb/7.0.1: + resolution: {integrity: sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==} + dev: false + /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false @@ -2395,6 +4020,10 @@ packages: engines: {node: '>= 4'} dev: true + /immediate/3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + dev: false + /immediate/3.3.0: resolution: {integrity: sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==} dev: false @@ -2407,6 +4036,15 @@ packages: parent-module: 1.0.1 resolve-from: 4.0.0 + /import-local/3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + /imurmurhash/0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -2417,7 +4055,6 @@ packages: dependencies: once: 1.4.0 wrappy: 1.0.2 - dev: true /inherits/2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -2447,7 +4084,6 @@ packages: /is-arrayish/0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: false /is-bigint/1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} @@ -2484,6 +4120,15 @@ packages: engines: {node: '>=0.10.0'} dev: true + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + /is-generator-fn/2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + dev: true + /is-glob/4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -2521,6 +4166,11 @@ packages: call-bind: 1.0.2 dev: true + /is-stream/2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + /is-string/1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -2557,18 +4207,486 @@ packages: resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} dev: false + /istanbul-lib-coverage/3.2.0: + resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-instrument/5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.20.5 + '@babel/parser': 7.20.5 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-report/3.0.0: + resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} + engines: {node: '>=8'} + dependencies: + istanbul-lib-coverage: 3.2.0 + make-dir: 3.1.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps/4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports/3.1.5: + resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.0 + dev: true + + /jest-changed-files/29.2.0: + resolution: {integrity: sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + execa: 5.1.1 + p-limit: 3.1.0 + dev: true + + /jest-circus/29.3.1: + resolution: {integrity: sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.3.1 + '@jest/expect': 29.3.1 + '@jest/test-result': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + chalk: 4.1.2 + co: 4.6.0 + dedent: 0.7.0 + is-generator-fn: 2.1.0 + jest-each: 29.3.1 + jest-matcher-utils: 29.3.1 + jest-message-util: 29.3.1 + jest-runtime: 29.3.1 + jest-snapshot: 29.3.1 + jest-util: 29.3.1 + p-limit: 3.1.0 + pretty-format: 29.3.1 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-cli/29.3.1_@types+node@18.7.18: + resolution: {integrity: sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.3.1 + '@jest/test-result': 29.3.1 + '@jest/types': 29.3.1 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.10 + import-local: 3.1.0 + jest-config: 29.3.1_@types+node@18.7.18 + jest-util: 29.3.1 + jest-validate: 29.3.1 + prompts: 2.4.2 + yargs: 17.6.2 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + + /jest-config/29.3.1_@types+node@18.7.18: + resolution: {integrity: sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.20.5 + '@jest/test-sequencer': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + babel-jest: 29.3.1_@babel+core@7.20.5 + chalk: 4.1.2 + ci-info: 3.7.0 + deepmerge: 4.2.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-circus: 29.3.1 + jest-environment-node: 29.3.1 + jest-get-type: 29.2.0 + jest-regex-util: 29.2.0 + jest-resolve: 29.3.1 + jest-runner: 29.3.1 + jest-util: 29.3.1 + jest-validate: 29.3.1 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.3.1 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-diff/29.3.1: + resolution: {integrity: sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.3.1 + jest-get-type: 29.2.0 + pretty-format: 29.3.1 + dev: true + + /jest-docblock/29.2.0: + resolution: {integrity: sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each/29.3.1: + resolution: {integrity: sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.3.1 + chalk: 4.1.2 + jest-get-type: 29.2.0 + jest-util: 29.3.1 + pretty-format: 29.3.1 + dev: true + + /jest-environment-node/29.3.1: + resolution: {integrity: sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.3.1 + '@jest/fake-timers': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + jest-mock: 29.3.1 + jest-util: 29.3.1 + dev: true + + /jest-get-type/29.2.0: + resolution: {integrity: sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-haste-map/29.3.1: + resolution: {integrity: sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.3.1 + '@types/graceful-fs': 4.1.5 + '@types/node': 18.7.18 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.10 + jest-regex-util: 29.2.0 + jest-util: 29.3.1 + jest-worker: 29.3.1 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /jest-leak-detector/29.3.1: + resolution: {integrity: sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.2.0 + pretty-format: 29.3.1 + dev: true + + /jest-matcher-utils/29.3.1: + resolution: {integrity: sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.3.1 + jest-get-type: 29.2.0 + pretty-format: 29.3.1 + dev: true + + /jest-message-util/29.3.1: + resolution: {integrity: sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.18.6 + '@jest/types': 29.3.1 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.10 + micromatch: 4.0.5 + pretty-format: 29.3.1 + slash: 3.0.0 + stack-utils: 2.0.6 + dev: true + + /jest-mock/29.3.1: + resolution: {integrity: sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + jest-util: 29.3.1 + dev: true + + /jest-pnp-resolver/1.2.3_jest-resolve@29.3.1: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 29.3.1 + dev: true + + /jest-regex-util/29.2.0: + resolution: {integrity: sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-resolve-dependencies/29.3.1: + resolution: {integrity: sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-regex-util: 29.2.0 + jest-snapshot: 29.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve/29.3.1: + resolution: {integrity: sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.10 + jest-haste-map: 29.3.1 + jest-pnp-resolver: 1.2.3_jest-resolve@29.3.1 + jest-util: 29.3.1 + jest-validate: 29.3.1 + resolve: 1.22.1 + resolve.exports: 1.1.0 + slash: 3.0.0 + dev: true + + /jest-runner/29.3.1: + resolution: {integrity: sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.3.1 + '@jest/environment': 29.3.1 + '@jest/test-result': 29.3.1 + '@jest/transform': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.10 + jest-docblock: 29.2.0 + jest-environment-node: 29.3.1 + jest-haste-map: 29.3.1 + jest-leak-detector: 29.3.1 + jest-message-util: 29.3.1 + jest-resolve: 29.3.1 + jest-runtime: 29.3.1 + jest-util: 29.3.1 + jest-watcher: 29.3.1 + jest-worker: 29.3.1 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-runtime/29.3.1: + resolution: {integrity: sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.3.1 + '@jest/fake-timers': 29.3.1 + '@jest/globals': 29.3.1 + '@jest/source-map': 29.2.0 + '@jest/test-result': 29.3.1 + '@jest/transform': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + chalk: 4.1.2 + cjs-module-lexer: 1.2.2 + collect-v8-coverage: 1.0.1 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-haste-map: 29.3.1 + jest-message-util: 29.3.1 + jest-mock: 29.3.1 + jest-regex-util: 29.2.0 + jest-resolve: 29.3.1 + jest-snapshot: 29.3.1 + jest-util: 29.3.1 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-snapshot/29.3.1: + resolution: {integrity: sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.20.5 + '@babel/generator': 7.20.5 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-syntax-typescript': 7.20.0_@babel+core@7.20.5 + '@babel/traverse': 7.20.5 + '@babel/types': 7.19.4 + '@jest/expect-utils': 29.3.1 + '@jest/transform': 29.3.1 + '@jest/types': 29.3.1 + '@types/babel__traverse': 7.18.3 + '@types/prettier': 2.7.1 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.5 + chalk: 4.1.2 + expect: 29.3.1 + graceful-fs: 4.2.10 + jest-diff: 29.3.1 + jest-get-type: 29.2.0 + jest-haste-map: 29.3.1 + jest-matcher-utils: 29.3.1 + jest-message-util: 29.3.1 + jest-util: 29.3.1 + natural-compare: 1.4.0 + pretty-format: 29.3.1 + semver: 7.3.7 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-util/29.3.1: + resolution: {integrity: sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + chalk: 4.1.2 + ci-info: 3.7.0 + graceful-fs: 4.2.10 + picomatch: 2.3.1 + dev: true + + /jest-validate/29.3.1: + resolution: {integrity: sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.3.1 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.2.0 + leven: 3.1.0 + pretty-format: 29.3.1 + dev: true + + /jest-watcher/29.3.1: + resolution: {integrity: sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.7.18 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.3.1 + string-length: 4.0.2 + dev: true + + /jest-worker/29.3.1: + resolution: {integrity: sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 18.7.18 + jest-util: 29.3.1 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest/29.3.1_@types+node@18.7.18: + resolution: {integrity: sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.3.1 + '@jest/types': 29.3.1 + import-local: 3.1.0 + jest-cli: 29.3.1_@types+node@18.7.18 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + /js-tokens/4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + /js-yaml/3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + /js-yaml/4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} dependencies: argparse: 2.0.1 dev: true + /jsesc/2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + /json-parse-even-better-errors/2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: false /json-schema-traverse/0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -2580,10 +4698,17 @@ packages: /json5/1.0.1: resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} + hasBin: true dependencies: minimist: 1.2.6 dev: true + /json5/2.2.1: + resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} + engines: {node: '>=6'} + hasBin: true + dev: true + /jsx-ast-utils/3.3.3: resolution: {integrity: sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==} engines: {node: '>=4.0'} @@ -2592,6 +4717,20 @@ packages: object.assign: 4.1.4 dev: true + /jszip/3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.7 + setimmediate: 1.0.5 + dev: false + + /kleur/3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + /ky/0.32.2: resolution: {integrity: sha512-eBJeF6IXNwX5rksdwBrE2rIJrU2d84GoTvdM7OmmTIwUVXEMd72wIwvT+nyhrqtv7AzbSNsWz7yRsHgVhj1uog==} engines: {node: '>=14.16'} @@ -2699,6 +4838,11 @@ packages: dev: false optional: true + /leven/3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + /levn/0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -2714,9 +4858,14 @@ packages: isomorphic.js: 0.2.5 dev: false + /lie/3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + dependencies: + immediate: 3.0.6 + dev: false + /lines-and-columns/1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: false /lit-element/3.2.2: resolution: {integrity: sha512-6ZgxBR9KNroqKb6+htkyBwD90XGRiqKDHVrW/Eh0EZ+l+iC+u+v+w3/BA5NGi4nizAVHGYvQBHUDuSmLjPp7NQ==} @@ -2739,6 +4888,13 @@ packages: lit-html: 2.4.0 dev: false + /locate-path/5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + /locate-path/6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -2746,10 +4902,18 @@ packages: p-locate: 5.0.0 dev: true + /lodash.camelcase/4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + dev: false + /lodash.debounce/4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} dev: false + /lodash.memoize/4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + dev: true + /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true @@ -2758,6 +4922,14 @@ packages: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: false + /long/4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + dev: false + + /long/5.2.0: + resolution: {integrity: sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w==} + dev: false + /loose-envify/1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} dependencies: @@ -2775,12 +4947,33 @@ packages: dev: false optional: true + /make-dir/3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.0 + dev: true + + /make-error/1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /makeerror/1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true + /marked/4.1.1: resolution: {integrity: sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==} engines: {node: '>= 12'} hasBin: true dev: false + /merge-stream/2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + /merge2/1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2794,11 +4987,27 @@ packages: picomatch: 2.3.1 dev: true + /mime-db/1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types/2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /mimic-fn/2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + /minimatch/3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 - dev: true /minimist/1.2.6: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} @@ -2926,12 +5135,45 @@ packages: - babel-plugin-macros dev: false + /node-fetch/2.6.7_encoding@0.1.13: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + encoding: 0.1.13 + whatwg-url: 5.0.0 + dev: false + /node-gyp-build/4.1.1: resolution: {integrity: sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==} hasBin: true dev: false optional: true + /node-int64/0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + dev: true + + /node-releases/2.0.6: + resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} + dev: true + + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path/4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + /object-assign/4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -3004,6 +5246,12 @@ packages: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 + + /onetime/5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 dev: true /optionator/0.9.1: @@ -3018,6 +5266,13 @@ packages: word-wrap: 1.2.3 dev: true + /p-limit/2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + /p-limit/3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -3025,6 +5280,13 @@ packages: yocto-queue: 0.1.0 dev: true + /p-locate/4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + /p-locate/5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -3032,6 +5294,15 @@ packages: p-limit: 3.1.0 dev: true + /p-try/2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /pako/1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: false + /parchment/1.1.4: resolution: {integrity: sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==} dev: false @@ -3050,7 +5321,6 @@ packages: error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - dev: false /path-exists/4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} @@ -3060,7 +5330,6 @@ packages: /path-is-absolute/1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} - dev: true /path-key/3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} @@ -3080,13 +5349,24 @@ packages: /picocolors/1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: false /picomatch/2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} dev: true + /pirates/4.0.5: + resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} + engines: {node: '>= 6'} + dev: true + + /pkg-dir/4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + /playwright-core/1.28.1: resolution: {integrity: sha512-3PixLnGPno0E8rSBJjtwqTwJe3Yw72QwBBBxNoukIj3lEeBNXwbNiKrNuB1oyQgTBw5QHUhNO3SteEtHaMK6ag==} engines: {node: '>=14'} @@ -3118,10 +5398,27 @@ packages: resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} engines: {node: '>=10.13.0'} + /pretty-format/29.3.1: + resolution: {integrity: sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.0.0 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + /process-nextick-args/2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: false + /prompts/2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + /prop-types/15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} dependencies: @@ -3129,6 +5426,49 @@ packages: object-assign: 4.1.1 react-is: 16.13.1 + /protobufjs/6.11.3: + resolution: {integrity: sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==} + hasBin: true + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.2 + '@types/node': 18.7.18 + long: 4.0.0 + dev: false + + /protobufjs/7.1.2: + resolution: {integrity: sha512-4ZPTPkXCdel3+L81yw3dG6+Kq3umdWKh7Dc7GW/CpNk4SX3hK58iPCWeCyhVTDrbkNeKrYNZ7EojM5WDaEWTLQ==} + engines: {node: '>=12.0.0'} + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 18.7.18 + long: 5.2.0 + dev: false + + /proxy-from-env/1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + /prr/1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} dev: false @@ -3207,7 +5547,6 @@ packages: /react-is/18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: false /react-remove-scroll-bar/2.3.4_w5j4k42lgipnm43s3brx6h3c34: resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} @@ -3328,10 +5667,31 @@ packages: engines: {node: '>=8'} dev: true + /require-directory/2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + /resolve-cwd/3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + /resolve-from/4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + /resolve-from/5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve.exports/1.1.0: + resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} + engines: {node: '>=10'} + dev: true + /resolve/1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} dependencies: @@ -3354,9 +5714,9 @@ packages: /rimraf/3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true dependencies: glob: 7.2.3 - dev: true /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -3376,23 +5736,45 @@ packages: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: false + /safer-buffer/2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false + /scheduler/0.23.0: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: loose-envify: 1.4.0 dev: false + /selenium-webdriver/4.5.0: + resolution: {integrity: sha512-9mSFii+lRwcnT2KUAB1kqvx6+mMiiQHH60Y0VUtr3kxxi3oZ3CV3B8e2nuJ7T4SPb+Q6VA0swswe7rYpez07Bg==} + engines: {node: '>= 14.20.0'} + dependencies: + jszip: 3.10.1 + tmp: 0.2.1 + ws: 8.10.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + /semver/6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true dev: true /semver/7.3.7: resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} engines: {node: '>=10'} + hasBin: true dependencies: lru-cache: 6.0.0 dev: true + /setimmediate/1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + dev: false + /sha3/2.1.4: resolution: {integrity: sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==} dependencies: @@ -3419,6 +5801,10 @@ packages: object-inspect: 1.12.2 dev: true + /signal-exit/3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + /simple-peer/9.11.1: resolution: {integrity: sha512-D1SaWpOW8afq1CZGWB8xTfrT3FekjQmPValrqncJMX7QFl8YwhrPTZvMCANLtgBwwdS+7zURyqxDDEmY558tTw==} dependencies: @@ -3433,6 +5819,10 @@ packages: - supports-color dev: false + /sisteransi/1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + /slash/3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -3443,11 +5833,50 @@ packages: engines: {node: '>=0.10.0'} dev: false + /source-map-support/0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + /source-map/0.5.7: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} engines: {node: '>=0.10.0'} dev: false + /source-map/0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /sprintf-js/1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + + /stack-utils/2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /string-length/4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + dev: true + + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + /string.prototype.matchall/4.0.7: resolution: {integrity: sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==} dependencies: @@ -3498,13 +5927,22 @@ packages: engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 - dev: true /strip-bom/3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} dev: true + /strip-bom/4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /strip-final-newline/2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + /strip-json-comments/3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -3552,7 +5990,6 @@ packages: engines: {node: '>=4'} dependencies: has-flag: 3.0.0 - dev: false /supports-color/7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} @@ -3561,10 +5998,35 @@ packages: has-flag: 4.0.0 dev: true + /supports-color/8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + /supports-preserve-symlinks-flag/1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + /swr/2.0.0: + resolution: {integrity: sha512-IhUx5yPkX+Fut3h0SqZycnaNLXLXsb2ECFq0Y29cxnK7d8r7auY2JWNbCW3IX+EqXUg3rwNJFlhrw5Ye/b6k7w==} + engines: {pnpm: '7'} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 + dependencies: + use-sync-external-store: 1.2.0 + dev: false + + /test-exclude/6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + /text-table/0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -3580,10 +6042,20 @@ packages: xtend: 2.1.2 dev: false + /tmp/0.2.1: + resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} + engines: {node: '>=8.17.0'} + dependencies: + rimraf: 3.0.2 + dev: false + + /tmpl/1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + /to-fast-properties/2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} - dev: false /to-regex-range/5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -3592,6 +6064,43 @@ packages: is-number: 7.0.0 dev: true + /tr46/0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /ts-jest/29.0.3_4f6uxrzmuwipl5rr3bcogf6k74: + resolution: {integrity: sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + jest: 29.3.1_@types+node@18.7.18 + jest-util: 29.3.1 + json5: 2.2.1 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.3.7 + typescript: 4.9.3 + yargs-parser: 21.1.1 + dev: true + /tsconfig-paths/3.14.1: resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} dependencies: @@ -3609,15 +6118,6 @@ packages: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} dev: false - /tsutils/3.21.0: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - dev: true - /tsutils/3.21.0_typescript@4.8.3: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -3628,6 +6128,16 @@ packages: typescript: 4.8.3 dev: true + /tsutils/3.21.0_typescript@4.9.3: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + typescript: 4.9.3 + dev: true + /turndown/7.1.1: resolution: {integrity: sha512-BEkXaWH7Wh7e9bd2QumhfAXk5g34+6QUmmWx+0q6ThaVOLuLUqsnkq35HQ5SBHSaxjSfSM7US5o4lhJNH7B9MA==} dependencies: @@ -3641,11 +6151,21 @@ packages: prelude-ls: 1.2.1 dev: true + /type-detect/4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + /type-fest/0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} dev: true + /type-fest/0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + /typescript/4.8.3: resolution: {integrity: sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==} engines: {node: '>=4.2.0'} @@ -3658,6 +6178,12 @@ packages: hasBin: true dev: true + /typescript/4.9.3: + resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + /unbox-primitive/1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -3667,6 +6193,17 @@ packages: which-boxed-primitive: 1.0.2 dev: true + /update-browserslist-db/1.0.10_browserslist@4.21.4: + resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.4 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + /uri-js/4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -3704,6 +6241,12 @@ packages: tslib: 2.4.0 dev: false + /use-sync-external-store/1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dev: false + /use-sync-external-store/1.2.0_react@18.2.0: resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: @@ -3720,11 +6263,51 @@ packages: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true + /v8-to-istanbul/9.0.1: + resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.17 + '@types/istanbul-lib-coverage': 2.0.4 + convert-source-map: 1.9.0 + dev: true + /void-elements/3.1.0: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} dev: false + /walker/1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + dev: true + + /webidl-conversions/3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /websocket-driver/0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + dependencies: + http-parser-js: 0.5.8 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + dev: false + + /websocket-extensions/0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + dev: false + + /whatwg-url/5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: @@ -3747,8 +6330,23 @@ packages: engines: {node: '>=0.10.0'} dev: true + /wrap-ansi/7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + /wrappy/1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + /write-file-atomic/4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 dev: true /ws/6.2.2: @@ -3782,6 +6380,19 @@ packages: dev: false optional: true + /ws/8.10.0: + resolution: {integrity: sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /xtend/2.1.2: resolution: {integrity: sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==} engines: {node: '>=0.4'} @@ -3856,6 +6467,10 @@ packages: - utf-8-validate dev: false + /y18n/5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true @@ -3865,6 +6480,42 @@ packages: engines: {node: '>= 6'} dev: false + /yargs-parser/20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + dev: false + + /yargs-parser/21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs/16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + dependencies: + cliui: 7.0.4 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + dev: false + + /yargs/17.6.2: + resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + /yjs/13.5.41: resolution: {integrity: sha512-4eSTrrs8OeI0heXKKioRY4ag7V5Bk85Z4MeniUyown3o3y0G7G4JpAZWrZWfTp7pzw2b53GkAQWKqHsHi9j9JA==} dependencies: